function Scan=Dicom2FourDAnalyze_MedCom_UCSF(Scan,baseDir);
% Scan=Dicom2FourDAnalyze_MedCom_UCSF(Scan);
% where Scan has to be a struct with the fields
% Scan.DirName
% Scan.Slices
% Scan.Volumes
% Scan.Filenames
% Scan.Filename4d
%
% the script will generate a 4danalyze file
% and put the name into the field Scan.Filename4d
% written 2006.01.12 by Mark Schira mark@ski.org

if ~exist('baseDir')
    baseDir = pwd;
end

Directory=[baseDir,filesep,Scan.DirName];
Filename=Scan.Filenames;
Slices=Scan.Slices;
Volumes=Scan.Volumes;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Stuff for fsl
fslBase='/raid/MRI/toolbox/FSL/fsl';
if (ispref('VISTA','fslBase'))
    disp('Setting fslBase to the one specified in the VISTA matlab preferences:');
    fslBase=getpref('VISTA','fslBase');
    disp(fslBase);
end

fslPath=fullfile(fslBase,'bin'); % This is where FSL lives - should also be able to get this from a Matlab pref
reconPath='/raid/MRI/toolbox/Recon'; % required for the recon program to convert .mag files into Analyze format

cd (Directory);

%******************************************************************
%now do the Recon

try
    In3dFileString=' ';
    for thisVol=1:Volumes;
        fistFile=1+(thisVol-1)*Slices;
        filenumbers=[fistFile:fistFile+Slices-1]; %these are the filenumbers of the slices we need
        filestring=' '; %we need a filestring to start with
        for thisSlice=1:Slices
            filestring=sprintf('%s %s%d.DCM',filestring,Filename,filenumbers(thisSlice));
        end
        Out3dVolStr=sprintf('%s%03d.hdr',Filename,thisVol);
        evalStr1=['!medcon -f',filestring,' -c anlz -stacks -o ',Out3dVolStr];
        eval(evalStr1);
        In3dFileString=sprintf('%s m000-stacks-%s%04d.DCM',In3dFileString,Out3dVolStr);
        In3dFileStringb=sprintf('%s m000-stacks-%s%04d.DCM',In3dFileString,Out3dVolStr);

    end
    OutVolStr=sprintf('%s_4d.hdr',Filename);
    %Usage: avwmerge <-x/y/z/t> <output> <file1 file2 .......>
    evalStr2=['!/raid/MRI/toolbox/FSL/fsl/bin/avwmerge -t ',OutVolStr,In3dFileString];
    eval(evalStr2);
    Scan.Filename4d=OutVolStr;
    display(['saved ',OutVolStr]);

    evalStr=(['! rm m000-stacks*']);
    eval(evalStr);
catch
    display('Warning!! Making4d file failed!');
end
cd (baseDir)


function rmSetDataTYPES(vw, params)
% Write the retinotopic model stimulus parameters to the dataTYPES
%
%   rmSetDataTYPES(vw, params)

mrGlobals;

dt = viewGet(vw, 'dataTypeNumber');

% %This returns an error if the fields already in dt.retinotopyModelParams
% are not exactly the same as those in params.stim
%
% for scan = 1:numel(params.stim)
%     dataTYPES(dt) = dtSet(dataTYPES(dt),...
%         'retinotopyModelParams', params.stim(scan), scan);
% end

dataTYPES(dt) = dtSet(dataTYPES(dt),'retinotopyModelParams', params.stim);

saveSession

return


function out = gpuBenchReport( varargin )
%gpuBenchReport  create an HTML report based on some GPU performance data
%
%   gpuBenchReport(data) creates a new HTML report based on the supplied
%   PerformanceData and opens it in the system browser.
%
%   gpuBenchReport() creates an HTML report based only on the pre-stored
%   performance data.
%
%   filename = gpuBenchReport(...) returns the location of the main page
%   for the report instead of viewing it immediately.
%
%   Examples:
%   >> gpuBenchReport
%   >> data = gpuBench;
%   >> gpuBenchReport( data )
%
%   See also: gpuBench

%   Copyright 2011 The MathWorks, Inc.

narginchk( 0, 2 );
nargoutchk( 0, 1 );

% Try to get some comparison data
if nargin>0
    assert( all( cellfun( 'isclass', varargin, 'gpubench.PerformanceData' ) ) );
    [allData,allDataSummary] = getComparisonData( [varargin{:}]' );
else
    [allData,allDataSummary] = getComparisonData();
end
if isempty(allData)
    error( 'gpuBenchReport:NoData', 'No data to report' );
end

N = numel( allData );
gpubench.multiWaitbar( 'Creating GPUBench report...', 0 );

% Ensure the output folder exists
reportDir = fullfile( tempdir(), 'GPUBenchReport' );
if ~exist( reportDir, 'dir' )
    mkdir( reportDir );
end
copyFiles( reportDir );

% Create the summary page for this device
makeSummaryBarChart( reportDir, allDataSummary );
reportname = makeSummaryPage( reportDir, allDataSummary );
gpubench.multiWaitbar( 'Creating GPUBench report...', 'Increment', 1/(N+1) );

% Now create the detail pages for all devices
for ii=1:numel( allData )
    makePerformancePlots( reportDir, allData, ii );
    makeDetailPage( reportDir, allData, allDataSummary, ii );
    gpubench.multiWaitbar( 'Creating GPUBench report...', 'Increment', 1/(N+1) );
end

gpubench.multiWaitbar( 'Creating GPUBench report...', 'close' );

if nargout
    out = reportname;
else
    web( reportname );
end

end % gpuBenchReport

%-------------------------------------------------------------------------%
function [allData,allDataSummary] = getComparisonData( data )

if nargin<1 || isempty(data)
    data = [];
    % No user data, so use the current release
    thisRelease = regexp( version, 'R\d*[ab]', 'match' );
    thisRelease = thisRelease{1};
else
    % Work out which data-file to use from the release
    thisRelease = data(1).MATLABRelease;
    % Flag the user's data so that we can highlight it
    for ii=1:numel(data)
        data(ii).IsSelected = true;
    end
end

% Try to load the data for this release
otherData = loadDataForRelease( thisRelease, data );

% If no data was found, warn and try an older release
if isempty(otherData)
    allDataFiles = dir( fullfile( 'data', 'R*.mat' ) );
    allDataFiles = {allDataFiles.name};

    % Try each file in turn, starting from the most recent
    for ii=numel(allDataFiles):-1:1
        release = allDataFiles{ii}(1:6);
        otherData = loadDataForRelease( release, data );
        if ~isempty(otherData)
            break;
        end
    end
    % If we reach here without any data then no file had what we wanted.
    % Give up!
    if isempty( otherData )
        error( 'GPUBenchReport:NoData', ...
        ['No pre-stored data was found. Please re-download and install ', ...
        'gpuBench from the File Exchange.'] );
    else
        % Indicate that we're using an older release
        warning( 'GPUBenchReport:NoDataForRelease', ...
            ['There is no pre-stored data for this MATLAB release (%s). ' ...
            'Using data for %s instead. ', ...
            'Check the File Exchange for an updated version of gpuBench ', ...
            'that has data for this release.'], ...
            thisRelease, release );
    end
end

% Construct the summary statistics from all the results and then sort the
% original data using the summary score.
if nargin>0
    allData = [data;otherData];
else
    allData = otherData;
end

if isempty( allData )
    % No data at all, so warn and show something older
    error( 'GPUBenchReport:NoData', ...
        ['There is no pre-stored data for this MATLAB release (%s). ' ...
        'Check the File Exchange for an updated version or use gpuBench ', ...
        'to view the results for your system.'], release );
elseif isempty( otherData )
end

allDataSummary = gpubench.SummaryData( allData );
allData = allData(allDataSummary.SortOrder);
end % getComparisonData

%-------------------------------------------------------------------------%
function otherData = loadDataForRelease( release, existingData )
datafilename = fullfile( gpubench.getDataDir(), [release, '.mat'] );
if exist( datafilename, 'file' ) == 2
    otherData = load( datafilename );
    if ~isfield( otherData, 'results' ) || ~isa( otherData.results, 'gpubench.PerformanceData' )
        error( 'GPUBench:BadDataFile', 'Data file was corrupted, please delete it: %s', datafilename );
    end
    otherData = otherData.results;

    % We don't want to see a result for the exact same card
    if ~isempty(existingData)
        keep = true( size( otherData ) );
        for ii=1:numel( otherData )
            for jj=1:numel(existingData)
                if ~existingData(jj).IsHostData
                    keep(ii) = keep(ii) ...
                        && ~strcmpi( otherData(ii).GPUInfo.Name, existingData(jj).GPUInfo.Name );
                end
            end
            otherData(ii).IsSelected = false;
        end
        otherData = otherData(keep);
    end
else
    otherData = gpubench.PerformanceData.empty(0,1);
end
end % loadDataForRelease

%-------------------------------------------------------------------------%
function makeSummaryBarChart( outDir, summaryData )

assert( isa( summaryData, 'gpubench.SummaryData' ) );

N = numel( summaryData.DeviceName );
deviceNames = summaryData.DeviceName;
functionNames = summaryData.LongName;
flopsResults = summaryData.PeakFLOPS;
isSelected = summaryData.IsSelectedDevice;

% Sort by data-type
types = unique( summaryData.Datatype );
numOfType = zeros(size(types));
colsForType = cell(size(types));
for ii=1:numel(types)
    match = strcmp( summaryData.Datatype, types{ii} );
    numOfType(ii) = sum( match );
    colsForType{ii} = find( match );
end
colOrder = [colsForType{:}];
functionNames = functionNames(colOrder);
flopsResults = flopsResults(:,colOrder);

figh = gpubench.makeFigure( 'Summary' );
set(figh,'Position',[10 10 650 650])
bars = barh( flopsResults'/1e9 );
set( gca, 'YTickLabel', functionNames, 'YDir', 'Reverse' )
xlabel( sprintf('GFLOPS\n(higher is better)') )

% Highlight the selected entry
for ii=1:N
    if isSelected(ii)
        deviceNames{ii} = ['{\bf',deviceNames{ii},' (yours)}'];
    end
end

gpubench.legend( deviceNames{:}, 'Location', 'SouthEast' );
grid on
title( 'Performance Summary' )

% Set colors to fade from blue to red
colors = [
    linspace(0,0.6,N)
    zeros(1,N)
    linspace(0.75,0,N)
    ]';
for ii=1:N
    set( bars(ii), 'FaceColor', colors(ii,:), 'EdgeColor', 0.5*colors(ii,:) );
end

% highlight the user's result
highlightColor = [0 1 0];
selectedResults = find(summaryData.IsSelectedDevice);
N = numel(selectedResults);
for ii=1:N
    ratio = (N-ii+2)/(N+1);
    set( bars(selectedResults(ii)), ...
        'FaceColor', highlightColor*ratio, ...
        'EdgeColor', [0 0 0], ...
        'Linewidth', 2 );
end

% Add dividers between types
hold on
x = get(gca,'XLim');
for ii=1:numel(numOfType)-1
    plot( x, (numOfType(ii)+0.5)*[1 1], 'k-' )
end

gpubench.addAreaShadows( gca() );
gpubench.addGradientToAxes( gca() );

% Save the image to file for the HTML to pick up
filename = 'summarychart.png';
gpubench.captureFigure( figh, fullfile( outDir, filename ), false );
close( figh );
end % makeSummaryBarChart

%-------------------------------------------------------------------------%
function makePerformancePlots( outDir, data, thisIdx )
%Create a FLOPS plot for each results in data with the "thisIdx" result
%highlighted.

fileBase = sprintf('device%d',thisIdx);

plotNames = cell( size(data) );
for ii=1:numel(data)
    plotNames{ii} = data(ii).getDeviceName();
end
plotNames{thisIdx} = ['{\bf',plotNames{thisIdx}, ' (selected)}'];

results = data(thisIdx).Results;

for rr=1:numel( results )
    name = [results(rr).FunctionName, ' (', results(rr).DataType, ')'];
    figh = gpubench.makeFigure( name );
    color = get( gca(), 'ColorOrder' );

    % Plot each device's curve, if they have the relevant data
    for ii=1:numel(data)
        colorIdx = mod(ii-1,size(color,1))+1;
        % Find the corresponding result
        if hasResult( data(ii), name )
            linewidth = 1+2*(ii==thisIdx);
            gpubench.plotFLOPS( getResult( data(ii), name ), color(colorIdx,:), linewidth )
        else
            % We still need to plot something for the legend to be correct
            plot( nan, nan, 'Color', color(colorIdx,:), 'LineWidth', 1 );
        end
    end
    % Add a highlight around the peak-flops point
    colorIdx = mod(thisIdx-1,size(color,1))+1;
    thisResult = getResult( data(thisIdx), name );
    [maxVal,maxIdx] = max( 1e-9 * thisResult.NumOps ./ thisResult.Times);
    plot( thisResult.Sizes(maxIdx), maxVal, ...
        'Color', color(colorIdx,:), ...
        'Marker', 'o', ...
        'MarkerSize', 16, ...
        'Linewidth', 2 );

    title( name );
    gpubench.legend( plotNames{:}, 'Location', 'NorthWest' );
    gpubench.addGradientToAxes( gca() );

    % Due to a bug in ZBuffer renderer, the log-lines disappear when we add
    % a patch to the plot. Stick them back in now.
    xtick = str2num( get( gca, 'XTickLabel' ) ); %#ok<ST2NM>
    ylim = get( gca, 'YLim' );
    for ii=1:numel(xtick)-1
        xminortick = (2:9) * power(10,xtick(ii));
        xdata = [xminortick;xminortick;nan(1,numel(xminortick))];
        ydata = [repmat(ylim',1,numel(xminortick)); nan(1,numel(xminortick))];
        line( 'XData', xdata(:), 'YData', ydata(:), ...
            'LineStyle', ':', ...
            'Color', 0.6*[1 1 1] );
    end

    % Save the image to file for the HTML to pick up
    filename = [fileBase,'-',results(rr).FunctionName,'-',results(rr).DataType,'.png'];
    gpubench.captureFigure( figh, fullfile( outDir, filename ) );
    close( figh );
end
end % makePerformancePlots

%-------------------------------------------------------------------------%
function copyFiles( outDir )
% Copy the required stylesheet and other files into the report folder

dataDir = gpubench.getDataDir();

files = {
    'gpubench.css'
    'title.png'
    'background.png'
    'warning.png'
    };
for ii=1:numel(files)
    copyfile( fullfile( dataDir, files{ii} ), outDir, 'f' );
end
end % copyFiles

%-------------------------------------------------------------------------%
function reportname = makeSummaryPage( outDir, summaryData )
% Create the summary page for this device

assert( isa( summaryData, 'gpubench.SummaryData' ) );

% Find the user's data
userIdx = find( summaryData.IsSelectedDevice, 1, 'first' );
if isempty( userIdx )
    % No user data, so use the first one
    pageName = '';
else
    pageName = [': ', summaryData.DeviceName{userIdx}];
end
reportname = fullfile( outDir, 'index.html' );

fid = fopen( reportname, 'wt' );
fprintf( fid, '\n' );
fprintf( fid, '  <title>GPU Comparison Report%s</title>\n', pageName );
fprintf( fid, '  <link rel="stylesheet" type="text/css" href="gpubench.css"/>\n' );
fprintf( fid, '  <meta author="Generated by GPUBench."/>\n' );
fprintf( fid, '\n' );
fprintf( fid, '\n' );

% All of the content goes in a giant table to control the width
fprintf( fid, '

\n' );
fprintf( fid, '  \n' );

% Main title
fprintf( fid, '
GPU Comparison Report%s
\n', pageName );

% Summary section
fprintf( fid, '
Summary of results
\n' );
% Add the description
writeBoilerPlate( fid, 'summary_intro.html' )

names = summaryData.FunctionName;
numCols = numel( names );

% Print the table header
fprintf( fid, '

\n' );
fprintf( fid, '
\n' );

% Titles for types
types = getDatatypes( summaryData );
colsForType = getColsForType( summaryData, types );
numOfType = cellfun( 'length', colsForType );
colOrder = [colsForType{:}];

fprintf( fid, '
	' );
for ii=1:numel(types)
    fprintf( fid, '      \n', ...
        numOfType(ii) );
    fprintf( fid, '        Results for data-type ''%s''
(In GFLOPS)	\n', ...
        types{ii} );
end

% Titles for each result
fprintf( fid, '
	' );
for cc=1:numCols
    fprintf( fid, '%s	', names{colOrder(cc)} );
end
fprintf( fid, '
\n' );
% Now the body
for rr=1:numel(summaryData.DeviceName)
    fprintf( fid, '
' );
    if (summaryData.IsSelectedDevice(rr))
        nameStr = ['',summaryData.DeviceName{rr},''];
        cellformat = '%1.2f	';
    else
        nameStr = summaryData.DeviceName{rr};
        cellformat = '%1.2f	';
    end
    fprintf( fid, '%s	', rr, nameStr );
    for cc=1:numCols
        colIdx = colOrder(cc);
        fprintf( fid, cellformat, rr, colIdx, summaryData.PeakFLOPS(rr,colIdx) / 1e9 );
    end
    fprintf( fid, '
\n' );
end
fprintf( fid, '
\n\n' );
fprintf( fid, '(click any device name or result to see the detailed data)
\n\n' );

% Add the summary image
fprintf( fid, '\n\n' );
fprintf( fid, '

\n' );

% Footer
fprintf( fid, '
\n' );
writeGeneratedBy( fid );

% Close the main layout table
fprintf( fid, '

\n' );
fprintf( fid, '\n' );
fprintf( fid, '\n' );
fclose( fid );
end % makeSummaryPage

%-------------------------------------------------------------------------%
function makeDetailPage( outDir, data, summaryData, thisIdx )
% Create page of detailed information for one device
name = summaryData.DeviceName{thisIdx};
fileBase = sprintf('device%d',thisIdx);

reportname = fullfile( outDir, [fileBase,'.html'] );

fid = fopen( reportname, 'wt' );
fprintf( fid, '\n' );
fprintf( fid, '  <title>GPU Performance Details: %s</title>\n', name );
fprintf( fid, '  <link rel="stylesheet" type="text/css" href="gpubench.css"/>\n' );
fprintf( fid, '  <meta author="Generated by GPUBench."/>\n' );
fprintf( fid, '\n' );
fprintf( fid, '\n' );

% All of the content goes in a giant table to control the width
fprintf( fid, '

\n' );
fprintf( fid, '  \n' );

% Main title
fprintf( fid, '
GPU Performance Details: %s
\n', name );

% Contents section
fprintf( fid, '

\n' );
fprintf( fid, '    Contents:\n' );
fprintf( fid, '  	\n' );
names = summaryData.LongName;
fprintf( fid, '
\n' );
fprintf( fid, '
System Configuration
\n' );

% Sort the contents by type
types = getDatatypes( summaryData );

for tt=1:numel( types )
    fprintf( fid, '
Results for datatype %s
\n', types{tt} );
    colsForType = getColsForType( summaryData, types{tt} );
    for nn=1:numel( colsForType )
        myCol = colsForType(nn);
        fprintf( fid, '
%s
\n', myCol, names{myCol} );
    end
    fprintf( fid, '

\n' );
end
fprintf( fid, '
\n' );
fprintf( fid, '

\n' );
fprintf( fid, '
\n' );

% Add a section showing the operating environment
fprintf( fid, '
System Configuration
\n' );

% If this isn't the user's system, make that clear
if ~data(thisIdx).IsSelected
    fprintf( fid, '

\n' );
    fprintf( fid, '    	\n' );
    fprintf( fid, '    Note that this is previously stored data and does not reflect your system configuration.	\n' );
    fprintf( fid, '

\n' );
end

fprintf( fid, '
MATLAB Release: %s
\n', data(thisIdx).MATLABRelease );
fprintf( fid, '

\n' );
fprintf( fid, '
Host
\n' );
writeStructTable( fid, data(thisIdx).CPUInfo );
% - only add the GPU if we ran on it
if ~data(thisIdx).IsHostData
    fprintf( fid, '  	\n' );
    fprintf( fid, '
GPU
\n' );
    writeStructTable( fid, data(thisIdx).GPUInfo );
end
fprintf( fid, '

\n' );
fprintf( fid, '
\n' );

% Add one section per result
names = summaryData.LongName;
for nn=1:numel( names )
    fprintf( fid, '
Results for %s
\n', nn, names{nn} );
    if ~hasResult( data(thisIdx), names{nn} )
        % No results for this function
        fprintf( fid, '
No results found for %s.
\n', names{nn} );
        continue;
    end
    myResult = getResult( data(thisIdx), names{nn} );
    % See if there's a description for this function
    writeBoilerPlate( fid, [myResult.FunctionName,'.html'] )

    fprintf( fid, '

\n' );

    fprintf( fid, '

\n');
    fprintf( fid, '      Raw data for %s - %s\n', name, names{nn} );
    fprintf( fid, '

\n');

    % Print the table header
    fprintf( fid, '
\n' );
    fprintf( fid, '
' );
    fprintf( fid, 'Array size
(elements)	' );
    fprintf( fid, 'Num
Operations	' );
    fprintf( fid, 'Time
(ms)	' );
    fprintf( fid, 'GigaFLOPS	' );
    fprintf( fid, '
\n' );
    % Now one row per size
    sizes = myResult.Sizes;
    flops = myResult.NumOps;
    times = myResult.Times;
    [~,peakIdx] = max( flops ./ times );
    baseFormatStr1 = '';
    baseFormatStr2 = '	';
    for ss=1:numel(sizes)
        % Highlight the peak FLOPS row
        if ss==peakIdx
            formatStr1 = [baseFormatStr1,''];
            formatStr2 = ['',baseFormatStr2];
        else
            formatStr1 = baseFormatStr1;
            formatStr2 = baseFormatStr2;
        end
        fprintf( fid, '
' );
        fprintf( fid, [formatStr1,'%s',formatStr2], num2strWithCommas(sizes(ss)) );
        fprintf( fid, [formatStr1,'%s',formatStr2], num2strWithCommas(flops(ss)) );
        fprintf( fid, [formatStr1,'%2.2f',formatStr2], times(ss)*1000 );
        fprintf( fid, [formatStr1,'%2.2f',formatStr2], flops(ss)/times(ss)/1e9 );
        fprintf( fid, '
\n' );
    end
    fprintf( fid, '
\n' );
    fprintf( fid, '(N gigaflops = Nx109 operations per second)
\n\n' );

    fprintf( fid, '

\n');

    % Add the image
    fprintf( fid, '  	\n' );
    fprintf( fid, '    \n', ...
        fileBase, myResult.FunctionName, myResult.DataType );
    fprintf( fid, '

\n' );
end

% Footer
fprintf( fid, '
\n' );

fprintf( fid, '

\n' );
writeGeneratedBy( fid );
fprintf( fid, '  	\n' );
fprintf( fid, '    Back to summary\n' );
fprintf( fid, '

\n' );

% Close the main layout table
fprintf( fid, '

\n' );
fprintf( fid, '\n' );
fprintf( fid, '\n' );
fclose( fid );
end % makeDetailPage

%-------------------------------------------------------------------------%
function writeStructTable( fid, data )
assert( isstruct( data ) && isscalar( data ) );
fprintf( fid, '
\n' );
fields = fieldnames( data );
for ff=1:numel( fields )
    fprintf( fid, '
%s	', fields{ff} );
    fprintf( fid, '' );
    x = data.(fields{ff});
    if ischar( x )
        fprintf( fid, '%s', x );
    elseif isinteger( x )
        fprintf( fid, '%d', x );
    else
        % Try to let MATLAB do the right thing
        fprintf( fid, '%g', x );
    end
    fprintf( fid, '
\n' );
end
fprintf( fid, '
\n' );
end % writeStructTable

%-------------------------------------------------------------------------%
function writeBoilerPlate( outFid, filename )
%Read some boiler-plate HTML and paste it into the supplied output file
filename = fullfile( gpubench.getDataDir(), filename );
inFid = fopen( filename, 'rt' );
if inFid<=0
    warning( 'gpuBenchReport:MissingBoilerPlateFile', ...
        'Input file could not be opened: %s', filename );
    return;
end
txt = fread( inFid );
fwrite( outFid, txt );
fclose( inFid );
end % writeBoilerPlate

%-------------------------------------------------------------------------%
function writeGeneratedBy( outFid )
%Write the "generated by" string into the footer

fprintf( outFid, 'Generated by gpuBench v%s: %s\n', ...
    gpubench.version(), datestr( now(), 'yyyy-mm-dd HH:MM:SS' ) );
end % writeGeneratedBy

%-------------------------------------------------------------------------%
function str = num2strWithCommas( num )
%Convert an integer into a string with commas separating sets of 3 digits
%
%  e.g. num2StrWithCommas(12345678) = '12,345,678'

% First convert using the standard method
baseStr = num2str( abs(num) );
% now insert some commas.
% pad to a multiple of 3
padding = 3 - (mod(length(baseStr)-1,3)+1);
str = [repmat(' ',1,padding), baseStr];
numCols = length(str)/3;
str = [reshape(str,3,numCols);repmat(',',1,numCols)];
str = strtrim( str(1:end-1) );
% Finally, re-insert the sign
if num<0
    str = ['-',str];
end
end % num2StrWithCommas


%            3
%1'----------------------2'
%  |                    |
%  |                    |
% 1|                    |2
%  |                    |
%  |                    |
%4'----------------------3'
%            4

%% it is better to define by mapping cuboid to rectangle
GeoRule(1).viewID = 1;
GeoRule(1).surfaceID = 2;
GeoRule(1).pointID = [6 8 4 2];
GeoRule(2).viewID = 2;
GeoRule(2).surfaceID = 1;
GeoRule(2).pointID = [7 5 1 3];
GeoRule(3).viewID = 3;
GeoRule(3).surfaceID = 4;
GeoRule(3).pointID = [8 7 3 4];
GeoRule(4).viewID = 4;
GeoRule(4).surfaceID = 3;
GeoRule(4).pointID = [5 6 2 1];
GeoRule(5).viewID = 5;
GeoRule(5).surfaceID = 6;
GeoRule(5).pointID = [7 8 6 5];
GeoRule(6).viewID = 6;
GeoRule(6).surfaceID = 5;
GeoRule(6).pointID = [1 2 4 3];

CubRule(1).suf = [1 3];
CubRule(1).cont = [4 8];
CubRule(1).check = 5;

CubRule(2).suf = [4 1];
CubRule(2).cont = [2 6];
CubRule(2).check = 5;

CubRule(3).suf = [2 3];
CubRule(3).cont = [3 7];
CubRule(3).check = 5;

CubRule(4).suf = [2 4];
CubRule(4).cont = [1 5];
CubRule(4).check = 5;

CubRule(5).suf = [5 1];
CubRule(5).cont = [6 8];
CubRule(5).check = [3 4];

CubRule(6).suf = [5 2];
CubRule(6).cont = [5 7];
CubRule(6).check = [3 4];

CubRule(7).suf = [3 5];
CubRule(7).cont = [7 8];
CubRule(7).check = [1 2];

CubRule(8).suf = [4 5];
CubRule(8).cont = [5 6];
CubRule(8).check = [1 2];

%% cuboid rule version 1
CuboidRule(1).lhs.vid = 1;
CuboidRule(1).lhs.lid = 2;
CuboidRule(1).lhs.pid = [3 2];
CuboidRule(1).rhs.vid = 3;
CuboidRule(1).rhs.lid = 1;
CuboidRule(1).lhs.pid = [4 1];
CuboidRule(1).chk.condition = [2 3 0];
CuboidRule(1).chk.vid = 5;
CuboidRule(1).chk.lhslid = [3 2];
CuboidRule(1).chk.rhslid = [3 3];

CuboidRule(2).lhs.vid = 3;
CuboidRule(2).lhs.lid = 2;
CuboidRule(2).rhs.vid = 2;
CuboidRule(2).rhs.lid = 1;
CuboidRule(2).chk.condition = [3 0];
CuboidRule(2).chk.vid = 5;
CuboidRule(2).chk.lhslid = [3 3];
CuboidRule(2).chk.rhslid = [3 1];

CuboidRule(3).lhs.vid = 4;
CuboidRule(3).lhs.lid = 2;
CuboidRule(3).rhs.vid = 1;
CuboidRule(3).rhs.lid = 1;
CuboidRule(3).chk.condition = [3 0];
CuboidRule(3).chk.vid = 5;
CuboidRule(3).chk.lhslid = [3 4];
CuboidRule(3).chk.rhslid = [3 2];

CuboidRule(4).lhs.vid = 2;
CuboidRule(4).lhs.lid = 2;
CuboidRule(4).rhs.vid = 4;
CuboidRule(4).rhs.lid = 1;
CuboidRule(4).chk.condition = [3 0];
CuboidRule(4).chk.vid = 5;
CuboidRule(4).chk.lhslid = [3 1];
CuboidRule(4).chk.rhslid = [3 4];

%-------------------------------------
CuboidRule(5).lhs.vid = 1;
CuboidRule(5).lhs.lid = 3;
CuboidRule(5).rhs.vid = 5;
CuboidRule(5).rhs.lid = 2;
CuboidRule(5).chk(1).condition = [2 1];
CuboidRule(5).chk(1).vid = 4;
CuboidRule(5).chk(1).lhslid = [1 2];
CuboidRule(5).chk(1).rhslid = [4 3];
CuboidRule(5).chk(2).condition = [2 0];
CuboidRule(5).chk(2).vid = 3;
CuboidRule(5).chk(2).lhslid = [2 1];
CuboidRule(5).chk(2).rhslid = [3 3];

CuboidRule(6).lhs.vid = 2;
CuboidRule(6).lhs.lid = 3;
CuboidRule(6).rhs.vid = 5;
CuboidRule(6).rhs.lid = 1;
CuboidRule(6).chk(1).condition = [2 1];
CuboidRule(6).chk(1).vid = 4;
CuboidRule(6).chk(1).lhslid = [2 1];
CuboidRule(6).chk(1).rhslid = [3 1];
CuboidRule(6).chk(2).condition = [2 0];
CuboidRule(6).chk(2).vid = 3;
CuboidRule(6).chk(2).lhslid = [1 2];
CuboidRule(6).chk(2).rhslid = [3 3];

CuboidRule(7).lhs.vid = 3;
CuboidRule(7).lhs.lid = 3;
CuboidRule(7).rhs.vid = 5;
CuboidRule(7).rhs.lid = 3;
CuboidRule(7).chk(1).condition = [1 0];
CuboidRule(7).chk(1).vid = 1;
CuboidRule(7).chk(1).lhslid = [1 2];
CuboidRule(7).chk(1).rhslid = [2 3];
CuboidRule(7).chk(2).condition = [1 1];
CuboidRule(7).chk(2).vid = 2;
CuboidRule(7).chk(2).lhslid = [2 1];
CuboidRule(7).chk(2).rhslid = [1 3];

CuboidRule(8).lhs.vid = 4;
CuboidRule(8).lhs.lid = 3;
CuboidRule(8).rhs.vid = 5;
CuboidRule(8).rhs.lid = 4;
CuboidRule(8).chk(1).condition = [1 0];
CuboidRule(8).chk(1).vid = 1;
CuboidRule(8).chk(1).lhslid = [2 1];
CuboidRule(8).chk(1).rhslid = [2 3];
CuboidRule(8).chk(2).condition = [1 1];
CuboidRule(8).chk(2).vid = 2;
CuboidRule(8).chk(2).lhslid = [1 2];
CuboidRule(8).chk(2).rhslid = [1 3];


% eeg_rejsuperpose() - superpose rejections of a EEG dataset.
%
% Usage:
%   >> EEGOUT = eeg_rejsuperpose( EEGIN, typerej, Rmanual, Rthres, ...
%                    Rconst, Rent, Rkurt, Rfreq, Rothertype);
%
% Inputs:
%   EEGIN      - input dataset
%   typerej    - type of rejection (1=raw data; 0=ica).
%   Rmanual    - include manual rejection (0|1).
%   Rthres     - include threshold rejection (0|1).
%   Rconst     - include rejection of constant activity (0|1).
%   Rent       - include entropy rejection (0|1).
%   Rkurt      - include kurtosis rejection (0|1).
%   Rfreq      - include frequcy based rejection (0|1).
%   Rothertype - include manual rejection (0|1).
%
% Outputs:
%   EEGOUT     - with rejglobal and rejglobalE fields updated
%
% See also: eeglab()

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

function [EEG, com] = eeg_rejsuperpose( EEG, typerej, Rmanual, Rthres, Rconst, ...
                              Rent, Rkurt, Rfreq, Rothertype);

if nargin < 9
	help eeg_rejsuperpose;
	return;
end;

typerej = ~typerej;
rejglobal  = zeros( 1, EEG.trials);
rejglobalE = zeros( EEG.nbchan, EEG.trials);

if typerej == 0 | Rothertype
	if Rmanual
		rejglobal  = rejarray( rejglobal,  EEG.reject.rejmanual); % see bottom for the
		rejglobalE = rejarray( rejglobalE, EEG.reject.rejmanualE); % function rejarray
	end;
	if Rthres
		rejglobal  = rejarray( rejglobal,  EEG.reject.rejthresh);
		rejglobalE = rejarray( rejglobalE, EEG.reject.rejthreshE);
	end;
	if Rfreq
		rejglobal  = rejarray( rejglobal,  EEG.reject.rejfreq);
		rejglobalE = rejarray( rejglobalE, EEG.reject.rejfreqE);
	end;
	if Rconst
		rejglobal  = rejarray( rejglobal,  EEG.reject.rejconst);
		rejglobalE = rejarray( rejglobalE, EEG.reject.rejconstE);
	end;
	if Rent
		rejglobal  = rejarray( rejglobal,  EEG.reject.rejjp);
		rejglobalE = rejarray( rejglobalE, EEG.reject.rejjpE);
	end;
	if Rkurt
		rejglobal  = rejarray( rejglobal,  EEG.reject.rejkurt);
		rejglobalE = rejarray( rejglobalE, EEG.reject.rejkurtE);
	end;
end;

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

if typerej == 1 | Rothertype
	if Rmanual
		rejglobal  = rejarray( rejglobal,  EEG.reject.icarejmanual);
		rejglobalE = rejarray( rejglobalE, EEG.reject.icarejmanualE);
	end;
	if Rthres
		rejglobal  = rejarray( rejglobal,  EEG.reject.icarejthresh);
		rejglobalE = rejarray( rejglobalE, EEG.reject.icarejthreshE);
	end;
	if Rfreq
		rejglobal  = rejarray( rejglobal,  EEG.reject.icarejfreq);
		rejglobalE = rejarray( rejglobalE, EEG.reject.icarejfreqE);
	end;
	if Rconst
		rejglobal  = rejarray( rejglobal,  EEG.reject.icarejconst);
		rejglobalE = rejarray( rejglobalE, EEG.reject.icarejconstE);
	end;
	if Rent
		rejglobal  = rejarray( rejglobal,  EEG.reject.icarejjp);
		rejglobalE = rejarray( rejglobalE, EEG.reject.icarejjpE);
	end;
	if Rkurt
		rejglobal  = rejarray( rejglobal,  EEG.reject.icarejkurt);
		rejglobalE = rejarray( rejglobalE, EEG.reject.icarejkurtE);
	end;
end;

EEG.reject.rejglobal = rejglobal;
EEG.reject.rejglobalE = rejglobalE;

com =sprintf('%s = eeg_rejsuperpose( %s, %d, %d, %d, %d, %d, %d, %d, %d);', ...
	  inputname(1), inputname(1), ~typerej, Rmanual, Rthres, Rconst, Rent, Rkurt, Rfreq, Rothertype);

return;

% subfunction rejecting an array ------
function dest = rejarray( dest, ori)
	if ~isempty(ori)
		dest = dest | ori;
	end;
return;


function result = hlp_config(configname, operation, varargin)
% helper function to process human-readable config scripts.
% Result = hlp_config(FileName,Operation,VariableName,Value,NVPs...)
%
% Config scripts consist of assignments of the form name = value; to set configuration options. In
% addition, there may be any type of comments, conditional control flow, etc - e.g., setting certain
% values on some platforms and others on others. This function allows to get or set the value
% assigned to a variable in the place of the script where it is actually assigned on the current
% platform. Note that the respective variable has to be already in the config file for this function
% to work.
%
% In:
%   FileName : name of the configuration file to process
%
%   Operation : operation to perform on the config file
%               'get' : get the currently defined value of a given variable
%               'set' : replace the current defintion of a given variable
%
%   VariableName : name of the variable to be affected (must be a MATLAB identifier)
%
%   Value : the new value to be assigned, if the operation is 'set', as a string
%           note that most data structures can be converted into a string via hlp_tostring
%
%   NVPs... : list of further name-value pairs, where each name denotes a config variables and the subsequent
%             value is the string expression that should be written into the config file. It is
%             generally a good idea to use hlp_tostring() to turn a data structure into such a string
%             representation.
%
% Out:
%   Result : the current value of the variable of interest, when using the 'get'
%            operation
%
% Notes:
%   There can be multiple successive variable name / value pairs for the set mode.
%   If an error occurs during a set operation, any changes will be rolled back.
%
% Examples:
%   % read out the value of the 'data' config variable from a config file
%   data = hlp_config('/home/christian/myconfig.m','get','data')
%
%   % override the values of the 'files' and 'capacity' config variables in the given config script
%   hlp_config('/home/christian/myconfig.m', 'set', 'files',myfiles, 'capacity',1000)
%
%                                Christian Kothe, Swartz Center for Computational Neuroscience, UCSD
%                                2010-11-19

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

if ~exist(configname,'file')
    error('hlp_config:file_not_found','The specified config file was not found.'); end

switch operation
    case 'get'
        varname = varargin{1};
        if ~isvarname(varname)
            error('hlp_config:bad_varname','The variable name must be a valid MATLAB identifier.'); end
        % get the currently defined value of a variable...
        result = get_value(configname,varname);
    case 'set'
        backupfile = [];
        try
            % apply first assignment
            backupfile = set_value(configname,varargin{1},varargin{2},true);
            for k = 4:2:length(varargin)
                % apply all other assignments
                set_value(configname,varargin{k-1},varargin{k},false); end
        catch e
            % got an error; roll back changes if necessary
            if ~isempty(backupfile)
                try
                    movefile(backupfile,configname);
                catch
                    disp(['Could not roll back changes. You can manually revert changes by replacing ' configname ' by ' backupfile '.']);
                end
            end
            rethrow(e);
        end
    otherwise
        error('hlp_config:unsupported_option','Unsupported config operation.');
end

% run the given config script and obtain the current value of the given variable...
function res = get_value(filename__,varname__)
try
    run_script(filename__);
catch e
    error('hlp_config:erroneous_file',['The config file is erroneous; Error message: ' e.message]);
end
if ~exist(varname__,'var')
    error('hlp_config:var_not_found','The variable is not being defined in the config file.'); end
res = eval(varname__);

function backup_name = set_value(filename,varname,newvalue,makebackup)
backup_name = [];
if ~exist(filename,'file')
    error('hlp_config:file_not_found','The config file was not found.'); end
if ~isvarname(varname)
    error('hlp_config:incorrect_value','The variable name must be a valid MATLAB identifier.'); end
if ~ischar(newvalue)
    error('hlp_config:incorrect_value','The value to be assigned must be given as a string.'); end
try
    % read the config file contents
    contents = {};
    f = fopen(filename,'r');
    while 1
        l = fgetl(f);
        if ~ischar(l)
            break; end
        contents{end+1} = [l 10];
    end
    fclose(f);
    % turn it into one str
    contents = [contents{:}];
catch e
    try fclose(f); catch,end
    error('hlp_config:cannot_read_config',['Cannot read the config file; Error message: ' e.message]);
end

% now check if the file is actually writable
try
    f = fopen(filename,'r+');
    if f ~= -1
        fclose(f);
    else
        error('hlp_config:permissions_error','Could not update the config file %s. Please check file permissions and try again.',filename);
    end
catch
    error('hlp_config:permissions_error','Could not update the config file %s. Please check file permissions and try again.',filename);
end

% if the desired config variables does not occur at all in the file (assuming that this is a legacy file)...
% (note that this check will not catch cases where the variable name might plausibly appear in comments or
% some sub-string)
if isempty(strfind(contents,varname))
    % ... append the assignment to the end
    f = fopen(filename,'a');
    fprintf(f,['\n%% the following variable was appended by hlp_config\n' varname ' = ' newvalue ';\n']);
    fclose(f);
    fprintf('Note: the variable %s did not occur in your config file %s; appended it to the end.\n',varname,filename);
else
    % temporarily replace stray semicolons by a special character and contract ellipses,
    % so that the subsequent assignment regex matching will not get derailed)
    evalstr = contents;
    comment_flag = false;
    string_flag = false;
    bracket_level = 0;
    ellipsis_flag = false;
    substitute = false(1,length(evalstr)); % this mask indicates where we have to subsitute reversibly by special characters
    spaceout = false(1,length(evalstr));   % this mask indicates where we can substitute irreversibly by whitespace characters...
    for k=1:length(evalstr)
        % everything that follows an ellipsis will be spaced out (including the subsequent newline that resets it)
        if ellipsis_flag
            spaceout(k) = true; end
        switch evalstr(k)
            case ';' % semicolon
                % in strs, brackets or comments: indicate need for substitution
                if string_flag || bracket_level>0 || comment_flag
                    substitute(k) = true; end
            case '''' % quotes
                % flip str flag, unless in comment
                if ~comment_flag
                    string_flag = ~string_flag; end
            case 10 % newline
                % reset bracket level, unless in ellipsis
                if ~ellipsis_flag
                    bracket_level = 0; end
                % reset comment flag, str flag and ellipsis flag
                comment_flag = false;
                string_flag = false;
                ellipsis_flag = false;
            case {'[','{'} % opening array bracket
                % if not in str nor comment, increase bracket level
                if ~string_flag && ~comment_flag
                    bracket_level = bracket_level+1; end
            case {']','}'} % closing array bracket
                % if not in str nor comment, decrease bracket level
                if ~string_flag && ~comment_flag
                    bracket_level = bracket_level-1; end
            case '%' % comment character
                % if not in str, switch on comment flag
                if ~string_flag
                    comment_flag = true; end
            case '.' % potential ellipsis character
                % if not in comment nor in str, turn on ellipsis and comment
                if ~string_flag && ~comment_flag && k>2 && strcmp(evalstr(k-2:k),'...')
                    ellipsis_flag = true;
                    comment_flag = true;
                    % we want to replace the ellipsis and everything that follows up to and including the next newline
                    spaceout(k-2:k) = true;
                end
        end
    end
    % replace the characters that need to be substituted (by the bell character)
    evalstr(substitute) = 7;
    evalstr(spaceout) = ' ';
    % replace all assignments of the form "varname = *;" by "varname{end+1} = num;"
    [starts,ends] = regexp(evalstr,[varname '\s*=[^;\n]*;']);
    for k=length(starts):-1:1
        evalstr = [evalstr(1:starts(k)-1) varname '{end+1} = struct(''assignment'',' num2str(k) ');' evalstr(ends(k)+1:end)]; end
    % add initial assignment
    evalstr = [sprintf('%s = {};\n',varname) evalstr];
    % back-substitute the special character by semicolons
    evalstr(evalstr==7) = ';';

    % evaluate contents and get the matching assignment id's
    ids = run_protected(evalstr,varname);

    % check validity of the updated value, and of the updated config file
    try
        % check if the value str can in fact be evaluated
        newvalue_eval = eval(newvalue);
    catch
        error('hlp_config:incorrect_value','The value "%s" (to be assigned to variable "%s") cannot be evaluated properly. Note that, for example, string values need to be quoted.',newvalue,varname);
    end
    % evaluate the original config script and record the full variable assignment
    [dummy,wspace_old] = run_protected(contents); %#ok<ASGLU>
    % splice the new value into the config file contents, for the last assignment in ids
    id = ids{end}.assignment;
    contents = [contents(1:starts(id)-1) varname ' = ' newvalue ';' contents(ends(id)+1:end)];
    % evaluate the new config script and record the full variable assignment
    [dummy,wspace_new] = run_protected(contents); %#ok<ASGLU>
    % make sure that the only thing that has changed is the assignment to the variable of interest
    wspace_old.(varname) = newvalue_eval;
    if ~isequalwithequalnans(wspace_old,wspace_new)
        error('hlp_config:update_failed','The config file can not be properly updated.'); end

    % apparently, everything went well, except for the following possibilities
    %  * the newly assigned value makes no sense (--> usage error)
    %  * the settings were changed for unanticipated platforms (--> this needs to be documented properly)
    if makebackup
        try
            % make a backup of the original config file using a fresh name (.bak00X)
            [p,n,x] = fileparts(filename);
            files = dir([p filesep n '*.bak*']);
            backup_numbers = cellfun(@(n)str2num(n(end-2:end)),{files.name},'UniformOutput',false);
            backup_numbers = [backup_numbers{:}];
            if ~isempty(backup_numbers)
                new_number = 1 + max(backup_numbers);
            else
                new_number = 1;
            end
            backup_name = [p filesep n '.bak' sprintf('%03i',new_number)];
            copyfile(filename,backup_name);
            % set read permissions
            warning off MATLAB:FILEATTRIB:SyntaxWarning
            fileattrib(backup_name,'+w','a');
        catch
            error('hlp_config:permissions_error','Could not create a backup of the original config file %s. Please check file permissions and try again.',filename);
        end
    end

    % split the contents into lines again
    contents = strsplit(contents,10);
    try
        % re-create the file, line by line
        f = fopen(filename,'w+');
        for k=1:length(contents)
            fwrite(f,contents{k});
            fprintf(f,'\n');
        end
        fclose(f);
        % set file attributes
        warning off MATLAB:FILEATTRIB:SyntaxWarning
        fileattrib(filename,'+w','a');
    catch
        try fclose(f); catch,end
        error('hlp_config:permissions_error','Could not override the config file %s. Please check file permissions and try again.',filename);
    end
end

% run the given config script and obtain the current value of the given variable...
function [res,wspace] = run_protected(code__,varname__)
try
    eval(code__);
    % collect all variables into a workspace struct
    infos = whos();
    for n = {infos.name}
        if ~any(strcmp(n{1},{'code__','varname__'}))
            wspace.(n{1}) = eval(n{1}); end
    end
    if exist('varname__','var')
        % if a specific variable was to be inspected...
        res = eval(varname__);
        if ~iscell(res) || length(res) < 1 || ~all(cellfun('isclass',res,'struct')) || ~all(cellfun(@(x)isfield(x,'assignment'),res))
            error('Not all assignments to the variable were correctly identified.'); end
    else
        res = [];
    end
catch e
    error('hlp_config:update_error',['The config file could not be parsed (probably it is ill-formed); Debug message: ' e.message]);
end

% split a string without fusing delimiters (unlike hlp_split)
function strs = strsplit(str, delim)
idx = strfind(str, delim);
strs = cell(numel(idx)+1, 1);
idx = [0 idx numel(str)+1];
for k = 2:numel(idx)
    strs{k-1} = str(idx(k-1)+1:idx(k)-1); end

% for old MATLABs that can't properly move files...
function movefile(src,dst)
try
    builtin('movefile',src,dst);
catch e
    if any([src dst]=='$') && hlp_matlab_version <= 705
        if ispc
            [errcode,text] = system(sprintf('move ''%s'' ''%s''',src,dst)); %#ok<NASGU>
        else
            [errcode,text] = system(sprintf('mv ''%s'' ''%s''',src,dst)); %#ok<NASGU>
        end
        if errcode
            error('Failed to move %s to %s.',src,dst); end
    else
        rethrow(e);
    end
end


function [val1,val2,val3,val4] = outtowks(mode)
%
% Utility Function: OUTTOWKS
%
% This function provides a gateway from the environment to the workspace

% Author: Craig Borghesani
% Date: 9/5/94
% Revised: 11/15/94
% Copyright (c) 1999, Prentice-Hall

if mode == 0,
 f = gcf;
else
 f2 = gcf;
 f = get(f2,'userdata');
end
ui_data = get(f,'userdata');
ui_han = ui_data{1};
ui_obj = ui_data{2};
ui_han2 = get(ui_han(51),'userdata');
cur_sys = get(ui_han(30),'userdata');
stat_bar = get(ui_han(43),'userdata');
win_str = get(ui_han(48),'userdata');
if length(ui_han2),
 stat_bar2 = ui_han2(16);
end

if mode==0, % Setup

 if ~figflag(['Out to Workspace...',win_str]),
  f2 = figure('numbertitle','off','menubar','none','name',['Out to Workspace...',win_str],...
              'pos',[30,50,395,187],'color',[0.8,0.8,0.8],'resize','off',...
              'userdata',f);

% Variable Input Fields
  del=17;
  uicontrol('style','text','string','Variable Names',...
            'pos',[10,145+del,375,17],'horizontalalignment','left',...
            'backgroundcolor',[0.8,0.8,0.8]);
  ui_han2(1) = uicontrol('style','text','string','Num:',...
            'pos',[0,123+del,40,17],'horizontalalignment','right',...
            'backgroundcolor',[0.8,0.8,0.8]);
  ui_han2(2) = uicontrol('style','edit','pos',[40,123+del,55,20],'backgroundcolor','w',...
                     'callback','outtowks(1)',...
                     'horiz','left');

  ui_han2(3) = uicontrol('style','text','string','Den:',...
            'pos',[95,123+del,40,17],'horizontalalignment','right',...
            'backgroundcolor',[0.8,0.8,0.8]);
  ui_han2(4) = uicontrol('style','edit','pos',[135,123+del,55,20],'backgroundcolor','w',...
                     'callback','outtowks(1)',...
                     'horiz','left');

  ui_han2(5) = uicontrol('style','text','string','',...
            'pos',[190,123+del,40,17],'horizontalalignment','right','vis','off',...
            'backgroundcolor',[0.8,0.8,0.8]);
  ui_han2(6) = uicontrol('style','edit','pos',[230,123+del,55,20],'backgroundcolor','w',...
                     'callback','outtowks(1)','vis','off',...
                     'horiz','left');

  ui_han2(7) = uicontrol('style','text','string','',...
            'pos',[285,123+del,40,17],'horizontalalignment','right','vis','off',...
            'backgroundcolor',[0.8,0.8,0.8]);
  ui_han2(8) = uicontrol('style','edit','pos',[325,123+del,55,20],'backgroundcolor','w',...
                     'callback','outtowks(1)','vis','off',...
                     'horiz','left');

% Option Fields
  uicontrol('style','text','string','Format',...
            'pos',[10,100+del,180,17],'horizontalalignment','left',...
            'backgroundcolor',[0.8,0.8,0.8]);
  ui_han2(9) = uicontrol('style','radio','pos',[10,80+del,180,20],...
                     'string','Numerator/Denominator',...
                     'backgroundcolor',[0.8,0.8,0.8],...
                     'callback','outtowks(2)','value',1);
  ui_han2(10) = uicontrol('style','radio','pos',[10,60+del,180,20],...
                     'string','Zero/Pole/Gain',...
                     'backgroundcolor',[0.8,0.8,0.8],...
                     'callback','outtowks(2)','value',0);
  ui_han2(11) = uicontrol('style','radio','pos',[10,40+del,180,20],...
                     'string','State Space',...
                     'backgroundcolor',[0.8,0.8,0.8],...
                     'callback','outtowks(2)','value',0);

  uicontrol('style','text','string','Transfer Function',...
            'pos',[205,100+del,180,17],'horizontalalignment','left',...
            'backgroundcolor',[0.8,0.8,0.8]);
  ui_han2(12) = uicontrol('style','radio','pos',[205,80+del,180,20],...
                     'string','Plant',...
                     'backgroundcolor',[0.8,0.8,0.8],...
                     'callback','outtowks(3)','value',1);
  ui_han2(13) = uicontrol('style','radio','pos',[205,60+del,180,20],...
                     'string','Forward Controller',...
                     'backgroundcolor',[0.8,0.8,0.8],...
                     'callback','outtowks(3)','value',0);
  ui_han2(14) = uicontrol('style','radio','pos',[205,40+del,180,20],...
                     'string','Feedback Controller',...
                     'backgroundcolor',[0.8,0.8,0.8],...
                     'callback','outtowks(3)','value',0);

  for c=1:3,
   set(ui_han2(8+c),'userdata',ui_han2(:,8+[1:(c-1),(c+1):3]));
  end

  for c=1:3,
   set(ui_han2(11+c),'userdata',ui_han2(:,11+[1:(c-1),(c+1):3]));
  end

  ui_han2(15) = uicontrol('style','push','pos',[103,10+del,60,20],'string','OK');
  uicontrol('style','push','pos',[166,10+del,60,20],'string','Cancel',...
            'callback','outtowks(5)');
  uicontrol('style','push','pos',[232,10+del,60,20],'string','Help',...
            'callback','userhelp(5,3)');

  ui_han2(16) = uicontrol('style','edit','pos',[0,0,395,20],...
             'foregroundcolor','k',...
             'horizontalalignment','left');
  stat_bar2 = ui_han2(16);
  set(ui_han(51),'userdata',ui_han2);
 end

 set(stat_bar2,'string','Enter variable names into edit boxes, press OK when done');
 drawnow;

elseif mode==1, % edit fields

% build output and input strings
 output_str = [];

 for k = 2:2:8,
  var_str = get(ui_han2(k),'string');
  if length(var_str),
   output_str = [output_str,var_str,','];
  end
 end

% remove extra comma
 output_str(length(output_str))=[];

% setup callback to pass desired variables to workspace
 callback_str = ['[',output_str,']=outtowks(4);'];
 set(ui_han2(15),'callback',callback_str);

elseif mode==2, % format

 cur_obj = get(f2,'currentobject');
 data = get(cur_obj,'userdata');
 set(data,'value',0);
 set(cur_obj,'value',1);

 if cur_obj == ui_han2(9), % num/den
  set(ui_han2(5:8),'vis','off');
  set(ui_han2(1),'string','Num:');
  set(ui_han2(3),'string','Den:');

 elseif cur_obj == ui_han2(10), % z/p/k
  set(ui_han2(7:8),'vis','off');
  set(ui_han2(5:6),'vis','on');
  set(ui_han2(1),'string','Zero:');
  set(ui_han2(3),'string','Pole:');
  set(ui_han2(5),'string','Gain:');

 elseif cur_obj == ui_han2(11), % state space
  set(ui_han2(5:8),'vis','on');
  set(ui_han2(1),'string','A:');
  set(ui_han2(3),'string','B:');
  set(ui_han2(5),'string','C:');
  set(ui_han2(7),'string','D:');
 end

elseif mode==3, % plant or controller

 cur_obj = get(f2,'currentobject');
 data = get(cur_obj,'userdata');
 set(data,'value',0);
 set(cur_obj,'value',1);

elseif mode==4, % OK

 if get(ui_han2(12),'value'), sel = 3;
 elseif get(ui_han2(13),'value'), sel = 6;
 elseif get(ui_han2(14),'value'), sel = 9; end
 term_mat = get(ui_han(sel+cur_sys),'userdata');

 if get(ui_han2(9),'value'),
  [var1,var2]=termextr(term_mat);
  len = 2;
 end

 if get(ui_han2(10),'value'),
  [var1,var2,var3]=term2zpk(term_mat);
  len = 3;
 end

 if get(ui_han2(11),'value'),
  [n,d]=termextr(term_mat);
  [var1,var2,var3,var4]=tf2ss(n,d);
  len = 4;
 end

 ct=1;
 for k = 1:len,
  eval(['val',int2str(ct),'=var',int2str(k),';']);
  ct=ct+1;
 end

 set(stat_bar,'string','Variables passed to workspace');

 set(f2,'vis','off');

elseif mode==5, % Cancel

 set(f2,'vis','off');

end


function dtiCompileMex

oldDir = pwd;
rootdir=fileparts(fileparts(which('mrDiffusion')));

mexFiles = {};

cd(fileparts(which('dtiFiberTracker.cxx')));
disp('Compiling dtiFiberTracker.cxx ...');
try
    mex -O -I./jama dtiFiberTracker.cxx
    mexFiles{end+1} = ['dtiFiberTracker.' mexext];
catch
    disp('Compiling dtiFiberTracker.cxx FAILED...');
end

cd(fileparts(which('nearpoints.cxx')));
disp('Compiling nearpoints.cxx ...');
try
    mex -O nearpoints.cxx
    mexFiles{end+1} = ['nearpoints.' mexext];
catch
    disp('Compiling nearpoints.cxx FAILED...');
end

cd(fileparts(which('magicwand1.c')));
disp('Compiling magicwand1.c ...');
try
    mex -O magicwand1.c
    mexFiles{end+1} = ['magicwand1.' mexext];
catch
    disp('Compiling magicwand1.c FAILED...');
end

cd(fileparts(which('dtiJointHist.c')));
disp('Compiling dtiJointHist.c ...');
try
    mex -O dtiJointHist.c
    mexFiles{end+1} = ['dtiJointHist.' mexext];
catch
    disp('Compiling dtiJointHist.c FAILED...');
end

cd(fileparts(which('niftiRead.c')));
disp('Compiling read/writeFileNifti ...');
try
    mex niftiRead.c nifti1_io.c znzlib.c zlib/adler32.c zlib/compress.c zlib/crc32.c zlib/deflate.c zlib/gzio.c zlib/infback.c zlib/inffast.c zlib/inflate.c zlib/inftrees.c zlib/trees.c zlib/zutil.c
    mexFiles{end+1} = ['niftiRead.' mexext];
    mex writeFileNifti.c nifti1_io.c znzlib.c zlib/adler32.c zlib/compress.c zlib/crc32.c zlib/deflate.c zlib/gzio.c zlib/infback.c zlib/inffast.c zlib/inflate.c zlib/inftrees.c zlib/trees.c zlib/zutil.c
    mexFiles{end+1} = ['writeFileNifti.' mexext];
catch
    disp('Compiling read/writeFileNifti.c FAILED...');
end

%      disp('Compiling dtiTensorInterp_Pajevic.c ...');
%      if(strcmp(computer,'GLNX86'))
%          mex -O dtiTensorInterp_Pajevic.c ./bcadtlib.so
%          mexFiles{end+1} = ['dtiTensorInterp_Pajevic.' mexext];
%      else
%          warning('dtiTensorInterp_Pajevic.c can only be compiled under 32-bit linux! Skipping it...'); %#ok<WNTAG>
%      end

%Confusing, multiple copies of sources and/or mex files in a different
%directory
%(1) 'mrManDist'; %Csource: c source
%(2) 'dijkstra2';%Csource under ManifoldUtilities AND within dir mrFlatMesh
%(3) 'dijkstra';%Csource

%'curvature'; -- where is the source?
%'smooth_mesh'; -- where is the source?
%'build_mesh'; -- where is the source?

%List of files to compile with path relative from the root vistasoft dir
functionsToCompile={
    ['mrAlign' filesep 'regInplanes'];
    ['mrAlign' filesep 'regHistogram'];
    ['mrAnatomy' filesep 'MrGray' filesep 'GrowGrayMatter' filesep 'grow_gray']; %cpp
    ['mrAnatomy' filesep 'mrMesh' filesep 'tcpToolbox' filesep 'pnet'];
    ['mrAnatomy' filesep 'VolumeUtilities' filesep 'mrAnatFastInterp3'];
    ['mrAnatomy' filesep 'VolumeUtilities' filesep 'myCinterp3'];
    ['mrDiffusion' filesep 'src' filesep 'dtiFitTensor'];
    ['mrDiffusion' filesep 'src' filesep 'dtiSplitTensor'];
    ['mrDiffusion' filesep 'xform' filesep 'fastDeformation' filesep 'trilin'];
    ['mrDiffusion' filesep 'xform' filesep 'fastDeformation' filesep 'initInvDiagsInC'];
    ['mrLoadRet' filesep 'Analysis' filesep 'SignalProc' filesep 'sumOfNeighbors'];
    ['mrLoadRet' filesep 'Analysis' filesep 'MotionComp' filesep 'MI' filesep 'MI' filesep 'Joint_Histogram' filesep 'spm_hist2_weighted_MI'];
    ['mrLoadRet' filesep 'Analysis' filesep 'MotionComp' filesep 'MI' filesep 'MI' filesep 'Joint_Histogram' filesep 'spm_hist2_weighted'];
    ['mrDiffusion' filesep 'src' filesep 'ndfun'];
    };

for CfileI =1:size(functionsToCompile, 1)
    cext='.c';
    CfileName=functionsToCompile{CfileI};
    [srcDir, f] = fileparts(which(CfileName));
    if(~exist(srcDir, 'dir'))
        warning(['Something went wrong! Where is ' srcDir ' directory?']); %#ok<WNTAG>
    end
    cd(srcDir);
    if(~exist([f cext], 'file'))
        cext='.cpp';
    end

    try
        disp(['Compiling ' f '...']);
        cmd = ['mex -O ' f cext];
        if(ispc)
            compileWithLapackLibToWinCommmand(cmd);
        else
            eval([cmd ' -lmwlapack -lmwblas']);
        end
        mexFiles{end+1} = [f '.' mexext];

    catch
        warning('Something went wrong! Check mex messages above.'); %#ok<WNTAG>
    end

end

fprintf('%d files compiled successfully.\n', length(mexFiles));

if(~isempty(mexFiles))
    fprintf('\n\n');
    fprintf('The following files were compiled and placed into the directories where respective source files were located%s:\n\n');
    for ii=1:length(mexFiles); fprintf('  %s\n', mexFiles{ii}); end
    %fprintf('\n\nYou probably want to move them to the usual place for mex files\n');
    %fprintf('(maybe %s ?)\n\n', fullfile(fileparts(srcDir),'DLLXX'));
end
cd(oldDir);

return;

function compileWithLapackLibToWinCommmand(cmd)

if exist(fullfile(matlabroot, 'extern', 'lib', 'win32', 'microsoft', 'libmwlapack.lib'),'file')
    libFile = fullfile(matlabroot, 'extern', 'lib', 'win32', 'microsoft', 'libmwlapack.lib');
elseif exist(fullfile(matlabroot, 'extern', 'lib', 'win32', 'microsoft', 'msvc60', 'libmwlapack.lib'),'file')
    libFile = fullfile(matlabroot, 'extern', 'lib', 'win32', 'microsoft', 'msvc60', 'libmwlapack.lib');
elseif exist(fullfile(matlabroot, 'extern', 'lib', 'win64', 'microsoft', 'libmwlapack.lib'),'file')
    libFile = fullfile(matlabroot, 'extern', 'lib', 'win64', 'microsoft', 'libmwlapack.lib');
else
    error('Cannot find libmwlapack.lib in standarad matlab directories!');
end

if isempty(find(matlabroot) == ' ')
    cmd = [cmd ' ' libFile];
    eval(cmd);
else
    copyfile(libFile);
    cmd = [cmd ' libmwlapack.lib'];
    eval(cmd);
    delete('libmwlapack.lib');
end

return;

% /home/bob/svn/vistasoft/trunk/fileFilters/nifti/niftiRead.mexa64
% /home/bob/svn/vistasoft/trunk/fileFilters/nifti/matToQuat.mexa64
% /home/bob/svn/vistasoft/trunk/fileFilters/nifti/writeFileNifti.mexa64
% /home/bob/svn/vistasoft/trunk/mrAlign/regInplanes.mexa64
% /home/bob/svn/vistasoft/trunk/mrAlign/regHistogram.mexa64
% /home/bob/svn/vistasoft/trunk/mrAnatomy/MrGray/GrowGrayMatter/grow_gray.mexa64
%
% /home/bob/svn/vistasoft/trunk/mrAnatomy/mrMesh/curvature.mexa64
% /home/bob/svn/vistasoft/trunk/mrAnatomy/mrMesh/tcpToolbox/pnet.mexa64
% /home/bob/svn/vistasoft/trunk/mrAnatomy/mrMesh/smooth_mesh.mexa64
% /home/bob/svn/vistasoft/trunk/mrAnatomy/mrMesh/build_mesh.mexa64
%
% /home/bob/svn/vistasoft/trunk/mrAnatomy/VolumeUtilities/nearpoints.mexa64
% /home/bob/svn/vistasoft/trunk/mrAnatomy/VolumeUtilities/mrAnatFastInterp3.mexa64
% /home/bob/svn/vistasoft/trunk/mrAnatomy/VolumeUtilities/myCinterp3.mexa64
% /home/bob/svn/vistasoft/trunk/mrAnatomy/ManifoldUtilities/mrManDist.mexa64
% /home/bob/svn/vistasoft/trunk/mrAnatomy/ManifoldUtilities/Csource/dijkstra2.mexa64
% /home/bob/svn/vistasoft/trunk/mrAnatomy/ManifoldUtilities/ShortestPaths/dijkstra.mexa64
%X /home/bob/svn/vistasoft/trunk/mrDiffusion/src/dtiFitTensor.mexa64
%X /home/bob/svn/vistasoft/trunk/mrDiffusion/src/dtiSplitTensor.mexa64
%X /home/bob/svn/vistasoft/trunk/mrDiffusion/src/dtiFiberTracker.mexa64
%X/home/bob/svn/vistasoft/trunk/mrDiffusion/src/ndfun.mexa64
% X/home/bob/svn/vistasoft/trunk/mrDiffusion/src/magicwand1.mexa64
% X/home/bob/svn/vistasoft/trunk/mrDiffusion/src/dtiJointHist.mexa64
% /home/bob/svn/vistasoft/trunk/mrDiffusion/xform/fastDeformation/trilin.mexa64
% /home/bob/svn/vistasoft/trunk/mrDiffusion/xform/fastDeformation/initInvDiagsInC.mexa64
% /home/bob/svn/vistasoft/trunk/mrLoadRet/Analysis/SignalProc/sumOfNeighbors.mexa64
% /home/bob/svn/vistasoft/trunk/mrLoadRet/Analysis/MotionComp/MI/MI/Joint_Histogram/spm_hist2_weighted_MI.mexa64
% /home/bob/svn/vistasoft/trunk/mrLoadRet/Analysis/MotionComp/MI/MI/Joint_Histogram/spm_hist2_weighted.mexa64


function canlab_glm_publish(varargin)
% :Usage:
% ::
%
%     canlab_glm_publish(directory_specifications [options])
%
% :Directory Specification:
%
%   **'s', dirs:**
%        Generates HTML reports of the output from scn_spm_design_check for
%        directories in cell array dires (string allowable for single dir).
%        If a directory is a subject level analysis, the HTML will be generated
%        for that subject in the analysis directory.
%        Ex:
%        ::
%
%        canlab_glm_publish('s',{'model1/1011' 'model1/1014'})
%
%        If a directory contains subject level analyses, an HTML will be
%        generated with output for each subject level analysis.
%        Ex:
%        ::
%
%        canlab_glm_publish('s','model1')
%
%        ASSUMPTION: lower level analyses contain an SPM.mat file.
%
%
%   **'g', dirs:**
%        For each "robfit directory" in cell array dirs, will run robust_results_batch
%        on all contrast directories (e.g., robust0001/) (string allowable for single dir).
%        ("robfit directories" contain robfit contrast directories (like robust0001))
%        EITHER directories contain EXPT.mat files (see help robfit)
%        OR an EXPT struct is loaded in the workspace and a single directory is specified
%        OR will do best to figure out info normally contained in EXPT.mat
%        Ex:
%        ::
%
%        canlab_glm_publish('g', {'group_n35' 'group_anxiety_n35' 'group_sadness_n35'})
%
% :Note: directory paths may be absolute or relative (to working directory)
%
%
% :Options:
%
%   **'t', {[pthresh clustersize] ...}:**
%        Use the paired voxelwise_pthresh and minimum_cluster_size thresholds
%        with which to produce robfit results maps.
%        This option must follow immediately after a 'g' option (see above) and
%        will only apply to the analyses specified in that option.
%        ONLY applies to robfit directories (no bearing on lower level design checks)
%
%        DEFAULT: {[.001 5] [.005 1] [.05 1]}
%        Ex:
%        ::
%
%        canlab_glm_publish('g', pwd, 't', {[.001 1] [.005 10] [.05 10] [.01 25]})
%
%
%   **'email', address:**
%        send notification email to address when done running
%        Ex:
%        ::
%
%        canlab_glm_publish('g', pwd, 'email', 'ruzic@colorado.edu')
%

thresh = [.001 .005 .05];
size = [5 1 1];

%% setup
STARTINGDIR = pwd;

%% parse arguments

i=1;
while i<=numel(varargin)
    if ischar(varargin{i})
        switch varargin{i}
            case {'s' 'l'}
                i=i+1;
                if isstr(varargin{i})
                    varargin{i} = {varargin{i}};
                elseif ~iscellstr(varargin{i})
                    error('[Argument to ''s'' must a be string or cell array.]')
                end
                spmlower_report(STARTINGDIR,varargin{i});

            case {'g' 'r'}
                i=i+1;
                if isstr(varargin{i})
                    varargin{i} = {varargin{i}};
                elseif ~iscellstr(varargin{i})
                    error('[Argument to ''g'' must a be string or cell array.]')
                end
                robfitdirs = varargin{i};

                if i < nargin && strcmp(varargin{i+1},'t')
                    i=i+2;
                    t = cell2mat(varargin{i});
                    thresh = t(1:2:end);
                    size = t(2:2:end);
                end

                robfit_report(STARTINGDIR,robfitdirs,thresh,size);

            case {'email'}
                i=i+1;
                address = varargin{i};

            otherwise
                error(['Unrecognized argument: ' varargin{i}])

        end
    else
        error(['Unrecognized argument: ' varargin{i}])
    end
    i=i+1;
end

%% clean up
cd(STARTINGDIR)

%% email notification
if exist('address','var')
    try
        [ignore output] = system(sprintf('printf "canlab_glm_publish has finished running.\n" | mail -v -s "canlab_glm_publish done" %s',address)); %#ok
    catch  %#ok
        fprintf('The notification email failed to send.\n');
    end
end

end

function spmlower_report(STARTINGDIR,analysisdirs)

for i = 1:numel(analysisdirs)
    if regexp(analysisdirs{i},'^/')
        targdir = analysisdirs{i};
    else
        targdir = fullfile(STARTINGDIR, analysisdirs{i});
    end

    if ~exist(targdir,'dir')
        warning('No such directory: %s', targdir)
        continue
    end

    cd(targdir);

    outputdir = fullfile(targdir, 'design_review_html');
    mkdir(outputdir)

    p = struct('useNewFigure', false, 'maxHeight', 1500, 'maxWidth', 1200, ...
        'outputDir', outputdir, 'showCode', false);

    fout = publish('canlab_glm_publish_subject_levels.m', p);
    fprintf('Created subject level design review:\n\t%s\n', fout);
end

end

%% robfit group analyses (robust_results_batch)
function robfit_report(STARTINGDIR,robfitdirs,thresh,size)

assignin('base','thresh',thresh)
assignin('base','size',size)

for i = 1:numel(robfitdirs)
    if regexp(robfitdirs{i},'^/')
        targdir = robfitdirs{i};
    else
        targdir = fullfile(STARTINGDIR, robfitdirs{i});
    end

    if ~exist(targdir,'dir')
        fprintf('*** WARNING: skipping robfit directory (not found): %s\n', targdir)
        continue
    end

    cd(targdir);
    canlab_glm_publish_group_levels
end

end


function varargout = DefaultArgs_ss(Args, DefArgs)
% auxillary function to replace argument check in the beginning and def. args assigment
% sets the absent or empty values of the Args (cell array, usually varargin)
% to their default values from the cell array DefArgs.
% Output should contain the actuall names of arguments that you use in the function

% e.g. : in function MyFunction(somearguments , varargin)
% calling [SampleRate, BinSize] = DefaultArgs(varargin, {20000, 20});
% will assign the defualt values to SampleRate and BinSize arguments if they
% are empty or absent in the varargin cell list
% (not passed to a function or passed empty)
if isempty(Args)
    Args ={[]};
end

% if iscell(Args) & isstr(Args{1}) & length(Args)==1
%     Args = Args{1};
% end

if ~iscell(DefArgs)
    DefArgs = {DefArgs};
end
nDefArgs = length(DefArgs);
nInArgs = length(Args);
%out = cell(nDefArgs,1);
if (nargout~=nDefArgs)
    error('number of defaults is different from assigned');
    %keyboard
end
for i=1:nDefArgs

    if (i>nInArgs | isempty(Args{i}))
        varargout(i) = {DefArgs{i}};
    else
        varargout(i) = {Args{i}};
    end
end


 function varargout = subsref_mm(ob, args)
%function varargout = subsref_mm(ob, args)
% handle subscript references like ob.ref or ob.ref(arg[s])
% Copyright 2006-1-19, Jeff Fessler, University of Michigan
% 2011-10-25 modified by Madison McGaffin to support multiple outputs

st = struct(ob);
varargout = cell(nargout,1);

if args(1).type ~= '.'
	error 'only ob.data and ob.meth(args) done'
end

%
% ob.name
%
name = args(1).subs;
if isfield(st, name)
	if length(args) == 1
%		out = st.(name);
		varargout = wrap_vararg(nargout, 'st.(name)', st, ob, args);
	else
%		out = subsref(st.(name), args(2:end));
		varargout = wrap_vararg(nargout, ...
			'subsref(st.(args(1).subs), args(2:end));', ...
			st, ob, args );
	end

%
% ob.name, where name is in data field
%
elseif isfield(st.data, name)
%	out = st.data.(name);
	varargout = wrap_vararg(nargout, 'st.data.(args(1).subs);', st, ob, args);

	if length(args) > 1

		% ob.name{:} does not work properly because there seems
		% to be no way to return an arbitrary number of arguments
		% (in a list) to the caller.  this is unfortunate because
		% a.b = {1,2} and a.b{:} works for ordinary structures.
% todo: see this solution involving numel()
% http://www.mathworks.com/support/solutions/data/1-1ABOD.html?solution=1-1ABOD
% n.b., link broken; will need to rewrite this for multiple return arguments.

%		if iscell(out) && ...
		if length(varargout) > 0 && iscell(varargout{1}) && ...
		(isequal(args(2).subs, {':'}) || length(args(2).subs{1}) > 1)
			warn 'instead of strum.data{:} etc., use two steps:'
			warn 'tmp = strum.data; tmp{:} or tmp{1:end} etc.'
			fail 'strum.data{:} etc. unsupported thanks to matlab'
		end

		% fix: strum1.strum2.plot() does not work here
%		out = subsref(out, args(2:end));
		varargout = {subsref(varargout{1}, args(2:end))};
	end

%
% ob.name or ob.name(arg[s]), where name is in meth field
%
elseif isfield(st.meth, name)
	fun = st.meth.(name); % function handle for method
	if length(args) == 1
%		if isfreemat || nargout(fun) % freemat: does not like nargout()
		if isfreemat || nargout % freemat: does not like nargout()
%			out = fun(ob);
			varargout = wrap_vararg(nargout, 'fun(ob);', st, ob, ...
				args, fun);
		else
			fun(ob);
		end
	elseif length(args) == 2
%		if isfreemat || nargout(fun) % freemat: does not like nargout()
		if isfreemat || nargout % freemat: does not like nargout()
%			out = fun(ob, args(2).subs{:});
			varargout = wrap_vararg(nargout, 'fun(ob, args(2).subs{:});', ...
					st, ob, args, fun );
		else
			fun(ob, args(2).subs{:});
		end
	else
		printm('unknown subs')
		keyboard
	end

else
	disp(st)
	fail(['unknown field name: ' name])
end

end % subsref

% wrap_vararg()
% return cell array with each output
function out = wrap_vararg(nout, script, st, ob, args, fun)

switch nout
case 0
	eval(script);
	out = {};
case 1
	v = eval(script);
	out = {v};
case 2
	[v1, v2] = eval(script);
	out = {v1, v2};

otherwise % general case using eval
	head = sprintf('v%d, ', 1:(nout-1));
	full = sprintf('[ %s vlast ] = %s', head, script);
	out = cell(nout,1);
	for i=1:(nout-1)
		out{i} = eval(sprintf('v%d', i));
	end
	out{end} = vlast;
end

end % wrap_vararg


function out = spm_run_realignunwarp(job)
% SPM job execution function
% takes a harvested job data structure and call SPM functions to perform
% computations on the data.
% Input:
% job    - harvested job data structure (see matlabbatch help)
% Output:
% out    - computation results, usually a struct variable.
%__________________________________________________________________________
% Copyright (C) 2005-2013 Wellcome Trust Centre for Neuroimaging

% Darren R. Gitelman
% $Id: spm_run_realignunwarp.m 6554 2015-09-11 17:21:23Z guillaume $

%-Assemble flags
%--------------------------------------------------------------------------
flags.quality = job.eoptions.quality;
flags.fwhm    = job.eoptions.fwhm;
flags.sep     = job.eoptions.sep;
flags.rtm     = job.eoptions.rtm;
flags.PW      = char(job.eoptions.weight);
flags.interp  = job.eoptions.einterp;
flags.wrap    = job.eoptions.ewrap;

uweflags.order     = job.uweoptions.basfcn;
uweflags.regorder  = job.uweoptions.regorder;
uweflags.lambda    = job.uweoptions.lambda;
uweflags.jm        = job.uweoptions.jm;
uweflags.fot       = job.uweoptions.fot;

if ~isempty(job.uweoptions.sot)
    cnt = 1;
    for i=1:size(job.uweoptions.sot,2)
        for j=i:size(job.uweoptions.sot,2)
            sotmat(cnt,1) = job.uweoptions.sot(i);
            sotmat(cnt,2) = job.uweoptions.sot(j);
            cnt = cnt+1;
        end
    end
else
    sotmat = [];
end
uweflags.sot       = sotmat;
uweflags.fwhm      = job.uweoptions.uwfwhm;
uweflags.rem       = job.uweoptions.rem;
uweflags.noi       = job.uweoptions.noi;
uweflags.exp_round = job.uweoptions.expround;

uwrflags.interp    = job.uwroptions.rinterp;
uwrflags.wrap      = job.uwroptions.wrap;
uwrflags.mask      = job.uwroptions.mask;
uwrflags.which     = job.uwroptions.uwwhich(1);
uwrflags.mean      = job.uwroptions.uwwhich(2);
uwrflags.prefix    = job.uwroptions.prefix;

if uweflags.jm == 1
    uwrflags.udc = 2;
else
    uwrflags.udc = 1;
end

%-Assemble files
%--------------------------------------------------------------------------
P   = cell(size(job.data));
sfP = cell(size(job.data));
for i = 1:numel(job.data)
    P{i} = char(job.data(i).scans{:});
    if ~isempty(job.data(i).pmscan)
        sfP{i} = job.data(i).pmscan{1};
    else
        sfP{i} = [];
    end
end

%-Realign
%--------------------------------------------------------------------------
spm_realign(P,flags);

%-Unwarp Estimate
%--------------------------------------------------------------------------
for i = 1:numel(P)
    uweflags.sfP = sfP{i};
    P1 = deblank(P{i}(1,:));
    if isempty(spm_file(P1,'number'))
        P1 = spm_file(P1,'number',1);
    end
    VP1 = spm_vol(P1);
    uweflags.M = VP1.mat;
    ds = spm_uw_estimate(P{i},uweflags);
    sess(i).ds = ds;
    dsfile = spm_file(P{i}(1,:), 'suffix','_uw', 'ext','.mat');
    save(dsfile,'ds', spm_get_defaults('mat.format'));
end

%-Unwarp Write - Sessions should be within subjects
%--------------------------------------------------------------------------
spm_uw_apply(cat(2,sess.ds),uwrflags);

%-Dependencies
%--------------------------------------------------------------------------
for i=1:numel(P)
    out.sess(i).rpfile{1} = spm_file(P{i}(1,:), 'prefix','rp_', 'ext','.txt');
    out.sess(i).dsfile{1} = spm_file(P{i}(1,:), 'suffix','_uw', 'ext','.mat');
end

switch job.uwroptions.uwwhich(1)
    case 0
        out.sess.uwrfiles  = {};
    case 2
        for i=1:numel(P)
            out.sess(i).uwrfiles = spm_file(cellstr(P{i}), ...
                'prefix',job.uwroptions.prefix);
        end
end
if job.uwroptions.uwwhich(2)
    out.meanuwr{1} = spm_file(P{1}(1,:), ...
        'prefix',['mean' job.uwroptions.prefix], ...
        'number','');
end


function [ filenames ] = palsar2_files( filename, check_nonstandard_filenames )
%PALSAR2_FILES Given one file in an ALOS PALSAR 2 data bundle of files, find the rest
%
% Written by: Wade Schwartzkopf, NGA/R
%
% //////////////////////////////////////////
% /// CLASSIFICATION: UNCLASSIFIED       ///
% //////////////////////////////////////////

if ~exist('check_nonstandard_filenames','var')
    % Should we look at other files in the directory by content, rather
    % than filename?
    check_nonstandard_filenames = false;
end

% A standard ALOS PALSAR 2 distribution will have several files all in the
% same directory.

FILETYPE_PREFIX = {'VOL-', 'LED-', 'IMG-[H|V]{2}-', 'TRL-'};
FILETYPE = cellfun(@(x) x(1:3), FILETYPE_PREFIX, 'UniformOutput', false);
RECTYPES.VOL = [1, 192, 192, 18, 18, 360];
RECTYPES.LED = [1, 11, 192, 18, 18, 720];
RECTYPES.IMG = [1, 50, 192, 18, 18, 720];
RECTYPES.TRL = [1, 63, 192, 18, 18, 720];

[pathstr, fnameonly, ext] = fileparts(filename);
fnameonly = [fnameonly ext];
dir_info = dir(pathstr);
for i = 1:numel(FILETYPE)
    filenames.(FILETYPE{i}) = {}; % Might be multiple
    % First check filename to see if its as expected.
    expected_filename = regexprep(fnameonly, ['^' strjoin(FILETYPE_PREFIX,'|')], FILETYPE_PREFIX(i));
    dir_info_type = dir_info(~cellfun(@isempty, regexp({dir_info.name}, expected_filename, 'once')));
    for j = 1:numel(dir_info_type)
        if check_filetype(fullfile(pathstr, dir_info_type(j).name), FILETYPE{i})
            filenames.(FILETYPE{i}){end+1} = fullfile(pathstr, dir_info_type(j).name);
        end
    end
    if check_nonstandard_filenames && isempty(filenames.(FILETYPE{i}))
        % If no expected filenames, check all files in current directory
        % for matching file type.
        % Warning: Could break if multiple datasets in the same
        % directory since we can't tell whether files are from same
        % dataset or not.  We assume files are either named
        % appropriately or grouped in directories appropriately, but
        % not necessarily both.
        for j = 1:numel(dir_info)
            if ~dir_info(j).isdir && ...
                    check_filetype(fullfile(pathstr, dir_info(j).name), FILETYPE{i})
                filenames.(FILETYPE{i}){end+1} = fullfile(pathstr, dir_info(j).name);
            end
        end
    end
    % Cleanup
    if isempty(filenames.(FILETYPE{i}))
        filenames = rmfield(filenames, FILETYPE{i});
    elseif ~strcmp(FILETYPE{i},'IMG') % No cell arrays needed for non-IMG types
        filenames.(FILETYPE{i}) = filenames.(FILETYPE{i}){1};
    end
end

    function [ bool ] = check_filetype( filename, type )
        % Read volume descriptor records
        fid=fopen(filename,'r','b');
        cur_types = [fread(fid,1,'uint32') ... % Record sequence number
            fread(fid,1,'uint8') ... % Record subtype code
            fread(fid,1,'uint8') ... % Record type
            fread(fid,1,'uint8') ... % Record subtype code
            fread(fid,1,'uint8') ... % Record subtype code
            fread(fid,1,'uint32')]; % Record length
        fclose(fid);

        bool = isequal(cur_types, RECTYPES.(type));
    end

end

% //////////////////////////////////////////
% /// CLASSIFICATION: UNCLASSIFIED       ///
% //////////////////////////////////////////


function t = subsasgn(t,s,b)
%SUBSASGN Subscripted assignment for tenmat.
%
%   Examples
%   X = tenmat(rand(3,4,2),1);
%   X(1:2,1:2) = ones(2,2); <-- Calls SUBSASGN
%
%   See also TENMAT, TENMAT/SUBSREF.
%
%MATLAB Tensor Toolbox.
%Copyright 2015, Sandia Corporation.

% This is the MATLAB Tensor Toolbox by T. Kolda, B. Bader, and others.
% http://www.sandia.gov/~tgkolda/TensorToolbox.
% Copyright (2015) Sandia Corporation. Under the terms of Contract
% DE-AC04-94AL85000, there is a non-exclusive license for use of this
% work by or on behalf of the U.S. Government. Export of this data may
% require a license from the United States Government.
% The full license terms can be found in the file LICENSE.txt

switch s.type
    case '()'
        [m n] = size(t.data);
	t.data(s.subs{:}) = b;
        if ~isequal([m n],size(t.data))
            error('Ambiguous change in size')
        end
    otherwise
        error('Invalid assignment for tenmat.')
end


function varargout = calculator(varargin)
% CALCULATOR M-file for calculator.fig
%      CALCULATOR, by itself, creates a new CALCULATOR or raises the existing
%      singleton*.
%
%      H = CALCULATOR returns the handle to a new CALCULATOR or the handle to
%      the existing singleton*.
%
%      CALCULATOR('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in CALCULATOR.M with the given input arguments.
%
%      CALCULATOR('Property','Value',...) creates a new CALCULATOR or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before calculator_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to calculator_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help calculator

% Last Modified by GUIDE v2.5 18-Feb-2011 17:46:26

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @calculator_OpeningFcn, ...
                   'gui_OutputFcn',  @calculator_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT

% --- Executes just before calculator is made visible.
function calculator_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to calculator (see VARARGIN)

% Choose default command line output for calculator
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

date1 = date;
set(handles.date1, 'String', date);
initialize_gui(hObject, handles, false);

% UIWAIT makes calculator wait for user response (see UIRESUME)
% uiwait(handles.figure1);

% --- Outputs from this function are returned to the command line.
function varargout = calculator_OutputFcn(hObject, eventdata, handles)
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;

% --- Executes during object creation, after setting all properties.
function numbera_CreateFcn(hObject, eventdata, handles)
% hObject    handle to numbera (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function numbera_Callback(hObject, eventdata, handles)
% hObject    handle to numbera (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of numbera as text
%        str2double(get(hObject,'String')) returns contents of numbera as a double

numbera = str2double(get(hObject, 'String'));
if isnan(numbera)
    set(hObject, 'String', 0);
    errordlg('Input must be a number','Error');
end

% Save the new density value
handles.metricdata.numbera = numbera;
guidata(hObject,handles)

% --- Executes during object creation, after setting all properties.
function numberb_CreateFcn(hObject, eventdata, handles)
% hObject    handle to numberb (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function numberb_Callback(hObject, eventdata, handles)
% hObject    handle to numberb (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of numberb as text
%        str2double(get(hObject,'String')) returns contents of numberb as a double

numberb = str2double(get(hObject, 'String'));
if isnan(numberb)
    set(hObject, 'String', 0);
    errordlg('Input must be a number','Error');
end

% Save the new density value
handles.metricdata.numberb = numberb;
guidata(hObject,handles)

% --- Executes on button press in add.
function add_Callback(hObject, eventdata, handles)
% hObject    handle to add (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

result = handles.metricdata.numbera + handles.metricdata.numberb;
set(handles.result, 'String', result)

% --- Executes on button press in substract.
function substract_Callback(hObject, eventdata, handles)
% hObject    handle to substract (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

result = handles.metricdata.numbera - handles.metricdata.numberb;
set(handles.result, 'String', result)

% --- Executes on button press in divide.
function divide_Callback(hObject, eventdata, handles)
% hObject    handle to divide (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

result = handles.metricdata.numbera / handles.metricdata.numberb;
set(handles.result, 'String', result)

% --- Executes on button press in multiply.
function multiply_Callback(hObject, eventdata, handles)
% hObject    handle to multiply (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

result = handles.metricdata.numbera * handles.metricdata.numberb;
set(handles.result, 'String', result)

% --- Executes on button press in natlog.
function natlog_Callback(hObject, eventdata, handles)
% hObject    handle to natlog (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

result = (log(handles.metricdata.numbera));
set(handles.result, 'String', result)

% --- Executes on button press in inverse.
function inverse_Callback(hObject, eventdata, handles)
% hObject    handle to inverse (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

result = (1 / handles.metricdata.numbera);
set(handles.result, 'String', result)

% --- Executes on button press in cube.
function cube_Callback(hObject, eventdata, handles)
% hObject    handle to cube (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

result = (handles.metricdata.numbera)^3;
set(handles.result, 'String', result)

% --- Executes on button press in powerb.
function powerb_Callback(hObject, eventdata, handles)
% hObject    handle to powerb (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

result = (handles.metricdata.numbera)^(handles.metricdata.numberb);
set(handles.result, 'String', result)

% --- Executes on button press in sqrt.
function sqrt_Callback(hObject, eventdata, handles)
% hObject    handle to sqrt (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

result = (sqrt(handles.metricdata.numbera));
set(handles.result, 'String', result)

% --- Executes on button press in logarithm.
function logarithm_Callback(hObject, eventdata, handles)
% hObject    handle to logarithm (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

result = log10(handles.metricdata.numbera);
set(handles.result, 'String', result)

% --- Executes on button press in broot.
function broot_Callback(hObject, eventdata, handles)
% hObject    handle to broot (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

result = (handles.metricdata.numbera)^(1 /handles.metricdata.numberb);
set(handles.result, 'String', result)

% --- Executes on button press in factorial.
function factorial_Callback(hObject, eventdata, handles)
% hObject    handle to factorial (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

N = 1;
for n = 1:1:handles.metricdata.numbera
    N = N.*n;
end
result = N;
set(handles.result, 'String', result)

% --- Executes on button press in square.
function square_Callback(hObject, eventdata, handles)
% hObject    handle to square (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

result = (handles.metricdata.numbera)^(2);
set(handles.result, 'String', result)

% --- Executes on button press in pushbutton30.
function pushbutton30_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton30 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

initialize_gui(gcbf, handles, true);

function initialize_gui(fig_handle, handles, isreset)
% If the metricdata field is present and the reset flag is false, it means
% we are we are just re-initializing a GUI by calling it from the cmd line
% while it is up. So, bail out as we dont want to reset the data.
if isfield(handles, 'metricdata') && ~isreset
    return;
end

handles.metricdata.numbera = 0;
handles.metricdata.numberb  = 0;

set(handles.numbera, 'String', handles.metricdata.numbera);
set(handles.numberb,  'String', handles.metricdata.numberb);
set(handles.result, 'String', 0);
set(handles.date1, 'String', date);

% Update handles structure
guidata(handles.figure1, handles);

function result_Callback(hObject, eventdata, handles)
% hObject    handle to result (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of result as text
%        str2double(get(hObject,'String')) returns contents of result as a double

% --- Executes during object creation, after setting all properties.
function result_CreateFcn(hObject, eventdata, handles)
% hObject    handle to result (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% this script is to provide complete reaction identifiers (#174) that will be used for Met Atlas web-portal.

% load reaction ids
rxnIDs = importTsvFile('reactions.tsv');

% replace underscore with `R`
rxnIDs.rxnMAID = strrep(rxnIDs.rxnMAID,'_','R');
indToFill = getNonEmptyList(rxnIDs.rxnMAID,false);

% prepare a list to fill
idsToAdd = cell(19999,1);
for i=1:19999
    idsToAdd{i} = strcat('MAR',sprintf('%05d', i));
end
idsToAdd = setdiff(idsToAdd, rxnIDs.rxnMAID);

% sequentially fill in blank MA ids
rxnIDs.rxnMAID(indToFill) = idsToAdd(1:length(indToFill));
if isequal(length(rxnIDs.rxnMAID), length(unique(rxnIDs.rxnMAID)))
    fprintf('the filling looks okay.\n');
end

% insert dash between MA and RDDDDD
rxnIDs.rxnMAID = strrep(rxnIDs.rxnMAID,'MA','MA-');

exportTsvFile(rxnIDs,'reactions.tsv');


function [vid_h_org, vid_l_bic] = load_video1(opt,part,param)

dirFile = opt.test_video.imgPath;
nFrames = opt.test_video.nFrame;
upscale = opt.res;

vid_h_org = [];
vid_l_bic = [];

for i = 1:nFrames
    filename = sprintf('original/Frame %03d.png', i);
    fullname = strcat(dirFile,filename);
    tmp = im2double(imread(fullname,'png'));
    [M, N] = size(tmp(:,:,1));
    switch part
        case 1 % whole frame
            vid_h_org{i} = tmp;
        case 2 % no use
            vid_h_org{i} = imresize(tmp, 1/2);
        case 3 % half x half (288x352)
            vid_h_org{i} = tmp(1:M/2,1:N/2,:);
        case 4 % quarter x quarter (144x176)
            vid_h_org{i} = tmp(1:M/4,1:N/4,:);
        case 5 % 64x64
            vid_h_org{i} = tmp(65:128,1:64,:);
        case 6 % 32x64
            vid_h_org{i} = tmp(65:96,1:64,:);
    end
    vid_l_bic{i} = imresize(vid_h_org{i}, 1/upscale);
end

if param.SHOW_IMAGE
    figure(1), imshow(vid_h_org{1}); title('original (frame1)');
end


function opt = mpoption_info_knitro(selector)
%MPOPTION_INFO_KNITRO  Returns MATPOWER option info for Artelys Knitro.
%
%   DEFAULT_OPTS = MPOPTION_INFO_KNITRO('D')
%   VALID_OPTS   = MPOPTION_INFO_KNITRO('V')
%   EXCEPTIONS   = MPOPTION_INFO_KNITRO('E')
%
%   Returns a structure for Knitro options for MATPOWER containing ...
%   (1) default options,
%   (2) valid options, or
%   (3) NESTED_STRUCT_COPY exceptions for setting options
%   ... depending on the value of the input argument.
%
%   This function is used by MPOPTION to set default options, check validity
%   of option names or modify option setting/copying behavior for this
%   subset of optional MATPOWER options.
%
%   See also MPOPTION.

%   MATPOWER
%   Copyright (c) 2014-2016, Power Systems Engineering Research Center (PSERC)
%   by Ray Zimmerman, PSERC Cornell
%
%   This file is part of MATPOWER.
%   Covered by the 3-clause BSD License (see LICENSE file for details).
%   See https://matpower.org for more info.

if nargin < 1
    selector = 'D';
end
if have_feature('knitro')
    switch upper(selector)
        case {'D', 'V'}     %% default and valid options
            opt = struct(...
                'knitro',       struct(...
                    'tol_x',        1e-4, ...
                    'tol_f',        1e-4, ...
                    'maxit',        0, ...
                    'opts',         [], ...
                    'opt_fname',    '', ...
                    'opt',          0 ...
                ) ...
            );
        case 'E'            %% exceptions used by nested_struct_copy() for applying
            opt = struct(...
                'name',         { 'knitro.opts' }, ...
                'check',        0, ...
                'copy_mode',    { '' } ...
                );
        otherwise
            error('mpoption_info_knitro: ''%s'' is not a valid input argument', selector);
    end
else
    opt = struct([]);       %% Artelys Knitro is not available
end


function f = vl_ertr(f) ;
% VL_ERTR  Transpose exremal regions frames
%  F = VL_ERTR(F) transposes the frames F as returned by VL_MSER(). This
%  conversion is required as the VL_MSER algorithm considers the column
%  index I as the frist image index, while according standard image
%  convention the first coordinate is the abscissa X.
%
%  See also: VL_MSER(), VL_HELP().

if size(f,1) ~= 5
  error('F is not in the right format') ;
end

% adjust convention
f = f([2 1 5 4 3],:) ;


function objPC = loadPC(objICP, i)
% LOADPC Load point cloud to workspace.
% ------------------------------------------------------------------------------
% DESCRIPTION/NOTES
% With this method a point cloud which was previously added to the globalICP
% object, can be loaded to the workspace.
% ------------------------------------------------------------------------------
% INPUT
% [i]
% Index of point cloud to load.
% ------------------------------------------------------------------------------
% EXAMPLES
% Call 'help globalICP.globalICP' for a minimal working example, which also
% includes this method.
% ------------------------------------------------------------------------------
% philipp.glira@gmail.com
% ------------------------------------------------------------------------------

objPC = pointCloud(objICP.PC{i});

end