function SQL_Store(writeWhat,dbname)
% SQL_Store 	Upload data to the mySQL database.
%
% Uploads data in the HCTSA.mat file in the current directory back into the
% mySQL database. Should be done to store the result new computations done by
% TS_Compute.

% ------------------------------------------------------------------------------
% Copyright (C) 2020, Ben D. Fulcher <ben.d.fulcher@gmail.com>,
% <http://www.benfulcher.com>
%
% If you use this code for your research, please cite the following two papers:
%
% (1) B.D. Fulcher and N.S. Jones, "hctsa: A Computational Framework for Automated
% Time-Series Phenotyping Using Massive Feature Extraction, Cell Systems 5: 527 (2017).
% DOI: 10.1016/j.cels.2017.10.001
%
% (2) B.D. Fulcher, M.A. Little, N.S. Jones, "Highly comparative time-series
% analysis: the empirical structure of time series and their methods",
% J. Roy. Soc. Interface 10(83) 20130048 (2013).
% DOI: 10.1098/rsif.2013.0048
%
% This work is licensed under the Creative Commons
% Attribution-NonCommercial-ShareAlike 4.0 International License. To view a copy of
% this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ or send
% a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View,
% California, 94041, USA.
% ------------------------------------------------------------------------------

% ------------------------------------------------------------------------------
%% Check Inputs
% ------------------------------------------------------------------------------
if nargin < 1
	writeWhat = 'null'; % 'nullerror'
    % find all nulls in the database and write over them if there are values in local files
end
if ~ismember(writeWhat,{'null','error','nullerror'})
    error('Unknown specifier ''%s''',writeWhat)
end
if nargin < 3
	dbname = '';
end

% ------------------------------------------------------------------------------
%% Open a mySQL database connection
% ------------------------------------------------------------------------------
% Much faster to use java connector than the Matlab database toolbox
% (exec commands are slow; update commands are even slower)
[dbc, dbname] = SQL_OpenDatabase(dbname,0,0);

% ------------------------------------------------------------------------------
%% Load local files
% ------------------------------------------------------------------------------
%% Read in information from local files
fid = 1; % haha no more logging option...
loadTimer = tic;
fprintf(fid,'Loading data from HCTSA.mat...');
load('HCTSA.mat')
fprintf(fid,' Done in %s.\n',BF_TheTime(toc(loadTimer)));
clear loadTimer

% ------------------------------------------------------------------------------
% Check that this file was actually retrieved from the database (such that these
% ts_ids and op_ids represent items stored in the linked mySQL database)
% ------------------------------------------------------------------------------
if ~fromDatabase
    theLoc = which('HCTSA.mat');
    error(['It looks like:\n%s\nwas generated using TS_init and does not match up ' ...
            'with ID entries a mySQL database...'],theLoc);
end

% ------------------------------------------------------------------------------
% Check that TS_CalcTime exists
% ------------------------------------------------------------------------------
% It will not exist if you've (by default) not retrieved calculation time data
% from the database, and not generated it from the computation
if ~exist('TS_CalcTime','var')
    error('No calculation time data found in HCTSA.mat');
end

% ------------------------------------------------------------------------------
%% Preliminary definitions
% ------------------------------------------------------------------------------
numTS = height(TimeSeries); % Number of time series
numOps = height(Operations); % Number of operations
ts_id_loc = TimeSeries.ID; % tsids in local file
op_id_loc = Operations.ID; % opids in local file
ts_ids_string = BF_cat(ts_id_loc,',');
op_ids_string = BF_cat(op_id_loc,',');

% ------------------------------------------------------------------------------
%% Check that nothing has been deleted since the data was loaded...
% ------------------------------------------------------------------------------
% Time series
SelectString = sprintf('SELECT COUNT(ts_id) FROM TimeSeries WHERE ts_id IN (%s)',ts_ids_string);
numTS_db = mysql_dbquery(dbc,SelectString);
numTS_db = numTS_db{1};

% Operations
SelectString = sprintf('SELECT COUNT(op_id) FROM Operations WHERE op_id IN (%s)',op_ids_string);
numOps_db = mysql_dbquery(dbc,SelectString);
numOps_db = numOps_db{1};

if (numOps == numOps_db) && (numTS == numTS_db)
    fprintf(1,'All local time series and operation ids still exist in %s. This is good.\n',dbname);
else
    if numTS_db < numTS
        fprintf(1,'There are %u time series that no longer match the database',(numTS-numTS_db));
    end

    if numOps_db < numOps
    	fprintf(1,'There are %u operations that no longer match the database',(numOps-numOps_db));
    end
    error(['It could be dangerous to write back to a changed database. ' ...
                'You should start a SQL_Retrieve from scratch.'])
end

% ------------------------------------------------------------------------------
%% Find the elements that are empty in the database
%       (and hopefully full in the local file)
% ------------------------------------------------------------------------------
% Parts of calculated subsection that are empty in storage
fprintf(1,'Retrieving %s elements from the Results table in %s...',writeWhat,dbname);

switch writeWhat
case 'null'
    % collect nulls in the database
    SelectString = sprintf(['SELECT ts_id, op_id FROM Results WHERE ts_id IN (%s)' ...
    					' AND op_id IN (%s) AND QualityCode IS NULL'],ts_ids_string,op_ids_string);
case 'nullerror'
    % Collect all NULLS and previous errors
    SelectString = sprintf(['SELECT ts_id, op_id, QualityCode FROM Results WHERE ts_id IN (%s)' ...
    					' AND op_id IN (%s) AND (QualityCode IS NULL OR QualityCode = 1)'], ...
        					ts_ids_string,op_ids_string);
case 'error'
    % Collect all previous errors (assume done a SQL_Retrieve using 'error' input)
    SelectString = sprintf(['SELECT ts_id, op_id FROM Results WHERE ts_id IN (%s)' ...
    					' AND op_id IN (%s) AND QualityCode = 1'], ...
        					ts_ids_string,op_ids_string);
end

retrievalTimer = tic; % Time the retrieval (should be fast)
[qrc,emsg] = mysql_dbquery(dbc,SelectString);
if ~isempty(emsg)
    fprintf(1,'\n'); error('Error selecting %s elements from %s',writeWhat,dbname);
elseif isempty(qrc)
    fprintf(1,'\nNo %s elements in this range in the database anymore! Nothing to write.\n',writeWhat);
    SQL_CloseDatabase(dbc); return
else
	fprintf(1,' Retrieved %u entries in %s\n',length(qrc),BF_TheTime(toc(retrievalTimer)));
end
clear retrievalTimer % Stop timing

ts_id_db = vertcat(qrc{:,1}); % ts_ids (in op_id pairs) of empty database elements in this ts_id/op_id range
op_id_db = vertcat(qrc{:,2}); % op_ids (in ts_id pairs) of empty database elements in this ts_id/op_id range
numWrite = length(ts_id_db);  % Number of database elements to attempt to write back to

% ------------------------------------------------------------------------------
% Give user feedback about what database writing will occur
% ------------------------------------------------------------------------------
switch writeWhat
case 'null'
    fprintf(1,['There are %u NULL entries in Results.\nWriting calculated ' ...
                    'elements of TS_DataMat to %s...\n'],numWrite,dbname);
case 'error'
    fprintf(1,['There are %u entries in Results (all previous errors) ' ...
                    'that are being written to %s...\n'],numWrite,dbname);
    fprintf(1,['Previous results stored as errors in the database WILL NOT ' ...
                                    'be overwritten with newer errors\n']);
case 'nullerror'
    q_db = qrc(:,3); % empties (NULL) and fatal error (1)
    q_db(cellfun(@isempty,q_db)) = {0}; % turn NULLs to 0s
    q_db = vertcat(q_db{:}); % turn cells to a numeric vector
    % so now nulls in database are labeled 0, and previous errors are labeled 1
    fprintf(1,['There are %u entries in Results (either NULL or previous errors) ' ...
                    'that are being written to %s...\n'],numWrite,dbname);
    fprintf(1,['Note that previous results stored as errors in the database WILL NOT ' ...
                                'be overwritten with newer errors\n']);
    fprintf(1,'However, NULLS will be written over with any result from the local files\n');
end

localIndex = zeros(numWrite,2);
localIndex(:,1) = arrayfun(@(x)find(ts_id_loc == x,1),ts_id_db); % Indices of rows in local file for each entry in the database
localIndex(:,2) = arrayfun(@(x)find(op_id_loc == x,1),op_id_db); % Indicies of columns in local file for each entry in the database
updateMe = zeros(numWrite,1); % Label iterations that should be written to the database

% ------------------------------------------------------------------------------
% Begin writing each element to the database, one at a time, using UPDATE commands
% ------------------------------------------------------------------------------

writeBackTimer = tic; % Time how long this takes to give user feedback
numReports = 3; % the number of time remaining updates to provide the user

for i = 1:numWrite

    % Retrieve the elements
    TS_DataMat_ij = TS_DataMat(localIndex(i,1),localIndex(i,2));
    TS_Quality_ij = TS_Quality(localIndex(i,1),localIndex(i,2));
    TS_CalcTime_ij = TS_CalcTime(localIndex(i,1),localIndex(i,2));

    switch writeWhat
    case 'null'
        if isfinite(TS_DataMat_ij)
            updateMe(i) = 1; % There is a value in TS_DataMat -- write it back to the NULL entry in the database
        end
    case 'error'
        if isfinite(TS_DataMat_ij) && TS_Quality_ij~=1
            updateMe(i) = 1; % There is a now a non-error value in TS_DataMat previously returned an error (in the database)
        end
    case 'nullerror'
        if isfinite(TS_DataMat_ij) && (q_db(i)==0 || TS_Quality_ij~=1)
            updateMe(i) = 1; % there is a value in TS_DataMat -- write it to the entry in the database
        end
		% (i) Has been calculated and a value stored in TS_DataMat (isfinite()), and
		% (ii) Either the database entry is NULL or we didn't get an error (prevents writing errors over errors)
    end

    if updateMe(i)

        if isnan(TS_CalcTime_ij) % happens when there is an error in the code
            TS_CalcTime_string = 'NULL';
        else
            TS_CalcTime_string = sprintf('%f',TS_CalcTime_ij);
        end

        % I can't see any simple way around running lots of single UPDATE commands (for each entry)
    	updateString = sprintf(['UPDATE Results SET Output = %19.17g, QualityCode = %u, CalculationTime = %s ' ...
						'WHERE ts_id = %u AND op_id = %u'],TS_DataMat_ij,TS_Quality_ij, ...
						TS_CalcTime_string,ts_id_db(i),op_id_db(i));
        [~,emsg] = mysql_dbexecute(dbc, updateString);
        if ~isempty(emsg)
            SQL_CloseDatabase(dbc) % close the database connection before calling the error...
        	error('Error storing (ts_id,op_id) = (%u,%u) to %s??!!\n%s\n', ...
                			TimeSeries.ID(localIndex(i,1)),Operations.ID(localIndex(i,2)),dbname,emsg);
        end
    end

    % Give user feedback on how long is remaining:
    if (i==50) && (i < numWrite/numReports) % give an initial estimate:
        fprintf(1,['Based on the first 50 retrievals, this is taking ' ...
                'approximately %s per entry to write to the database.\n'],BF_TheTime(toc(writeBackTimer)));
		fprintf(1,'Approximately %s remaining...\n',BF_TheTime(toc(writeBackTimer)/i*(numWrite-i)));
    elseif mod(i,floor(numWrite/numReports))==0 % Give numReports more time updates...
		fprintf(1,['Approximately %s remaining -- %u (/ %u possible) entries have been'  ...
			' written to %s...\n'],BF_TheTime(toc(writeBackTimer)/i*(numWrite-i)),sum(updateMe),i,dbname);
	end
end

% ------------------------------------------------------------------------------
% Finished writing back to the database!
% ------------------------------------------------------------------------------

fprintf(1,['Successfully wrote %u new calculation results ' ...
            '(/ %u) to the Results table of %s in %s.\n'],...
            sum(updateMe),numWrite,dbname,BF_TheTime(toc(writeBackTimer)));

if any(~updateMe) % Some entries were not written to the database
    fprintf(1,['%u entries were not written (previously-calculated errors) and remain ' ...
                            'awaiting calculation in the database.\n'],sum(~updateMe));
end

SQL_CloseDatabase(dbc) % Close the database connection

end


function [] = aps_gacos_files(orderflag_GACOS_website)
% script that runs and checks which GACOS data files are needed based on
% the satellite pass time.
% INPUTS:
%
%
%     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.,
%     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%
% By David Bekaert - November 2017
% Modifications:

stdargin = nargin ;
if stdargin<1
    orderflag_GACOS_website = 0;
end

% getting the variables from the parms_aps file
workdir = pwd;
stamps_processed = getparm_aps('stamps_processed');
UTC_sat =  getparm_aps('UTC_sat');
gacos_datapath = getparm_aps('gacos_datapath');
datestructure = 'yyyymmdd';                               % assumed date structure for era
if isempty(gacos_datapath)
    error('please specify gacos_datapath')
end

% loading the data
if strcmp(stamps_processed,'y')
    ll_matfile = getparm_aps('ll_matfile');
    ps = load(ll_matfile);
    dates = ps.day;
else
    ifgday_matfile = getparm_aps('ifgday_matfile');
    ifgs_dates = load(ifgday_matfile);
    ifgs_dates = ifgs_dates.ifgday;
    dates = reshape(ifgs_dates,[],1);
    dates = unique(dates);
    dates = datenum(num2str(dates),'yyyymmdd');
end

% getting the dates
n_dates = length(dates);

% find two closest times with respect the 1hr spaced ERA5 data
time = str2num(UTC_sat(1:2)) + str2num(UTC_sat(4:5))/60;
fprintf(['Satellite pass is ' num2str(time) ' UTC \n'])
datelist =  datestr(dates,datestructure);
filelist = [datelist repmat('.ztd',size(datelist,1),1) ];

if orderflag_GACOS_website==0
    % outputing this information to a file
    fid = fopen('GACOS_files.txt','w');
    fprintf(['Required GACOS files for all interferograms \n'])
    for k=1:size(filelist,1)
        fprintf([filelist(k,:) '\n']);
        fprintf(fid,[filelist(k,:) '\n']);
    end
    fclose(fid);

    % getting the BBOX needed for GACO, in case user wants to download manually
    crop_range_in = 0.5; % increasing extent of weather data region by this value (degree)
    region_lat_range = getparm_aps('region_lat_range');
    region_lon_range = getparm_aps('region_lon_range');
    if isempty(region_lat_range) == 1
        error('Specify the region for the weather model data')
    end
    fprintf('increasing crop area by %s deg in each direction \n',num2str(crop_range_in))
    S = num2str(min(round(region_lat_range)) - crop_range_in);
    N = num2str(max(round(region_lat_range)) + crop_range_in);
    W = num2str(min(round(region_lon_range)) - crop_range_in);
    E = num2str(max(round(region_lon_range)) + crop_range_in);       % DB fixed typo min to max
    weatherregstr = [N,'/',W,'/',S,'/',E];   % N/W/S/E
    fprintf('weather model region N/W/S/E %s \n',weatherregstr);

    fid2 = fopen('GACOS_download_info.txt','w');
    % give the metadata needed
    fprintf(fid2,['UTC: ' UTC_sat '\n']);
    fprintf(fid2,['South: ' S '\n']);
    fprintf(fid2,['North: ' N '\n']);
    fprintf(fid2,['West: ' W '\n']);
    fprintf(fid2,['East: ' E '\n\n']);
    fprintf(fid2,['dates:\n']);
    for k=1:size(datelist,1)
        fprintf(fid2,[datelist(k,1:end) '\n']);
    end
    fclose(fid2);
end

%% Below is specific for the ECMWF data website
crop_range_in = 2; % increasing extent of weather data region by this value (degree)
overwrite_flag=-1;
if orderflag_GACOS_website==1

    error('GACOS website does not support api call')

    % weather model region
    fprintf('getting the data from the GACOS website ...')
    region_lat_range = getparm_aps('region_lat_range');
    region_lon_range = getparm_aps('region_lon_range');
    if isempty(region_lat_range) == 1
        error('Specify the region for the weather model data')
    end
    fprintf('increasing crop area by %s deg in each direction \n',num2str(crop_range_in))
    S = num2str(min(round(region_lat_range)) - crop_range_in);
    N = num2str(max(round(region_lat_range)) + crop_range_in);
    W = num2str(min(round(region_lon_range)) - crop_range_in);
    E = num2str(max(round(region_lon_range)) + crop_range_in);       % DB fixed typo min to max
    weatherregstr = [N,'/',W,'/',S,'/',E];   % N/W/S/E
    fprintf('weather model region N/W/S/E %s \n',weatherregstr);

    %%%%% CODE BELOW IS LEGACY CODE FROM ECMWF DOWNLOAD PROGRAM
    %%%%% TB CLEANED

    for l = 1:size(filelist,1)
        subdirpath = [gacos_datapath,'/',filelist(l,5:12),'/'];
        if exist(subdirpath,'dir') == 0
            fprintf('creating directory %s \n',subdirpath);
            mkdir(subdirpath)
        end
        if exist([subdirpath,'ggap', filelist(l,5:16) '.nc'],'file') == 0
            cd(subdirpath)
            fprintf('Order and downloading %s \n',filelist(l,5:16))
            aps_era5_ECMWF_Python(filelist(l,5:16),weatherregstr) %write python donwload file
            python_str = ['python ',filelist(l,5:16),'.py > ',filelist(l,5:16),'down.log &'];
            [a,b] = system(python_str); % start python script
            clear a b
            cd ..
        else
            if overwrite_flag==-1
                str='';
                while ~strcmpi(str,'y') && ~strcmpi(str,'n')
                    fprintf(['Do you want to overwrite existing files? \n'])
                    str = input('[y: for yes, n: no] \n','s');
                end
                if strcmpi(str,'n')
                    overwrite_flag=0;
                else
                    overwrite_flag=1;
                end
            end
            % check if the files need to be overwritten
            if overwrite_flag==1
                cd(subdirpath)
                delete([subdirpath,'ggap', filelist(l,5:16) '.nc'])
                fprintf('Order and downloading %s \n',filelist(l,5:16))
                aps_era5_ECMWF_Python(filelist(l,5:16),weatherregstr) %write python donwload file
                python_str = ['python ',filelist(l,5:16),'.py > ',filelist(l,5:16),'down.log &'];
                [a,b] = system(python_str); % start python script
                clear a b
                cd ..
            elseif overwrite_flag==0
                fprintf('File %s has already been downloaded \n',filelist(l,:))
            end
        end
    end
    cd(workdir)
end

% check if the files needs to be organized into a YYYYMMDD folder structure
try
    cd(gacos_datapath)
    for k=1:size(filelist,1)
       file = filelist(k,:);
        date = file(1:8);
        if exist(date,'dir')~=7
            mkdir(date)
        end
        if exist(file,'file')==2
            movefile([file '*'],[date filesep '.'])
        end

    end
    cd(workdir)

catch
    cd(workdir)
end

cd(workdir)     % back to work directory


% High fiber diet defintion. For details, please see https://www.vmh.life/#nutrition
% Ines Thiele 2016-2019

Diet = {%'Reaction'	'Flux Value'
'EX_etoh(e)'	'22.79219595'
'EX_h2o(e)'	'181671.3368'
'EX_caro(e)'	'0.013131607'
'EX_retinol(e)'	'1.099662212'
'EX_thm(e)'	'7.235600966'
'EX_adpcbl(e)'	'2.56714E-06'
'EX_ribflv(e)'	'0.006894923'
'EX_nac(e)'	'0.479928584'
'EX_ncam(e)'	'0.216377372'
'EX_pnto_R(e)'	'0.054851141'
'EX_pydam(e)'	'0.00499406'
'EX_pydxn(e)'	'0.004994745'
'EX_pydx(e)'	'0.005054977'
'EX_btn(e)'	'0.000479218'
'EX_10fthf(e)'	'0.000254697'
'EX_5mthf(e)'	'0.000261905'
'EX_thf(e)'	'0.000270786'
'EX_ascb_L(e)'	'1.513851945'
'EX_vitd3(e)'	'1.53391E-05'
'EX_avite1(e)'	'0.068538616'
'EX_phyQ(e)'	'0.000936308'
'EX_ca2(e)'	'33.02011078'
'EX_cl(e)'	'231.4450117'
'EX_k(e)'	'116.4477739'
'EX_mg2(e)'	'31.15531784'
'EX_na1(e)'	'147.9118802'
'EX_pi(e)'	'22.33606621'
'EX_cu2(e)'	'0.04732792'
'EX_fe2(e)'	'0.424456084'
'EX_fe3(e)'	'0.424456084'
'EX_mn2(e)'	'0.174378247'
'EX_zn2(e)'	'0.244799633'
'EX_mnl(e)'	'2.691195893'
'EX_xylt(e)'	'0.276050998'
'EX_lcts(e)'	'26.57468014'
'EX_malt(e)'	'0.803397055'
'EX_sucr(e)'	'137.1179664'
'EX_fru(e)'	'157.3272926'
'EX_gal(e)'	'1.010236134'
'EX_cellul(e)'	'0.237688253'
'EX_ala_L(e)'	'59.06129761'
'EX_arg_L(e)'	'40.67170675'
'EX_asp_L(e)'	'80.1605212'
'EX_cys_L(e)'	'13.82679835'
'EX_glu_L(e)'	'130.8154595'
'EX_gly(e)'	'60.78249181'
'EX_urate(e)'	'6.319184488'
'EX_his_L(e)'	'17.21966348'
'EX_ile_L(e)'	'41.93225125'
'EX_leu_L(e)'	'63.31791856'
'EX_lys_L(e)'	'46.34676332'
'EX_met_L(e)'	'12.66995194'
'EX_phe_L(e)'	'29.69793406'
'EX_pro_L(e)'	'50.90466905'
'EX_ser_L(e)'	'52.11494434'
'EX_thr_L(e)'	'38.25894566'
'EX_trp_L(e)'	'6.192991854'
'EX_tyr_L(e)'	'21.2683752'
'EX_val_L(e)'	'50.97864807'
'EX_dca(e)'	'0.043443556'
'EX_ddca(e)'	'0.101851489'
'EX_ttdca(e)'	'0.787507202'
'EX_ttdcea(e)'	'0.031285071'
'EX_ptdca(e)'	'0.072103355'
'EX_hdca(e)'	'34.44714331'
'EX_hpdca(e)'	'0.202603374'
'EX_ocdca(e)'	'9.424142226'
'EX_ocdcea(e)'	'130.2124615'
'EX_lnlc(e)'	'66.47282487'
'EX_lnlnca(e)'	'22.76317966'
'EX_strdnc(e)'	'0'
'EX_arach(e)'	'0.667592228'
'EX_CE2510(e)'	'1.006715204'
'EX_CE4843(e)'	'0.038033671'
'EX_arachd(e)'	'0.35958741'
'EX_docosac(e)'	'0.394315728'
'EX_doco13ac(e)'	'0.049887472'
'EX_adrn(e)'	'0'
'EX_clpnd(e)'	'0.050167498'
'EX_crvnc(e)'	'0.384328462'
'EX_but(e)'	'0.07233298'
'EX_octa(e)'	'0.015502414'
'EX_chsterol(e)'	'1.053035858'
'EX_sbt_D(e)'	'6.5699521'
'EX_glc_D(e)'	'120.210995'
'EX_hdcea(e)'	'3.616984668'
'EX_lgnc(e)'	'0.166975493'
'EX_fol(e)'	'0.000272645'
'EX_strch1(e)'	'45.11396195'
'EX_i(e)'	'0.003660628'
'EX_starch1200(e)'	'0.417683121'

};

Diet = regexprep(Diet,'EX_','Diet_EX_');
Diet = regexprep(Diet,'\(e\)','\[d\]');


function stackOut = WardAlignment(stack, bStackOut, folder_name, format, target_exposure)
%
%
%       stackOut = WardAlignment(stack, bStackOut, folder_name, format)
%
%       This function shifts pixels on the right with wrapping of the moved
%       pixels. This can be used as rotation on the Y-axis for environment
%       map encoded as longituted-latitude encoding.
%
%       Input:
%           -stack: a stack (4D) containing all images.
%           -bStackOut: if it is true (1), it outputs an aligned stack in
%           stackOut. Otherwise, stackOut is set to empty, [].
%           -folder_name: the folder name where the stack is stored. This flag
%           is valid if stack is empty, [].
%           -format: the file format of the stack. This flag is valid if
%           stack is empty, [].
%           -target_exposure: The index of the target exposure for aligning
%           images. If stack is empty, [], it contains the name of the file
%           for the alignment. If not provided the stack will be analyzed.
%
%       Output:
%           -stackOut: the aligned stack as output
%
%     Copyright (C) 2012-15  Francesco Banterle
%
%     This program is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
%
%     This program is distributed in the hope that it will be useful,
%     but WITHOUT ANY WARRANTY; without even the implied warranty of
%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%     GNU General Public License for more details.
%
%     You should have received a copy of the GNU General Public License
%     along with this program.  If not, see <http://www.gnu.org/licenses/>.
%

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

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

lst = [];

bStack = ~isempty(stack);

if(~bStack)
    lst = dir([folder_name, '/*.', format]);
    n = length(lst);
else
    n = size(stack, 4);
    stack = normalizeFromAnything(stack);
end

if(n < 2)
    return;
end

if(~exist('target_exposure', 'var'))
    target_exposure = GalloReferenceImage(stack, folder_name, format);
else
    if(~bStack)
        target_exposure = findNameInList(lst, target_exposure);
    end
end

if(bStack)
    img = stack(:,:,:,target_exposure);
else
    img = ldrimread([folder_name, '/', lst(target_exposure).name]);
end

[r, c, col] = size(img);

alignment = zeros(n, 2);

stackOut = [];

if(bStackOut)
    stackOut = zeros(r, c, col, n);
    stackOut(:,:,:,target_exposure) = img;
end

for i=1:n
    shift_ret = [0, 0];

    if(i ~= target_exposure)
        disp(['Aligning image ', num2str(i), ' to image ', num2str(target_exposure)]);

        if(~bStack)
            img_work = ldrimread([folder_name, '/', lst(i).name]);
        else
            img_work = stack(:,:,:,i);
        end

        img_work_shifted = WardImageAlignment(img, img_work);

        if(bStackOut)
            stackOut(:,:,:,i) = img_work_shifted;
        end

        if(~bStack)
            name = strrep(lst(i).name, ['.', format], ['_shifted.', format]);

            if(strcmp(lst(i).name, name) == 1)
                name = [name, '_shifted.', format];
            end

            imwrite(img_work_shifted,[folder_name, '/', name]);
        end

        clear('img_work_shifted');
        clear('img_work');
    end

    alignment(i,:) = shift_ret;
end

end


function val = ctrGet(ctr,param,varargin)
% Retrieve data from ConTrack structure
%
%  val = ctrGet(ctr,param,varargin)
%
% Read the parameters of a ctr structure.
% Access this structure should go through this routine and through
%   ctrSet.
%
% Parameters:
%
%
%

if notDefined('ctr'), error('No ConTrack structure defined.'); end
if notDefined('param'), error('No parameter defined'); end

val = [];

switch lower(param)
    case {'version'}
        val = ctr.version;
    case {'name'}
        val = ctr.name;
    case {'type'}
        val = ctr.type;
    case {'image_directory'}
        val = ctr.image_directory;
    case {'tensors_filename'}
        val = ctr.tensors_filename;
    case {'fa_filename'}
        val = ctr.fa_filename;
    case {'pdf_filename'}
        val = ctr.pdf_filename;
    case {'mask_filename'}
        val = ctr.mask_filename;
    case {'xmask_filename'}
        val = ctr.Xmask_filename;
    case {'require_way'}
        val = ctr.require_way;
    case {'compute_fa'}
        val = ctr.compute_fa;
    case {'sampler_type'}
        val = ctr.sampler_type;
    case {'desired_samples'}
        val = ctr.desired_samples;
    case {'burnin'}
        val = ctr.burnin;
    case {'max_nodes'}
        val = ctr.max_nodes;
    case {'min_nodes'}
        val = ctr.min_nodes;
    case {'step_size'}
        val = ctr.step_size;
    case {'skip_samples'}
        val = ctr.skip_samples;
    case {'roi'}
        if length(varargin) ~= 2, error('Incomplete ctrGet for ROI'); end
        arg1 = varargin{1};
        arg2 = varargin{2};
        switch lower(arg2)
            case {'coords'}
                val = ctr.roi{arg1}.coords;
            case {'valid_cortex'}
                val = ctr.roi{arg1}.valid_cortex;
            case {'seed_region'}
                val = ctr.roi{arg1}.seed_region;
        end
    case {'translate'}
        val = ctr.translate;
    case {'isr'}
        val = ctr.isr;
    case {'esr'}
        val = ctr.esr;
    case {'temp_swap'}
        val = ctr.temp_swap;
    case {'inv_temp'}
        val = ctr.inv_temp;
    case {'start_path_tries'}
        val = ctr.start_path_tries;
    case {'save_out_spacing'}
        val = ctr.save_out_spacing;
    case {'fa_absorb'}
        val = ctr.fa_absorb;
    case {'abs_normal'}
        val = ctr.abs_normal;
    case {'abs_penalty'}
        val = ctr.abs_penalty;
    case {'smooth_std'}
        val = ctr.smooth_std;
    case {'angle_cutoff'}
        val = ctr.angle_cutoff;
    case {'shape_params_vec'}
        val = ctr.shape_params_vec;
end

return;


  function hh = fig_text(varargin)
%|function hh = fig_text(...)
%| add text to figure, using coordinates relative to entire window
%| options:
%|	'-date'		prepend date
%|	'-tex'		tex parse string
%|	x,y		coordinates relative to [0 0 1 1]
%|	{args}		style arguments for text() command
%| jeff fessler

comment = '';
thedate = '';
interpret = 'none';
textarg = {'fontsize', 11};
x = 0.01;
y = 0.01;
while length(varargin)
	arg = varargin{1};
	if ischar(arg)
		if streq(arg, '-date')
			thedate = [mydate ' '];
		elseif streq(arg, '-tex')
			interpret = 'tex';
		else
			comment = arg;
		end
		varargin = {varargin{2:end}};

	elseif isnumeric(arg)
		if length(varargin) < 2, error 'need x, y', end
		x = varargin{1};
		y = varargin{2};
		varargin = {varargin{3:end}};

	elseif iscell(arg)
		textarg = {textarg{:}, arg{:}};
		varargin = {varargin{2:end}};

	else
		help(mfilename), error 'bad args'
	end
end

hh = gca;

hold on
h = axes('position', [0 0 1 1]); axis off
h = text(x, y, [thedate comment], 'interpreter', interpret, textarg{:});
hold off

if nargout
	hh = h;
else
	axes(hh) % reset axes to the one before the text added
	clear hh
end

function s = mydate
%s = datestr(now, 'yyyy-mm-dd HH:MM:SS');
%s = datestr(now, 'yy-mm-dd HH:MM:SS');
t1 = datestr(now, 'yy');
t2 = datestr(now, 'mm');
t3 = datestr(now, 'dd');
t4 = datestr(now, 'HH:MM:SS');
s = sprintf('%s-%s-%s %s', t1, t2, t3, t4);


function varargout = subsref(S, index)
%SUBSREF    Evaluate a SPINOPERATOR or reference its fields.
%   S(U) is equaivalent to FEVAL(S, U).
%
%   S.PROP returns the property PROP of S.
%
% See also SPINOPERATOR/FEVAL.

% Copyright 2017 by The University of Oxford and The Chebfun Developers.
% See http://www.chebfun.org/ for Chebfun information.

idx = index(1).subs;
switch index(1).type

    case '.'

        % Allow access to any of the properties of S:
        out = S.(idx);

        % Recurse on SUBSREF:
        if ( numel(index) > 1)
            out = subsref(out, index(2:end));
        end

        varargout = {out};

    case '()'

        % Evaluate the operator, i.e., wrapper for SPINOPERATOR/FEVAL:
        varargout = {feval(S, idx{:})};

    otherwise

        error('SPINOPERATOR:subsref:indexType', ...
            ['Unexpected index type encountered: ' index(1).type]);

end


function [tree ndnm]=updatetree(tree,ndnm,al)
  apr=find([tree.sym]==al);
  if isempty(apr)
      apr=find([tree.wgt]==0);

      tree(end+1).left=0;
      tree(end).right=0;
      tree(end).sym=al;
      tree(end).parent=apr;
      tree(end).wgt=1;
      tree(end).nn=ndnm;

      ndnm=ndnm-1;

      tree(apr).wgt=tree(apr).wgt+1;
      tree(apr).right=length(tree);

      tree(end+1).left=0;
      tree(end).right=0;
      tree(end).sym=0;
      tree(end).parent=apr;
      tree(end).wgt=0;
      tree(end).nn=ndnm;

      ndnm=ndnm-1;
      tree(apr).left=length(tree);

      apr=tree(apr).parent;
      if apr==0
		return;
      end
  end
      while(1)
      ndwt=tree(apr).wgt;
      ndn=tree(apr).nn;
      wt=find([tree.wgt]==ndwt);
      mx=max([tree(wt).nn]);
      idx=find([tree.nn]==mx);
      if (ndn==mx) | (tree(apr).parent==idx)
          tree(apr).wgt=tree(apr).wgt+1;
      else
          temp=tree(idx);
          tree(idx)=tree(apr);
          tree(apr)=temp;

          temp=idx;
          idx=apr;
          apr=temp;

          temp=tree(idx).nn;
          tree(idx).nn=tree(apr).nn;
          tree(apr).nn=temp;

          temp=tree(idx).parent;
          tree(idx).parent=tree(apr).parent;
          tree(apr).parent=temp;

          id=tree(apr).left;
          if id~=0
              tree(id).parent=apr;
          end
          id=tree(apr).right;
          if id~=0
              tree(id).parent=apr;
          end

          id=tree(idx).left;
          if id~=0
              tree(id).parent=idx;
          end
          id=tree(idx).right;
          if id~=0
              tree(id).parent=idx;
          end

          tree(apr).wgt=tree(apr).wgt+1;
      end
          if tree(apr).parent==0
              break;
          end
          apr=tree(apr).parent;

      end
end


% Source Code Listings for the Calspan Version
% of the FlOl Engine Response Model
% Based on Report DNA-TR-93-124 by Adam J. Baran
% and Dr. Michael G. Dunn of Calspan Corporation
%
% AFRL/RQTI Sept 2012
%
% engine parameters:
% xn1 - fan speed (rpm)
% xn2 - core speed (rpm)
%    (fan speed correlation)
% xigv - fan inlet variable guide vane angle (deg.)
% psl4 - fan discharge static pressure (psig)
% pt25 - fan discharge total pressure (psig)
% xoil1 - oil pressure [xn1 correlation) (psig)
%    (core speed correlation)
% thrust - thrust (lbf)
% air - airflow (lbm/sec)
% vgv -compressor inlet variable guide vane angle (deg.)
% cdp - compressor discharge pressure Cpsig)
% pyro - pyrometer temperature (F)
% egt - exhaust gas temperature (F)
% fuel - fuel flow (Pph)
% xoil2c - oil pressure [xn2 correlation] (psig)
%
%       (subscripts)
% ()nom - nominal value
% ()del - Cin/de)crement over current interval
% ()sumc - sum of (in/de)crements over previous intervals
%        (prescripts)
% f() - function which generates the value of the variable
%
% Normal syntax to run is "Dunnv1('infile.dat','outfile.dat')" from matlab
% prompt. To build datafile on first run just run "Dunnv1"...
%% Main Routine
function Dunnv1(Infile,Outfile)
dbstop if error
% Check for whether a runtime datafile exists
if nargin == 0 ;            % no formatted input file exists
    defaultdata ;
    Infile = 'infile.dat';
    Outfile = 'outfile.dat';
elseif nargin == 1 ;        % formatted input file exists
    Outfile = 'outfile.dat';
end ;
STOR = [];
%% -------------------------------
% ROUTINE - READIN DATA FILE
%  -------------------------------
% readindata(Infile) ; Read in data from inputfile ; IN = fopen(Infile,'r') ;
%if (Infile == '');
%%%    Infile = 'infile.dat' ; %%% Remove this when converting to input
%end;
IN = fopen(Infile); %IN = fopen('infile.dat','w')
[pla] = textread(Infile, '%f',1,'headerlines',4) ;
[pamb] = textread(Infile, '%f',1,'headerlines',6) ;
[tamb] = textread(Infile, '%f',1,'headerlines',8) ;
[debug] = textread(Infile, '%u',1,'headerlines',10) ;
[nenc] = textread(Infile, '%u',1,'headerlines',12) ;
% Preallocate the arrays
% ib = zeros(nenc,1); blend = zeros(nenc,1); c = zeros(nenc,1); delt = zeros(nenc,1);
[ib blend c delt] =  textread(Infile,'%u %u %f %f','headerlines',14) ;
fclose('all') ;
%% Start writting out Header Block of Output File
%% -------------------------------
% ROUTINE - WRITEOUT RESULTS
%  -------------------------------
%if (Infile == '');
%%%    Outfile = 'outfile.dat' ; %%% Remove this when converting to input
%end;
OUT = fopen(Outfile,'w') ;
fprintf(OUT,'PEARL - F101 reponse model \n') ;
fprintf(OUT,'%s\n',datestr(now)) ;
fprintf(OUT,' \n') ; fprintf(OUT,' \n') ; fprintf(OUT,' \n') ;
fprintf(OUT,'inputs :  \n'); fprintf(OUT,' \n') ;
fprintf(OUT,'PLA (deg) from (16.5-80.0) =>  \n') ;
fprintf(OUT,'%-4.2e  \n',pla) ;
fprintf(OUT,'ambient pressure (psia) => ') ; fprintf(OUT,'%-4.2e  \n',pamb) ;
fprintf(OUT,'ambient temperature (F) => ') ; fprintf(OUT,'%-4.2e  \n',tamb) ;
fprintf(OUT,' \n') ;
fprintf(OUT,'#_of_encounters(-)(1-10)=> ') ; fprintf(OUT,'%-2i  \n',nenc) ;
fprintf(OUT,'enc#, blend (1=mpb,2=blend2), dust conc. (mg/m^3), duration (min) \n') ;
fprintf(OUT,' \n') ;
for i = 1:1:max(ib) ; % 'max(ib) is 'nenc'
    fprintf(OUT,'%-2i \t %-1i \t %-4.2e \t  %-4.2e \n', ib(i), blend(i),c(i),delt(i));
end ;
fprintf(OUT,' \n') ;
fprintf(OUT,'debug mode (0=off,1=on)  => ') ; fprintf(OUT,'%-2i  \n',debug) ;
fprintf(OUT,' \n') ; fprintf(OUT,' \n') ;
fprintf(OUT,'calculation begun   \n') ; fprintf(OUT,' \n'); fprintf(OUT,' \n');
fprintf(OUT,' i blend dust cnc. time int. AIR FLOW   ACC DUST    N2     CDP    FUEL FLOW   THRUST  \n');
fprintf(OUT,'         (mg/m^3)  (min)     lbm/sec)  (kg)        (rpm)  (psig) (lbm/hr)    (lbf)   \n');
fprintf(OUT,'+--+---+--------+--------+-------------+----------+-------+------+----------+-------+ \n');
%% START MAIN LOGIC HERE
% Initialize all Runtime Engine Parameters to zero
ienc = 0; none = 0; dust = 0.; icdpflag = 0; cdplim = 54.; accdust = 0. ;
ibug = 0; time = 0. ;
xn2nom = 0.; xn2del = 0.; xn2sum = 0.;            % Spool speeds
cdpnom = 0.; cdpdel = 0.; cdpsum = 0.;            % Compressor pressure
fuelnom = 0.; fueldel = 0.; fuelsum = 0.;         % Fuel mass flow
thrustnom = 0.; thrustdel = 0.; thrustsum = 0.;   % Engine Thrust
%%% F101 Specific DATA Here
const = 1.699e-06;                                % F101 engine correl. parameters for dust accum in F101
cdprate1 = 9.36e-03; cdprate2 = 1.59e-02;         % F101 engine correl. parameters for cdp w/ dust1 and 2
fuelrate1 = 1.22e-01; fuelrate2 = 3.32e-01;       % F101 engine correl. parameters for fuel mass flow w/ dust1 and 2
thrustrate1 = 1.41e-01; thrustrate2 = 3.33e-01;   % F101 engine correl. parameters for thrust w/ dust1 and 2
%%% F101 Specific DATA Here
% Calculate Ambient Density of Air (lbm/sec)
rhoamb = 144.*pamb/(53.3*(tamb+460.));            % Air equation of state
% Nominal clear air engine parameter values
xn2nom = FXN2NOM(pla) ;     % call function "figure nominal core speed from PLA"
xn2  = xn2nom ;             % set core speed from nominal core speed
air = FAIR(xn2) ;           % call function for "obtain air mass flow from core speed"
cdpnom = FCDPNOM(xn2) ;     % call function "get nominal compress discharge pressure from core speed"
cdp = cdpnom ;              % set comp. discharge pressure from nominal comp. discharge pressure
fuelnom = FFUELNOM(xn2) ;   % call function "get nominal fuel flow from core speed"
fuel = fuelnom ;            % set fuel flow from the nominal fuel flow
thrustnom = FTHRUSTNOM(xn2) ;
thrust = thrustnom ;
fprintf(OUT,'%2i\t%2i\t%4.1f\t%5.1f\t\t%4.1f\t\t%3.2e\t%6.1f\t%4.1f\t%6.1f\t%6.1f\n',0,0,0,0,air,accdust,xn2,cdp,fuel,thrust) ;
STORBASE = [0 0 0 0 0 air accdust xn2 cdp fuel thrust];
% LOOP over all dust clound encounters
for ienc = 1:1:nenc;
    %% Calculate Airflow, ingested dust over this interval and total accumulated dust
    % based on conditions at start of encounter
    air = FAIR(xn2);
    q = air/rhoamb ;
    dust = const*q*c(ienc)*delt(ienc) ; % Incremental Dust accumulation
    accdust = dust + accdust;           % Cumulative Dust accumulation
    %% Calculate Core Speed          %ibug %ib(ienc)%accdust %c(ienc)
    xn2rate = FXN2RATE(ibug,blend(ienc),accdust,c(ienc));
    xn2del = xn2rate*delt(ienc);
    xn2 = xn2nom - xn2del - xn2sum ;
    %% Calculate cdp
    cdpnom = FCDPNOM(xn2);
    if(blend(ienc) == 1);    % If dust blend #1 (mpb)
       cdprate = cdprate1 ;
    elseif(blend(ienc) == 2); % If dust blend #2 (blend-2)
       cdprate = cdprate2 ;
    end;
    cdpdel = cdprate*c(ienc)*delt(ienc);
    cdp = cdpnom + cdpdel + cdpsum ;
    %% Check for surge probability
    if((cdpdel+cdpsum >= cdplim)&&(icdpflag == 0));
       icdpflag = 1;
       cdpdelc = cdplim - cdpsum ;
       tau = cdpdelc/(cdprate*c(ienc));
       fprintf(OUT,'%s %3.1f  %s  %2i %s','*** engine surge at ',tau,'minutes into the',ienc,' -th encounter');
       fprintf(OUT,' \n') ;
    end
    %% Calculate Fuel Burn Rate
    fuelnom = FFUELNOM(xn2) ;
    if(blend(ienc) == 1);    % If dust blend #1 (mpb)
       fuelrate = fuelrate1 ;
    elseif(blend(ienc) == 2); % If dust blend #2 (blend-2)
       fuelrate = fuelrate2 ;
    end;
    fueldel = fuelrate*c(ienc)*delt(ienc) ;
    fuel = fuelnom + fueldel + fuelsum ;
    %% Calculate Thrust
    thrustnom = FTHRUSTNOM(xn2) ;
    if(blend(ienc) == 1);    % If dust blend #1 (mpb)
       thrustrate = thrustrate1 ;
    elseif(blend(ienc) == 2); % If dust blend #2 (blend-2)
       thrustrate = thrustrate2 ;
    end;
    thrustdel = thrustrate*c(ienc)*delt(ienc);
    thrust = thrustnom + thrustdel + thrustsum ;
    %% Updat the sum terms of each engine parameter
    xn2sum = xn2sum + xn2del ;
    cdpsum = cdpsum + cdpdel ;
    fuelsum = fuelsum + fueldel ;
    thrustsum = thrustsum + thrustdel ;
    %% Write and store out runtime results
    fprintf(OUT,'%2i\t%2i\t%4.1f\t%5.1f\t\t%4.1f\t\t%3.2e\t%6.1f\t%4.1f\t%6.1f\t%6.1f\n',ienc,blend(ienc),c(ienc),delt(ienc),air,accdust,xn2,cdp,fuel,thrust) ;
    time = time + delt(ienc);
    STOR(ienc,:) = [ienc time blend(ienc) c(ienc) delt(ienc) air accdust xn2 cdp fuel thrust];
end
STOR = [STORBASE ; STOR] ;
% Plot Out Trends
figure(1); scale = 0;
subplot(2,3,1); plot(STOR(:,2),STOR(:,4)); grid on ; axis([ 0 max(STOR(:,2)) 0 1.1.*max(STOR(:,4))]) ;
title('dust concentration at enc') ; xlabel('time (min)'); ylabel('concentration (mg/m^3)') ;
subplot(2,3,2); plot(STOR(:,2),STOR(:,6)); grid on ;
if (scale == 1); axis([ 0 max(STOR(:,2)) 0 1.1.*max(STOR(:,6))]) ; end;
title('air flow') ; xlabel('time (min)'); ylabel('air mass flow (lbm/sec)') ;
subplot(2,3,3); plot(STOR(:,2),STOR(:,8)); grid on ;
if (scale == 1); axis([ 0 max(STOR(:,2)) 0 1.1.*max(STOR(:,8))]) ; end;
title('fan speed') ; xlabel('time (min)'); ylabel('fan speed (rpm)') ;
subplot(2,3,4); plot(STOR(:,2),STOR(:,9)); grid on ;
if (scale == 1); axis([ 0 max(STOR(:,2)) 0 1.1.*max(STOR(:,9))]) ; end ;
title('compressor discharge pressure') ; xlabel('time (min)'); ylabel('pressure (psig)') ;
subplot(2,3,5); plot(STOR(:,2),STOR(:,10)); grid on ;
if (scale == 1); axis([ 0 max(STOR(:,2)) 0 1.1.*max(STOR(:,10))]) ; end;
title('fuel burn') ; xlabel('time (min)'); ylabel('fuel burn rate (pph)') ;
subplot(2,3,6); plot(STOR(:,2),STOR(:,11)); grid on ;
if (scale == 1); axis([ 0 max(STOR(:,2)) 0 1.1.*max(STOR(:,11))]) ; end;
title('thrust') ; xlabel('time (min)'); ylabel('thrust (lbf)') ;
%
fclose(OUT) ;
% END of MAIN Routine
end
%% Calculate Airflow as a function a fan of fan speed
% "x" is passed from "xn2" and "y" is passed from "air"
function [y] = FAIR(x);  %%% F101 Specific DATA Here
%%% F101 Specific DATA Here
a0= 440922.79744; a1= -174.0731208; a2= 0.027346652504;
a3= -2.1376216416e-06; a4= 8.3178976743e-11; a5= -1.2891058570e-15;
p = [440922.79744 -174.0731208 0.027346652504 -2.1376216416e-06 8.3178976743e-11];
%%% F101 Specific DATA Here
if(x<10348.);
    y=0.;
elseif(x>15000.);
    y=0.;
elseif((x>=10348.)&&(x<=15000.));
    y = a0 + a1*x + a2*x^2 + a3*x^3 + a4*x^4 + a5*x^5;
%    y = polyval(p,x)
end
end
%% Calculate the nominal fuel a fan of fan speed, x is passed from xn2
function [y] = FFUELNOM(x) ;%%% F101 Specific DATA Here
%%% F101 Specific DATA Here
a0 = -49816.415015; a1 = 15.16955213; a2 = -0.00090483247417;
a3 = -1.0788972042E-07; a4 = 1.3439057313e-11; a5 = -3.6898802700E-16;
%%% F101 Specific DATA Here
if(x<10348.);
    y = 0. ;
elseif(x>15000.);
    y = 0. ;
elseif((x>=10348.)&&(x<=15000.));
    y = a0 + a1*x + a2*x^2 + a3*x^3 + a4*x^4 + a5*x^5;
end
end
%% Function calculates the nominal thrust a fan of fan speed
function [y] = FTHRUSTNOM(x);%%% F101 Specific DATA Here
% 'x' is 'xn2' while 'y' is 'fthrustnom'
%%% F101 Specific DATA Here
a10=-90190833.084; a11=38206.13731; a12=-6.4537917919; a13=0.00054340227729;
a14=-2.2807645464e-08; a15=3.8182035691e-13;
a20=-26525834.184; a21=5596.7412494; a22=-0.24258263565; a23=-2.2544154617e-05;
a24=2.2276804666e-09; a25=-5.2033103514e-14;
%%% F101 Specific DATA Here
if(x<10543.) ;
    y = 0. ;
elseif(x>15000.) ;
    y = 0. ;
elseif((x>=10543.)&&(x<=13246.));
    y = a10 + a11*x + a12*x^2 + a13*x^3 + a14*x^4 + a15*x^5;
elseif((x>13426.)&&(x<=15000.));     % else
    y = a20 + a21*x + a22*x^2 + a23*x^3 + a24*x^4 + a25*x^5;
end
end
%%  Calculate Nominal value of Core Speed as function of power setting
function [y] = FXN2NOM(x);%%% F101 Specific DATA Here
% "x" is passed from the global variable "pla", and "y" is "xn2nom"
%%% F101 Specific DATA Here
a10=10353.360465; a11=0.18067978533; a20=10306.641571;
a21=220.99533596; a22=-21.326092808; a23=0.69563112177;
a24=-0.0087987179757; a25=3.8820512919e-05;
%%% F101 Specific DATA Here
if(x<16.5) ;
    y = 0. ;
elseif(x>80.);
    y = 0. ;
elseif((x>=16.5)&&(x<30.));
    y = a10 + a11*x ;
elseif((x>=30.)&&(x<=80.));
    y = a20 + a21*x + a22*x^2 + a23*x^3 + a24*x^4 + a25*x^5 ;
end
end
%% Calculate Compressor Discharge Pressure from core speed
function [y]= FCDPNOM(x);%%% F101 Specific DATA Here
% "x" is passed from "xn2" and "y" is passed at "cdpnom"
%%% F101 Specific DATA Here
a0 = 52767.656799 ; a1 = -20.435530217 ; a2 = 0.0031594211659 ;
a3 = -2.441489353e-07 ; a4 = 9.4426267256e-12 ; a5 = -1.4592076510e-16 ;
%%% F101 Specific DATA Here
if(x<10348.);
    y = 0. ;
elseif(x>15000.);
    y = 0. ;
elseif((x>=10348.)&&(x<=15000.));
    y = a0 + a1*x + a2*x^2 + a3*x^3 + a4*x^4 + a5*x^5 ;
end
end
%% Calculates core speed drop rate due to dust
function [y] = FXN2RATE(libug,lblend,lacc,lc) ;%%% F101 Specific DATA Here
%% where 'libug' is passed from 'ibug', is debug mode
% where 'li' is passed from 'i', is cloud encounter index counter
% where 'lacc' is passed from 'acc', is sum accumulation of dust
% where 'lc' is passed from 'c', concentration of the dust cloud
% where 'y' is passed back as 'fxn2rate', the core speed drop rate
%%% F101 Specific DATA Here
a110 = 0. ; a111 = 0.031091666884 ; a120 = 2.2386 ; a130 = 0.41616348802 ;
a131= 0.062687011283 ; a210= -0.023120229598 ; a211= 0.19569725331 ;
a212= -0.001954960762 ; a213= 6.9569031307e-06;
%%% F101 Specific DATA Here
if(lacc<=0.); y = 0.0; end;
if(lblend==1);                  % Model for the mpb blend
    if(lacc<72.);
        if((lc>=0.)&&(lc<72.));
            y = a110 + a111*lc ;
        elseif((lc>=72.)&&(lc<=293.));
            y = a120 ;
        elseif(lc>293);
            y = 1.0e10 ;
        end;
    elseif(lacc>=72.);
        if((lc>=0.)&&(lc<=282.));
            y = a130 + a131*lc ;
        elseif(lc>282.);
            y = 1.0e10;
        end;
    end;
elseif(lblend==2);              % Model for Blend #2
    if((lc>=0.)&&(lc<=295.));
        y = a210 + a211*lc + a212*lc^2 + a213*lc^3 ;
    elseif(lc>295.);
        y = 1.0e10;
    end;
end
end
%% DEFAULT DATA INPUT FILE
function defaultdata() ;
%% --------------------------------
%       DEFAULT DATA INPUT FILE
%  --------------------------------
% Write out a formatted 'infile.dat' for user editing if none exists in the
% directory where 'Dunnv1.m' is run.
% Defualt INPUT VALUES BLOCK
pla = 80.0 ;    % 65 percent throttle (from 16.5 to 80)
tamb = 59.0 ;   % Ambient temperature (in degF)
pamb =  14.7 ;  % Ambient pressure (in psia)
nenc = 10 ;     % No. of dust cloud encounters (No. of enc)
% Dust cloud encounter index numbers
ib = [0 1 2 3 4 5 6 7 8 9 10];
% CMAS blend (1 = mpb, 2 = blend2), as defined in DNA TR-92-121
blend = [0 2 2 2 2 2 2 2 2 2 2];
% dust conc. (mg/m^3)
c = [0. 100. 100. 100. 100. 100. 100. 100. 100. 100. 100.];
% duration (min)
delt = [0.0 6.0 6.0 6.0 6.0 6.0 6.0 6.0 6.0 6.0 6.0];
% debug mode {0=off, 1=on}
debug = 0;
% Write out these properties into default file in carefully formatted
% output
IN = fopen('infile.dat','w') ;
fprintf(IN,'PEARL - F101 reponse model \n') ;
fprintf(IN,' \n') ;
fprintf(IN,' \n') ;
fprintf(IN,'PLA (deg) from (16.5-80.0) =>  \n') ;
fprintf(IN,'%-4.2e  \n',pla) ;
fprintf(IN,'ambient pressure (psia) =>  \n') ;
fprintf(IN,'%-4.2e  \n',pamb) ;
fprintf(IN,'ambient temperature (F) =>  \n') ;
fprintf(IN,'%-4.2e  \n',tamb) ;
fprintf(IN,'debug mode (0=off,1=on)  =>  \n') ;
fprintf(IN,'%-2i  \n',debug) ;
fprintf(IN,'#_of_encounters(-)(1-10)=>  \n') ;
fprintf(IN,'%-2i  \n',nenc) ;
fprintf(IN,'enc#, blend (1=mpb,2=blend2), dust conc. (mg/m^3), duration (min) \n') ;
fprintf(IN,' \n') ;
for i = 1:1:nenc; fprintf(IN,'%-2i \t %-1i \t %-4.2e \t  %-4.2e \n', ib(i+1),blend(i+1),c(i+1),delt(i+1));end;
fclose(IN); % Close file
end


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

%%
clear; close all; clc;

%% Syntax
% |[L]=isGlobalSurfDirOutward(F,V);|

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


function sequentialNames(varargin)
%SEQUENTIALNAMES Sets names of all unnamed layers based on type and order
% OBJ.SEQUENTIALNAMES() replaces empty layer names with new names
% sequentially, based on their function handle and execution order. OBJ
% is the network output layer.
% Example layer names are 'conv1', 'conv2', 'pool1'.
%
% OBJ1.SEQUENTIALNAMES(OBJ2, ...) or SEQUENTIALNAMES(OBJ1, OBJ2, ...) is
% the same, but considering a network with several outputs OBJ1, OBJ2, ...
%
% SEQUENTIALNAMES(..., MODIFIER) also specifies a function handle to be
% evaluated on each name, possibly modifying it (e.g. to append a prefix or
% suffix).
%
% See also Layer.workspaceNames.

% Copyright (C) 2016 Joao F. Henriques.
% All rights reserved.
%
% This file is part of the VLFeat library and is made available under
% the terms of the BSD license (see the COPYING file).

  if ~isempty(varargin) && isa(varargin{end}, 'function_handle')
    modifier = varargin{end} ;
    varargin(end) = [] ;
  else
    modifier = @deal ;
  end

  % list all layer objects, in forward order
  assert(~isempty(varargin), 'Not enough input arguments.') ;
  objs = cell(1, numel(varargin)) ;
  for i = 1:numel(varargin)
    objs{i} = varargin{i}.find() ;
  end
  objs = [objs{:}] ;  % flatten array of results

  % automatically set missing names, according to the execution order
  for k = 1:numel(objs)
    if isa(objs{k}, 'Input')  % input1, input2, ...
      if isempty(objs{k}.name)
        n = nnz(cellfun(@(o) isa(o, 'Input'), objs(1:k))) ;
        objs{k}.name = modifier(sprintf('input%i', n)) ;  %#ok<*AGROW>
      end
    elseif ~isempty(objs{k}.func)  % conv1, conv2...
      name = objs{k}.name ;
      if isempty(name)
        n = nnz(cellfun(@(o) isequal(o.func, objs{k}.func), objs(1:k))) ;
        name = func2str(objs{k}.func) ;  %#ok<*PROP>

        if strncmp(name, 'vl_nn', 5), name(1:5) = [] ; end  % shorten names
        if strcmp(name, 'bnorm_wrapper'), name = 'bnorm' ; end
        name = sprintf('%s%i', name, n) ;
        objs{k}.name = modifier(name) ;
      end

      % set dependant Param names for vl_nnconv and vl_nnbnorm
      suffix = [] ;
      if isequal(objs{k}.func, @vl_nnconv)
        suffix = {[], 'filters', 'biases'} ;
      elseif isequal(objs{k}.func, @vl_nnbnorm_wrapper)
        suffix = {[], 'g', 'b', 'moments'} ;
      end
      inputs = objs{k}.inputs ;
      if ~isempty(suffix)
        for i = 2 : min(numel(suffix), numel(inputs))
          if isa(inputs{i}, 'Param') && isempty(inputs{i}.name)
            inputs{i}.name = modifier(sprintf('%s_%s', name, suffix{i})) ;
          end
        end
      end

      % set dependant Param names for general layers: name_p1, name_p2, ...
      ps = find(cellfun(@(o) isa(o, 'Param'), inputs)) ;
      for i = 1:numel(ps)
        if isempty(inputs{ps(i)}.name)
          inputs{ps(i)}.name = modifier(sprintf('%s_p%i', name, i)) ;
        end
      end
    end
  end

  % name any remaining objects by class
  for k = 1:numel(objs)
    if isempty(objs{k}.name)
      n = nnz(cellfun(@(o) isa(o, class(objs{k})), objs(1:k))) ;
      objs{k}.name = modifier(sprintf('%s%i', lower(class(objs{k})), n)) ;
    end
  end
end


function [cfg] = ft_spike_plot_raster(cfg, spike, timelock)

% FT_SPIKE_PLOT_RASTER makes a raster plot of spike-trains and allows for a
% spike-density or a PSTH plot on top.
%
% Use as
%   ft_spike_plot_raster(cfg, spike)
% or
%   ft_spike_plot_raster(cfg, spike, timelock)
%
% The input SPIKE data structure should be organized as the spike or the
% raw datatype The optional input TIMELOCK should be organized as the
% timelock datatype, e.g. the output from FT_SPIKE_PSTH or FT_SPIKEDENSITY,
% having the average firing rate / spike count per time-point / time-bin.
% However, timelock could also be the output from FT_TIMELOCKANALYSIS.
%
% Configuration options
%   cfg.spikechannel     =  see FT_CHANNELSELECTION for details
%   cfg.latency          =  [begin end] in seconds, 'maxperiod' (default), 'minperiod',
%                           'prestim' (all t<=0), or 'poststim' (all t>=0).
%   cfg.linewidth        =  number indicating the width of the lines (default = 1);
%   cfg.cmapneurons      =  'auto' (default), or nUnits-by-3 matrix.
%                           Controls coloring of spikes and psth/density
%                           data if multiple cells are present.
%   cfg.spikelength      =  number >0 and <=1 indicating the length of the spike. If
%                           cfg.spikelength = 1, then no space will be left between
%                           subsequent rows representing trials (row-unit is 1).
%   cfg.trialborders     =  'yes' or 'no'. If 'yes', borders of trials are
%                           plotted
%   cfg.plotselection   =  'yes' or 'no' (default). If yes plot Y axis only for selection in cfg.trials
%   cfg.topplotsize      =  number ranging from 0 to 1, indicating the proportion of the
%                           rasterplot that the top plot will take (e.g., with 0.7 the top
%                           plot will be 70% of the rasterplot in size). Default = 0.5.
%   cfg.topplotfunc      =  'bar' (default) or 'line'.
%   cfg.errorbars        = 'no', 'std', 'sem' (default), 'conf95%','var'
%
%   cfg.interactive      = 'yes' (default) or 'no'. If 'yes', zooming and panning operate via callbacks.
%   cfg.trials           =  numeric or logical selection of trials (default = 'all').

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

% these are used by the ft_preamble/ft_postamble function and scripts
ft_revision = '$Id$';
ft_nargin   = nargin;
ft_nargout  = nargout;

% do the general setup of the function
ft_defaults
ft_preamble init
ft_preamble provenance spike timelock

% check if input spike structure is indeed a spike structure
spike = ft_checkdata(spike,'datatype', 'spike', 'feedback', 'yes'); % converts raw as well

% get the default options
cfg.spikechannel = ft_getopt(cfg,'spikechannel', 'all');
cfg.trials     = ft_getopt(cfg,'trials', 'all');
cfg.latency      = ft_getopt(cfg,'latency','maxperiod');
cfg.linewidth    = ft_getopt(cfg,'linewidth', 1);
cfg.cmapneurons  = ft_getopt(cfg,'cmapneurons', 'auto');
cfg.spikelength  = ft_getopt(cfg,'spikelength', 0.9);
cfg.topplotsize  = ft_getopt(cfg,'topplotsize', 0.5);
cfg.topplotfunc  = ft_getopt(cfg,'topplotfunc', 'bar');
cfg.errorbars    = ft_getopt(cfg,'errorbars', 'sem');
cfg.trialborders = ft_getopt(cfg,'trialborders','yes');
cfg.plotselection = ft_getopt(cfg,'plotselection','no');
cfg.interactive  = ft_getopt(cfg,'interactive','yes');

% ensure that the options are valid
cfg = ft_checkopt(cfg,'spikechannel',{'cell', 'char', 'double'});
cfg = ft_checkopt(cfg,'latency', {'char', 'ascendingdoublebivector'});
cfg = ft_checkopt(cfg,'trials', {'char', 'doublevector', 'logical'});
cfg = ft_checkopt(cfg,'linewidth', 'doublescalar');
cfg = ft_checkopt(cfg,'cmapneurons', {'char', 'doublematrix', 'doublevector'});
cfg = ft_checkopt(cfg,'spikelength', 'doublescalar');
cfg = ft_checkopt(cfg,'topplotsize', 'doublescalar');
cfg = ft_checkopt(cfg,'topplotfunc', 'char', {'bar', 'line'});
cfg = ft_checkopt(cfg,'errorbars', 'char', {'sem', 'std', 'conf95%', 'no', 'var'});
cfg = ft_checkopt(cfg,'trialborders', 'char', {'yes', 'no'});
cfg = ft_checkopt(cfg,'plotselection', 'char', {'yes', 'no'});
cfg = ft_checkopt(cfg,'interactive', 'char', {'yes', 'no'});

cfg = ft_checkconfig(cfg, 'allowed', {'spikechannel', 'latency', 'trials', 'linewidth', 'cmapneurons', 'spikelength', 'topplotsize', 'topplotfunc', 'errorbars', 'trialborders', 'plotselection', 'interactive'});

% check if a third input is present, and check if it's a timelock structure
if nargin==3
  doTopData = true;
  timelock  = ft_checkdata(timelock, 'datatype', 'timelock', 'hastrials', 'no', 'feedback', 'yes');
else
  doTopData = false;
end

% get the spikechannels
cfg.spikechannel = ft_channelselection(cfg.spikechannel, spike.label);
spikesel         = match_str(spike.label, cfg.spikechannel);
nUnits           = length(spikesel); % number of spike channels
if nUnits==0, error('No spikechannel selected by means of cfg.spikechannel'); end

% get the number of trials and set the cfg.trials field
nTrialsOrig = size(spike.trialtime,1);
nTrialsShown = nTrialsOrig;
if  strcmp(cfg.trials,'all')
  cfg.trials = 1:nTrialsOrig;
elseif islogical(cfg.trials) || all(cfg.trials==0 | cfg.trials==1)
  cfg.trials = find(cfg.trials);
end
cfg.trials = sort(cfg.trials(:));

if max(cfg.trials)>nTrialsOrig
  error('maximum trial number in cfg.trials should not exceed length of spike.trial')
end
if isempty(cfg.trials), errors('No trials were selected in cfg.trials'); end

% determine the duration of each trial
begTrialLatency = spike.trialtime(cfg.trials,1);
endTrialLatency = spike.trialtime(cfg.trials,2);

% select the latencies
if strcmp(cfg.latency,'minperiod')
  cfg.latency = [max(begTrialLatency) min(endTrialLatency)];
elseif strcmp(cfg.latency,'maxperiod') || strcmp(cfg.latency,'all')
  cfg.latency = [min(begTrialLatency) max(endTrialLatency)];
elseif strcmp(cfg.latency,'prestim')
  cfg.latency = [min(begTrialLatency) 0];
elseif strcmp(cfg.latency,'poststim')
  cfg.latency = [0 max(endTrialLatency)];
end

% check whether the time window fits with the data
if (cfg.latency(1) < min(begTrialLatency)), cfg.latency(1) = min(begTrialLatency);
  warning('Correcting begin latency of averaging window');
end
if (cfg.latency(2) > max(endTrialLatency)), cfg.latency(2) = max(endTrialLatency);
  warning('Correcting begin latency of averaging window');
end

% delete trials that are not in our window
overlaps      = endTrialLatency>=cfg.latency(1) & begTrialLatency<=cfg.latency(2);
trialSel      = overlaps(:);
cfg.trials    = cfg.trials(trialSel); %update the trial selection
if isempty(cfg.trials),warning('No trials were selected');end

% create the data that should be plotted
[unitX,unitY] = deal(cell(1,nUnits));

% find the spiketimes per neuron and make one vector of them with y value per element
for iUnit = 1:nUnits
  unitIndx       = spikesel(iUnit);
  latencySel     = spike.time{unitIndx}>=cfg.latency(1) & spike.time{unitIndx} <= cfg.latency(2);
  isInTrials     = ismember(spike.trial{unitIndx},cfg.trials);
  unitX{iUnit}   = spike.time{unitIndx}(isInTrials(:) & latencySel(:));
  unitY{iUnit}   = spike.trial{unitIndx}(isInTrials(:) & latencySel(:));
  if strcmp(cfg.plotselection,'yes')
   tempY{iUnit} = zeros(size(unitY{iUnit}));
   u = unique(unitY{iUnit});
   for i = 1:length(u)
     idx = find(unitY{iUnit} == u(i));
     tempY{iUnit}(idx) = i;
   end
   nTrialsShown = length(u);
   unitY{iUnit} = tempY{iUnit};
  end
end

% some error checks on spike length
if (cfg.spikelength<=0 || cfg.spikelength>1)
  error('cfg.spikelength should be a single number >0 and <=1. 1 row (1 trial) = 1');
end

% some error checks on the size of the top figure
if (cfg.topplotsize<=0 || cfg.topplotsize>1)
  error('cfg.topplotsize should be a single number >0 and <=1. 0.7 = 70%');
end

% plot the trial borders if desired
if strcmp(cfg.trialborders,'yes')
  begTrialLatency = begTrialLatency(overlaps(:));
  endTrialLatency = endTrialLatency(overlaps(:));

  % make yellow fills after trial end
  X = endTrialLatency;
  Y = cfg.trials;
  Y = [Y(:);Y(end);Y(1);(Y(1))];
  X = [X(:);cfg.latency(2);cfg.latency(2);endTrialLatency(1)];
  f = fill(X,Y,'y');
  set(f,'EdgeColor', [1 1 1]);

  % make yellow fills before trial beginning
  X = begTrialLatency;
  Y = cfg.trials;
  Y = [Y(:);Y(end);Y(1);(Y(1))];
  X = [X(:);cfg.latency(1);cfg.latency(1);begTrialLatency(1)];
  hold on, fill(X,Y,'y'), hold on
  set(f,'EdgeColor', [1 1 1]);
end

% start plotting the rasterplot
for iUnit = 1:nUnits

  % create the x and y value to be plotted
  x = [unitX{iUnit}(:)'; unitX{iUnit}(:)']; % create x duplicates, spike times
  y = unitY{iUnit}(:); % these are the trial values
  y = [y' - cfg.spikelength/2; y' + cfg.spikelength/2];

  % process the color information for the different units
  if strcmp(cfg.cmapneurons, 'auto'), cfg.cmapneurons = colormap_cgbprb(nUnits); end
  if all(size(cfg.cmapneurons) ./ [nUnits 3])
    color = cfg.cmapneurons(iUnit,:);
  else
    error('cfg.cmapneurons should be nUnits-by-3 matrix or "auto"');
  end

  % create axes for the rasterplot, all go to the same position, so do this for unit 1
  if iUnit==1
    ax(1) = newplot;
    posOrig = get(ax(1), 'Position'); % original position for a standard plot
    pos     = posOrig;
    if doTopData % if topdata, we leave space on top
      posRaster   = [pos(1:3) pos(4)*(1-cfg.topplotsize)]; % and decrease the size of width and height
    else
      posRaster   = pos;
    end
    set(ax(1), 'ActivePositionProperty', 'position', 'Position', posRaster)
  end

  % make the raster plot and hold on for the next plots
  rasterHdl = line(x, y,'LineWidth', cfg.linewidth,'Color', color);
  cfg.hdl.raster = rasterHdl;
  set(ax(1),'NextPlot', 'add')
  set(ax(1),'Box', 'off')
end

% create the labels for the first axes
xlabel('time (sec)')
ylabel('Trial Number')
axis ij

% plot the top data
if doTopData

  % match on the basis of labels, and specify this in the documentary
  unitIndx = find(ismember(timelock.label,spike.label(spikesel)));
  if sum(unitIndx)<nUnits, error('timelock.label should contain all label of selected units'); end

  % select timepoints  and get the data to be plotted
  binSel = timelock.time>=cfg.latency(1) & timelock.time<=cfg.latency(2);
  dataY  = timelock.avg(unitIndx,binSel);
  dataX  = timelock.time(binSel);

  % create the position for the topplot and axes with this position
  posTopPlot = [0 pos(4)*(1-cfg.topplotsize)  0 0] + pos.*[1 1 1 cfg.topplotsize];
  ax(2)  = axes('Units', get(ax(1), 'Units'), 'Position', posTopPlot,...
    'Parent', get(ax(1), 'Parent'));

  % make the bar or the line plot
  if strcmp(cfg.topplotfunc,'bar')

    % plot thje density / psth as a bar plot
    avgHdl  = feval(cfg.topplotfunc,dataX,dataY', 'stack');

    % color the different bars
    for iUnit = 1:nUnits
      set(avgHdl(iUnit),'FaceColor',cfg.cmapneurons(iUnit,:),'EdgeColor', cfg.cmapneurons(iUnit,:),'LineWidth', 3);
    end

    % set the bar width to 1
    set(avgHdl,'BarWidth', 1);

    if ~strcmp(cfg.errorbars, 'no') && nUnits>1
      warning('error bars can only be plotted with bar plot if one unit is plotted');
    end

    % add standard error bars to it
    if ~strcmp(cfg.errorbars, 'no') && nUnits==1
      x = [timelock.time(binSel);timelock.time(binSel)]; % create x doublets
      if strcmp(cfg.errorbars, 'sem')
        err = sqrt(timelock.var(unitIndx,binSel)./timelock.dof(unitIndx,binSel));
      elseif strcmp(cfg.errorbars, 'std')
        err = sqrt(timelock.var(unitIndx,binSel));
      elseif strcmp(cfg.errorbars, 'var')
        err = timelock.var(unitIndx,binSel);
      elseif strcmp(cfg.errorbars, 'conf95%')
        % use a try statement just in case the statistics toolbox doesn't work.
        try
          tCrit = tinv(0.975,timelock.dof(unitIndx,binSel));
          err = tCrit.*sqrt(timelock.var(unitIndx,binSel)./timelock.dof(unitIndx,binSel)); % assuming normal distribution, SHOULD BE REPLACED BY STUDENTS-T!
        catch % this is in case statistics toolbox is lacking
          err = 0;
          warning('error with computing 95% conf limits, probably issue with statistics toolbox');
        end
      end

      y = dataY + err;

      % plot the errorbars as line plot on top of the bar plot
      hold on
      y = [zeros(1,length(y));y]; % let lines run from 0 to error values
      hd = plot(x,y,'k'); % plot the error bars
    end

  else

    % plot the density / psth
    avgHdl  = feval(cfg.topplotfunc,dataX,dataY');

    % set the color for every unit
    for iUnit = 1:nUnits
      set(avgHdl(iUnit),'Color',cfg.cmapneurons(iUnit,:));
    end

    % ensure that the data limits are increasing
    mnmax = [nanmin(dataY(:))-eps nanmax(dataY(:))+eps];

    % plot the errorbars
    if ~strcmp(cfg.errorbars,'no')

      % check if the right error information is there
      if ~isfield(timelock, 'var') || ~isfield(timelock, 'dof')
        error('timelock should contain field .var and .dof for errorbars');
      end

      % select the degrees of freedom
      df = timelock.dof(unitIndx,binSel);

      % plot the different error bars
      if strcmp(cfg.errorbars, 'sem')
        err = sqrt(timelock.var(unitIndx,binSel)./df);
      elseif strcmp(cfg.errorbars, 'std')
        err = sqrt(timelock.var(unitIndx,binSel));
      elseif strcmp(cfg.errorbars, 'var')
        err = timelock.var(unitIndx,binSel);
      elseif strcmp(cfg.errorbars, 'conf95%')
        tCrit = tinv(0.975,df);
        err   = tCrit.*sqrt(timelock.var(unitIndx,binSel)./df);
      end

      % ensure division by zero does not count, should not happen however
      err(~isfinite(err)) = NaN;

      % make a polygon of the error bars that allows easy filling in adobe
      for iUnit = 1:nUnits
        upb  = dataY(iUnit,:) + err(iUnit,:);
        lowb = dataY(iUnit,:) - err(iUnit,:);
        sl   = ~isnan(upb);
        [X,Y] = polygon(dataX(sl),upb(sl)+0.0001,lowb(sl)-0.0001);
        hold on
        hd = plot(X,Y,'--');
        set(hd,'Color', cfg.cmapneurons(iUnit,:));
        hold on
      end
      mnmax = [nanmin(dataY(:) - err(:)) nanmax(dataY(:) + err(:))];
    end

    % set the y limits explicitly
    ylim = mnmax;
    d    = ylim(2)-ylim(1);
    yl = ylim(1)-0.05*d;
    if ylim(1)>0
      if yl<0, yl = 0; end
    end
    ylim(1) = yl;

    yl = ylim(2)+0.05*d;
    if ylim(2)<0
      if yl>0, yl = 0; end
    end
    ylim(2) = yl;
  if ylim(2) == ylim(1) %if the plot is empty
    ylim(2)=ylim(1)+1; %be nice to set
  end
    set(gca,'YLim', ylim)
  end

  % store the handle
  cfg.hdl.psth = avgHdl;

  % modify the axes
  set(ax(2),'YAxisLocation', 'right') % swap y axis location
  set(ax(2),'XTickLabel', {}) % remove ticks and labels for x axis
  set(ax(2),'XTick', [])
  set(ax(2), 'Box', 'off') % turn the box off

  % change the axis settings
  try
    ylabel(timelock.cfg.outputunit)
  catch
    warning('unit of the y-axis is unknown');
    ylabel('Signal intensity')
  end
end

% set the limits for the axis
set(ax,'XLim', [cfg.latency])
if nTrialsShown==0; nTrialsShown = 1; end %
set(ax(1), 'YLim', [0.5 nTrialsShown+0.5]); % number of trials
set(ax,'TickDir','out') % put the tickmarks outside

% now link the axes, constrain zooming and keep ticks intact
limX       = [cfg.latency];
limY       = get(ax,'YLim');
if ~iscell(limY), limY = {limY}; end

% constrain the zooming and zoom psth together with the jpsth, remove
% ticklabels jpsth
if strcmp(cfg.interactive,'yes')
  set(zoom,'ActionPostCallback',{@mypostcallback,ax,limX,limY});
  set(pan,'ActionPostCallback',{@mypostcallback,ax,limX,limY});
end

% pass positions and axis handles so downstream
% functions can respect the positions set here.
cfg.pos.posRaster = posRaster;
cfg.hdl.axRaster = ax(1);
if doTopData
 cfg.pos.posTopPlot = posTopPlot;
 cfg.hdl.axTopPlot = ax(2);
end

% do the general cleanup and bookkeeping at the end of the function

ft_postamble previous spike
ft_postamble provenance

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% SUBFUNCTION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [] = mypostcallback(fig,evd,ax,lim,ylim)
currentAxes = evd.Axes;
indx = find(currentAxes==ax);

% keep the y axis within boundaries
origLim = ylim{indx};
ylim = get(ax(indx), 'YLim');
if origLim(1)>ylim(1), ylim(1) = origLim(1); end
if origLim(2)<ylim(2), ylim(2) = origLim(2); end
set(ax(indx), 'YLim', ylim)

% keep the x axis within boundaries and reset for both
xlim = get(ax(indx), 'XLim');
if lim(1)>xlim(1), xlim(1) = lim(1); end
if lim(2)<xlim(2), xlim(2) = lim(2); end
set(ax,'XLim', xlim)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% SUBFUNCTION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [colorspace] = colormap_cgbprb(N)
% COLORMAP_SEPARATION returns a color map with well separated colors that does not include
% white, yellow or orange since these are not well visible in white plots.
%
% Inputs: N is the number of colors desired
% Outputs: COLORSPACE is an N-by-3 colorspace.
% Chosen colors are green, cyan, blue, purple, red and black
% Script was adapted from varycolors.m from FEX
% Copyright (c) 2009, Martin Vinck

if nargin<1
  error('specify the number of colors that you want')
end

% create a well visible color space
%        green     cyan  blue    purple    red     black
colors = [[0 1 0]; [0 1 1] ; [0 0 1] ; [1 0 1]; [1 0 0]; [0 0 0]];
order  = [1 5 3 2 4 6]; % our preference order when plotting different lines
rm{2} = [2:5];
rm{3} = [2 4 5];
rm{4} = [2 4];
rm{5} = [4];

if N==1
  colorspace = colors(end,:);
elseif N>1&&N<6
  colors(rm{N},:) = [];
  colorspace = colors;
else
  n      = floor(N/5)*ones(1,5);
  rest   = mod(N,5);
  order  = [1 5 3 2 4];
  % if we have some rest, add them starting oppositly
  n(order(1:rest)) = n(order(1:rest)) + 1;

  colorspace = [];
  for iColor = 1:5
    corStart  = colors(iColor,:);
    corEnd    = colors(iColor+1,:);
    dim       = corStart~=corEnd;
    subColors = corStart(ones(n(iColor)+1,1),:);
    if iColor>1
      subColors(:,dim) = linspace(corStart(dim),corEnd(dim),n(iColor)+1);
      subColors(1,:) = [];
    else
      subColors(1:end-1,dim) =   linspace(corStart(dim),corEnd(dim),n(iColor));
      subColors(end,:) = [];
    end
    colorspace = [colorspace;subColors];
  end
end

function [X,Y] = polygon(x,sm1,sm2,multiplier)

x = x(:)';
if nargin < 4
    multiplier = 1;
end
X = [x x(end:-1:1) x(1)];
up = sm1(:)';
down = sm2(:)';
Y = [down up(end:-1:1) down(1)];


%% set parameters
%folderpath = '/home/gyeongsikmoon/workspace/Data/Hand_pose_estimation/ICVL/Training/Depth/';
%filepath = '/home/gyeongsikmoon/workspace/Data/Hand_pose_estimation/ICVL/Training/labels.txt';
%frameNum = 331006;

folderpath = '/home/gyeongsikmoon/workspace/Data/Hand_pose_estimation/ICVL/Testing/Depth/';
filepath = '/home/gyeongsikmoon/workspace/Data/Hand_pose_estimation/ICVL/Testing/test_seq_1.txt';
frameNum = 702;

%folderpath = '/home/gyeongsikmoon/workspace/Data/Hand_pose_estimation/ICVL/Testing/Depth/';
%filepath = '/home/gyeongsikmoon/workspace/Data/Hand_pose_estimation/ICVL/Testing/test_seq_2.txt';
%frameNum = 894;

fp = fopen(filepath);
fid = 1;

tline = fgetl(fp);
while fid <= frameNum

    splitted = strsplit(tline);
    img_name = splitted{1};

    if exist(strcat(folderpath,img_name), 'file')
        img = imread(strcat(folderpath,img_name));

        fp_save = fopen(strcat(folderpath,img_name(1:size(img_name,2)-3),'bin'),'w');
        fwrite(fp_save,permute(img,[2,1,3]),'float');
        fclose(fp_save);

        %delete(strcat(folderpath,img_name));
    end

    tline = fgetl(fp);
    fid = fid + 1;
end

fclose(fp);


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

%%
clear; close all; clc;

%% Syntax
% |[Xc,Yc,Zc]=im2MRcart(I,J,K,v,OR,r,c);|

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


%kcpRGBNTSCtoRC 'converts an image from RGB NTSC to Retinal Cone '
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros cpRGBNTSCtoRC.pane file
%
% Parameters:
% InputFile: i 'Input ', required: 'First Input data object'
% OutputFile: o 'Output', required: 'Resulting output data object'
%
% Example: o = kcpRGBNTSCtoRC(i, {'i','';'o',''})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% cpRGBNTSCtoRC - converts an image from RGB NTSC to Retinal Cone
%
%  DESCRIPTION
% call ckfromRGBNTSC with the parameter -retinalcone to convert an image from RGB NTSC to Retinal Cone
%
%
%
%  EXAMPLES
%
%  "SEE ALSO"
%
%  RESTRICTIONS
%
%  REFERENCES
% All references for the COLOR toolbox are on the file $COLOR/Readme.html
%
%  COPYRIGHT
% Copyright (C) 1997 Rafael Santos. Khoros (C) Khoral Research, Inc.
%

function varargout = kcpRGBNTSCtoRC(varargin)
if nargin ==0
  Inputs={};arglist={'',''};
elseif nargin ==1
  Inputs=varargin{1};arglist={'',''};
elseif nargin ==2
  Inputs=varargin{1}; arglist=varargin{2};
else error('Usage: [out1,..] = kcpRGBNTSCtoRC(Inputs,arglist).');
end
if size(arglist,2)~=2
  error('arglist must be of form {''ParameterTag1'',value1;''ParameterTag2'',value2}')
 end
narglist={'i', '__input';'o', '__output'};
maxval={0,0};
minval={0,0};
istoggle=[0,0];
was_set=istoggle * 0;
paramtype={'InputFile','OutputFile'};
% identify the input arrays and assign them to the arguments as stated by the user
if ~iscell(Inputs)
Inputs = {Inputs};
end
NumReqOutputs=1; nextinput=1; nextoutput=1;
  for ii=1:size(arglist,1)
  wasmatched=0;
  for jj=1:size(narglist,1)
   if strcmp(arglist{ii,1},narglist{jj,1})  % a given argument was matched to the possible arguments
     wasmatched = 1;
     was_set(jj) = 1;
     if strcmp(narglist{jj,2}, '__input')
      if (nextinput > length(Inputs))
        error(['Input ' narglist{jj,1} ' has no corresponding input!']);
      end
      narglist{jj,2} = 'OK_in';
      nextinput = nextinput + 1;
     elseif strcmp(narglist{jj,2}, '__output')
      if (nextoutput > nargout)
        error(['Output nr. ' narglist{jj,1} ' is not present in the assignment list of outputs !']);
      end
      if (isempty(arglist{ii,2}))
        narglist{jj,2} = 'OK_out';
      else
        narglist{jj,2} = arglist{ii,2};
      end

      nextoutput = nextoutput + 1;
      if (minval{jj} == 0)
         NumReqOutputs = NumReqOutputs - 1;
      end
     elseif isstr(arglist{ii,2})
      narglist{jj,2} = arglist{ii,2};
     else
        if strcmp(paramtype{jj}, 'Integer') & (round(arglist{ii,2}) ~= arglist{ii,2})
            error(['Argument ' arglist{ii,1} ' is of integer type but non-integer number ' arglist{ii,2} ' was supplied']);
        end
        if (minval{jj} ~= 0 | maxval{jj} ~= 0)
          if (minval{jj} == 1 & maxval{jj} == 1 & arglist{ii,2} < 0)
            error(['Argument ' arglist{ii,1} ' must be bigger or equal to zero!']);
          elseif (minval{jj} == -1 & maxval{jj} == -1 & arglist{ii,2} > 0)
            error(['Argument ' arglist{ii,1} ' must be smaller or equal to zero!']);
          elseif (minval{jj} == 2 & maxval{jj} == 2 & arglist{ii,2} <= 0)
            error(['Argument ' arglist{ii,1} ' must be bigger than zero!']);
          elseif (minval{jj} == -2 & maxval{jj} == -2 & arglist{ii,2} >= 0)
            error(['Argument ' arglist{ii,1} ' must be smaller than zero!']);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} < minval{jj})
            error(['Argument ' arglist{ii,1} ' must be bigger than ' num2str(minval{jj})]);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} > maxval{jj})
            error(['Argument ' arglist{ii,1} ' must be smaller than ' num2str(maxval{jj})]);
          end
        end
     end
     if ~strcmp(narglist{jj,2},'OK_out') &  ~strcmp(narglist{jj,2},'OK_in')
       narglist{jj,2} = arglist{ii,2};
     end
   end
   end
   if (wasmatched == 0 & ~strcmp(arglist{ii,1},''))
        error(['Argument ' arglist{ii,1} ' is not a valid argument for this function']);
   end
end
% match the remaining inputs/outputs to the unused arguments and test for missing required inputs
 for jj=1:size(narglist,1)
     if  strcmp(paramtype{jj}, 'Toggle')
        if (narglist{jj,2} ==0)
          narglist{jj,1} = '';
        end;
        narglist{jj,2} = '';
     end;
     if  ~strcmp(narglist{jj,2},'__input') && ~strcmp(narglist{jj,2},'__output') && istoggle(jj) && ~ was_set(jj)
          narglist{jj,1} = '';
          narglist{jj,2} = '';
     end;
     if strcmp(narglist{jj,2}, '__input')
      if (minval{jj} == 0)  % meaning this input is required
        if (nextinput > size(Inputs))
           error(['Required input ' narglist{jj,1} ' has no corresponding input in the list!']);
        else
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        end
      else  % this is an optional input
        if (nextinput <= length(Inputs))
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end;
     else
     if strcmp(narglist{jj,2}, '__output')
      if (minval{jj} == 0) % this is a required output
        if (nextoutput > nargout & nargout > 1)
           error(['Required output ' narglist{jj,1} ' is not stated in the assignment list!']);
        else
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
          NumReqOutputs = NumReqOutputs-1;
        end
      else % this is an optional output
        if (nargout - nextoutput >= NumReqOutputs)
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end
     end
  end
end
if nargout
   varargout = cell(1,nargout);
else
  varargout = cell(1,1);
end
global KhorosRoot
if exist('KhorosRoot') && ~isempty(KhorosRoot)
w=['"' KhorosRoot];
else
if ispc
  w='"C:\Program Files\dip\khorosBin\';
else
[s,w] = system('which cantata');
w=['"' w(1:end-8)];
end
end
[varargout{:}]=callKhoros([w 'ckfromRGBNTSC"  -retinalcone'],Inputs,narglist);


function f =  quantity(q, which)

%tstoolbox/@unit/quantity
%   returns quantity name of unit q. If argument which is omitted, the
%   english quantity name will be returned.
%
% Copyright 1997-2001 DPI Goettingen, License http://www.physik3.gwdg.de/tstool/gpl.txt

if isa(q, 'unit')
	if nargin > 1
		if strcmp(which, 'ger')
			f = q.quantity.ger;
		else
			f = q.quantity.eng;
		end
	else
		f = q.quantity.eng;
	end
else
	f = '';
end


%function calib_gui(mode)

% calib_gui(mode)
%
% Runs the Camera Calibration Toolbox.
% Set mode to 1 to run the memory efficient version.
% Any other value for mode will run the normal version (see documentation)
%
% INFORMATION ABOUT THE MEMORY EFFICIENT MODE FOR THE CAMERA CALIBRATION TOOLBOX:
%
% If your calibration images are large, or if you calibrate using a lot of images, you may have experienced memory problems
% in Matlab when using the calibration toolbox (OUT OF MEMORY errors). If this is the case, you can now run the
% new memory efficient version of the toolbox that loads every image one by one without storing them all in memory.
% If you choose to run the standard version of the toolbox now, you can always switch to the other memory efficient mode
% later in case the OUT OF MEMORY error message is encountered. The two modes of operation are totally compatible.

cell_list = {};

fig_number = 1;

title_figure = 'Camera Calibration Toolbox - Select mode of operation:';

cell_list{1,1} = {'Standard (all the images are stored in memory)','calib_gui_normal;'};
cell_list{2,1} = {'Memory efficient (the images are loaded one by one)','calib_gui_no_read;'};
cell_list{3,1} = {'Exit',['disp(''Bye. To run again, type calib_gui.''); close(' num2str(fig_number) ');']};

show_window(cell_list,fig_number,title_figure,290,18,0,'clean',12);