%LOAD_ACQ  load BIOPAC's AcqKnowledge file format for Windows PC
%
%  Usage: acq = load_acq(filename, [force_chan_by_chan_load])
%
%  acq - AcqKnowledge file structure containing ACQ header field,
%	and data matrix.
%
%  filename - BIOPAC's AcqKnowledge file
%
%  force_chan_by_chan_load - Optional. By default, this optional flag will
%	be set to 1, which means that when you use acq = load_acq(fname),
%	the data will be loaded one channel after the other. This can
%	avoid memory crash when you load very large ACQ data. If your
%	ACQ data is not huge, I suggest that you set this optional flag to
%	0, i.e. acq = load_acq(fname, 0). In this case, the program will
%	read data depending on the data type. If the program detects that
%	the data type in ACQ file are different from channel to channel,
%	it will still read data channel by channel. Otherwise, it will
%	read whole data in one block (a lot faster than using traditional
%	way from channel to channel with the same result).
%
%  Notes:
%
%  This program is based on Application Note #156 from BIOPAC web site:
%  http://www.biopac.com/ResearchNotes.asp?Aid=&ANid=82&Level=4
%  ( 156 - ACQKNOWLEDGE FILE FORMATS FOR PC WITH WINDOWS )
%
%  The note mentioned that: "This document describes file formatting for
%  all Windows versions of AcqKnowledge 3.9.x or below". Thanks to the
%  open Python source code provided by Nathan Vack, this program can also
%  read AcqKnowledge 4.0 & 4.1 data (with no documentation from BIOPAC).
%  Compressed data is not supported by this program.
%
%  Created on 5-APR-2007 by Jimmy Shen (jimmy@rotman-baycrest.on.ca)
%
%  Modify on 31-JUL-2007 by Julio Cruz (julio.cruz@juliocruz.info) to
%	make the program also work on MAC OS.
%
%  Modify on 01-MAY-2008 by Antonio Molins (amolins@mit.edu) to
%	make the program work with files recorded in Biopac student data
%	acquisition system. Changes include:
%	- added reading of markers, with "markers" field included in
%	returned structure..
%	- proper handling of foreign data (was not getting quite there with
%	the code (as it was downloaded from MathWorks).
%	- proper handling of var_sampling_rate = 0, as produced by the
%	Biopac software in occasions.
%
function acq = load_acq(filename, chan_by_chan)

   if ~exist('chan_by_chan','var')
      chan_by_chan = 1;
   end

   if ~exist('filename','var')
      error('Usage: acq = load_acq(filename)');
   end

   if ~exist(filename,'file')
      error([filename, ': Can''t open file']);
   end

   fid = fopen(filename,'r', 'l');

   if fid < 0,
      msg = sprintf('Cannot open file %s.',filename);
      error(msg);
   end

   fread(fid, 1, 'int16')';
   file_version = fread(fid, 1, 'int32')';

   %  try different endian
   %
   if file_version < 0 | file_version > 200
      fclose(fid);
      fid = fopen(filename,'r', 'b');

      fread(fid, 1, 'int16')';
      file_version = fread(fid, 1, 'int32')';
      fseek(fid, 0, 'bof');

      if file_version < 0 | file_version > 200
         error('This ACQ file is not supported');
      end
   end

   fprintf('Loading %s ', filename);

   %  read header
   %
   acq.hdr = read_acq_hdr(fid);

   %  read data
   %
   acq.data = read_acq(fid, acq.hdr, chan_by_chan);

   %  read markers written by AM (Antonio Molins) for ACQ 3
   %
   if file_version < 68
      acq.markers = read_markers(fid, acq.hdr, size(acq.data));
   end

   fclose(fid);

   fprintf(' Done!\n');

   return;					% load_acq

%---------------------------------------------------------------------
function hdr = read_acq_hdr(fid)

   fseek(fid, 0, 'bof');
   hdr.graph = graph(fid);
   acc_chan_header_len = 0;

   for i = 1:hdr.graph.num_channels
      fseek(fid, hdr.graph.ext_item_header_len+acc_chan_header_len, 'bof');
      hdr.per_chan_data(i) = per_chan_data(fid, hdr.graph.file_version);
      acc_chan_header_len = acc_chan_header_len + hdr.per_chan_data(i).chan_header_len;
   end

   % added by AM: foreign data section was being started to read one short,
   % this fseek takes care of that
   fseek(fid, hdr.graph.ext_item_header_len+acc_chan_header_len, 'bof');

   hdr.foreign = foreign(fid, hdr.graph.file_version);

   if hdr.graph.file_version >= 68 & hdr.graph.file_version < 80
      unused = fread(fid, hdr.foreign.length2-12, 'uint8')';
   end

   for i = 1:hdr.graph.num_channels
      hdr.per_chan_type(i) = per_chan_type(fid);
   end

   return;					% read_acq_hdr

%---------------------------------------------------------------------
function hdr = graph(fid, file_version)

   %  Struct						% off + size
   unused = fread(fid, 1, 'int16')';			% 0 + 2
   hdr.file_version = fread(fid, 1, 'int32');		% 2 + 4
   hdr.ext_item_header_len = fread(fid, 1, 'int32');	% 6 + 4
   hdr.num_channels = fread(fid, 1, 'int16');		% 10 + 2
   hdr.horiz_axis_type = fread(fid, 1, 'int16');	% 12 + 2
   hdr.curr_channel = fread(fid, 1, 'int16');		% 14 + 2
   hdr.sample_time = fread(fid, 1, 'double');		% 16 + 8
   hdr.time_offset = fread(fid, 1, 'double');		% 24 + 8
   hdr.time_scale = fread(fid, 1, 'double');		% 32 + 8
   hdr.time_cursor1 = fread(fid, 1, 'double');		% 40 + 8
   hdr.time_cursor2 = fread(fid, 1, 'double');		% 48 + 8
   hdr.chart_window = fread(fid, 4, 'int16');		% 56 + 8
   hdr.measurement = fread(fid, 6, 'int16');		% 64 + 12
   hdr.hilite = fread(fid, 1, 'int16');			% 76 + 2
   hdr.first_time_offset = fread(fid, 1, 'double');	% 78 + 8
   hdr.rescale = fread(fid, 1, 'int16');		% 86 + 2
   hdr.horiz_units1 = deblank(fread(fid, 40, '*char')'); % 88 + 40
   hdr.horiz_units2 = deblank(fread(fid, 10, '*char')'); % 128 + 10
   hdr.in_memory = fread(fid, 1, 'int16');		% 138 + 2
   hdr.grid = fread(fid, 1, 'int16');			% 140 + 2
   hdr.markers = fread(fid, 1, 'int16');		% 142 + 2
   hdr.plot_draft = fread(fid, 1, 'int16');		% 144 + 2
   hdr.display_mode = fread(fid, 1, 'int16');		% 146 + 2
   hdr.reserved = fread(fid, 1, 'int16');		% 148 + 2

   if hdr.file_version > 33 & hdr.file_version < 68
      hdr.show_toolbar = fread(fid, 1, 'int16');	% 150 + 2
      hdr.show_chan_butt = fread(fid, 1, 'int16');	% 152 + 2
      hdr.show_measurement = fread(fid, 1, 'int16');	% 154 + 2
      hdr.show_marker = fread(fid, 1, 'int16');		% 156 + 2
      hdr.show_journal = fread(fid, 1, 'int16');	% 158 + 2
      hdr.cur_x_channel = fread(fid, 1, 'int16');	% 160 + 2
      hdr.mmt_precision = fread(fid, 1, 'int16');	% 162 + 2
   end

   if hdr.file_version > 34 & hdr.file_version < 68
      hdr.measurement_row = fread(fid, 1, 'int16');	% 164 + 2
      hdr.mmt = fread(fid, 40, 'int16');		% 166 + 80
      hdr.mmt_chan = fread(fid, 40, 'int16');		% 246 + 80
   end

   if hdr.file_version > 35 & hdr.file_version < 68
      hdr.mmt_calc_opnd1 = fread(fid, 40, 'int16');	% 326 + 80
      hdr.mmt_calc_opnd2 = fread(fid, 40, 'int16');	% 406 + 80
      hdr.mmt_calc_op = fread(fid, 40, 'int16');	% 486 + 80
      hdr.mmt_calc_constant = fread(fid, 40, 'double');	% 566 + 320
   end

   if hdr.file_version > 37 & hdr.file_version < 68
      hdr.new_grid_minor = fread(fid, 1, 'int32');	% 886 + 4
      hdr.color_major_grid = fread(fid, 1, 'int32');	% 890 + 4
      hdr.color_minor_grid = fread(fid, 1, 'int32');	% 894 + 4
      hdr.major_grid_style = fread(fid, 1, 'int16');	% 898 + 2
      hdr.minor_grid_style = fread(fid, 1, 'int16');	% 900 + 2
      hdr.major_grid_width = fread(fid, 1, 'int16');	% 902 + 2
      hdr.minor_grid_width = fread(fid, 1, 'int16');	% 904 + 2
      hdr.fixed_units_div = fread(fid, 1, 'int32');	% 906 + 4
      hdr.mid_range_show = fread(fid, 1, 'int32');	% 910 + 4
      hdr.start_middle_point = fread(fid, 1, 'double');	% 914 + 8
      hdr.offset_point = fread(fid, 60, 'double');	% 922 + 480
      hdr.h_grid = fread(fid, 1, 'double');		% 1402 + 8
      hdr.v_grid = fread(fid, 60, 'double');		% 1410 + 480
      hdr.enable_wave_tool = fread(fid, 1, 'int32');	% 1890 + 4

      %  interpret color_major_grid
      %
      color_str = sprintf('%06s', dec2hex(hdr.color_major_grid));
      hdr.color_major_grid = ...
         [hex2dec(color_str(5:6)) hex2dec(color_str(3:4)) hex2dec(color_str(1:2))]/255;

      %  interpret color_minor_grid
      %
      color_str = sprintf('%06s', dec2hex(hdr.color_minor_grid));
      hdr.color_minor_grid = ...
         [hex2dec(color_str(5:6)) hex2dec(color_str(3:4)) hex2dec(color_str(1:2))]/255;

   end

   if hdr.file_version > 38 & hdr.file_version < 68
      hdr.horiz_precision = fread(fid, 1, 'int16');	% 1894 + 2
   end

   if hdr.file_version > 40 & hdr.file_version < 68
      hdr.reserved2 = fread(fid, 20, 'int8');		% 1896 + 20
      hdr.overlap_mode = fread(fid, 1, 'int32');	% 1916 + 4
      hdr.show_hardware = fread(fid, 1, 'int32');	% 1920 + 4
      hdr.x_auto_plot = fread(fid, 1, 'int32');	% 1924 + 4
      hdr.x_auto_scroll = fread(fid, 1, 'int32');	% 1928 + 4
      hdr.start_butt_visible = fread(fid, 1, 'int32');	% 1932 + 4
      hdr.compressed = fread(fid, 1, 'int32');		% 1936 + 4
      hdr.always_start_butt_visible = fread(fid, 1, 'int32');	% 1940 + 4
   end

   if hdr.file_version > 42 & hdr.file_version < 68
      hdr.path_video = deblank(fread(fid, 260, '*char')'); % 1944 + 260
      hdr.opt_sync_delay = fread(fid, 1, 'int32');	% 2204 + 4
      hdr.sync_delay = fread(fid, 1, 'double');		% 2208 + 8
      hdr.hrp_paste_measurement = fread(fid, 1, 'int32'); % 2216 + 4
   end

   if hdr.file_version > 44 & hdr.file_version < 68
      hdr.graph_type = fread(fid, 1, 'int32');		% 2220 + 4
      hdr.mmt_calc_expr = fread(fid, [40 256], '*char'); % 2224 + 10240
      hdr.mmt_moment_order = fread(fid, 40, 'int32');	% 12464 + 160
      hdr.mmt_time_delay = fread(fid, 40, 'int32');	% 12624 + 160
      hdr.mmt_embed_dim = fread(fid, 40, 'int32');	% 12784 + 160
      hdr.mmt_mi_delay = fread(fid, 40, 'int32');	% 12944 + 160
   end

   if hdr.file_version >= 68
      unused = fread(fid, 411, 'int16')';		% 150 + 822
      hdr.compressed = fread(fid, 1, 'int32');		% 972 + 4
   end

   return;						% graph

%---------------------------------------------------------------------
function hdr = per_chan_data(fid, file_version)

   %  Struct						% off + size
   hdr.chan_header_len = fread(fid, 1, 'int32')';	% 0 + 4
   hdr.num = fread(fid, 1, 'int16')';			% 4 + 2
   hdr.comment_text = deblank(fread(fid, 40, '*char')'); % 6 + 40
   hdr.rgb_color = fread(fid, 1, 'int32')';		% 46 + 4
   hdr.disp_chan = fread(fid, 1, 'int16')';		% 50 + 2
   hdr.volt_offset = fread(fid, 1, 'double')';		% 52 + 8
   hdr.volt_scale = fread(fid, 1, 'double')';		% 60 + 8
   hdr.units_text = deblank(fread(fid, 20, '*char')');	% 68 + 20
   hdr.buf_length = fread(fid, 1, 'int32')';		% 88 + 4
   hdr.ampl_scale = fread(fid, 1, 'double')';		% 92 + 8
   hdr.ampl_offset = fread(fid, 1, 'double')';		% 100 + 8
   hdr.chan_order = fread(fid, 1, 'int16')';		% 108 + 2
   hdr.disp_size = fread(fid, 1, 'int16')';		% 110 + 2

   if file_version >= 68

      unused = fread(fid, 5, 'double')';		% 112 + 40
      hdr.var_sample_divider = fread(fid, 1, 'int16')'; % 152 + 2

      % FIX according to comments on fileexchange
      hdr.var_sample_divider = 1;

   else

   hdr.plot_mode = fread(fid, 1, 'int16')';		% 112 + 2
   hdr.mid = fread(fid, 1, 'double')';			% 114 + 8

   %  interpret rbg_color
   %
   color_str = sprintf('%06s', dec2hex(hdr.rgb_color));
   hdr.rgb_color = ...
      [hex2dec(color_str(5:6)) hex2dec(color_str(3:4)) hex2dec(color_str(1:2))]/255;

   if file_version > 37
      hdr.description = deblank(fread(fid, 128, '*char')'); % 122 + 128
      hdr.var_sample_divider = fread(fid, 1, 'int16')'; % 250 + 2

      % AM does not make sense to have a zero divider, set those to 1. No
      % warranties this is standard, but .ACQ files generated with biopac
      % programs produce files with var_sample_divider = 0 although this is
      % not documented. This fix works for the files seen so far.
      if hdr.var_sample_divider==0
          hdr.var_sample_divider = 1;
      end
   else
      hdr.var_sample_divider = 1;
   end

   if file_version > 38
      hdr.vert_precision = fread(fid, 1, 'int16')';	% 252 + 2
   end

   if file_version > 42
      hdr.active_seg_color = fread(fid, 1, 'int32')';	% 254 + 4
      hdr.active_seg_style = fread(fid, 1, 'int32')';	% 258 + 4

      %  interpret active_seg_color
      %
      color_str = sprintf('%06s', dec2hex(hdr.active_seg_color));
      hdr.active_seg_color = ...
         [hex2dec(color_str(5:6)) hex2dec(color_str(3:4)) hex2dec(color_str(1:2))]/255;
   end

   end						% if file_version < 68

   return;						% per_chan_data

%---------------------------------------------------------------------
function hdr = foreign(fid, file_version)

   %  Struct						% off + size
   hdr.length = fread(fid, 1, 'short')';		% 0 + 2
   hdr.id = fread(fid, 1, 'short')';			% 2 + 2

   if file_version < 68
      hdr.by_foreign_data = fread(fid, hdr.length-4, 'int8')'; % 4 + x
      hdr.length2 = hdr.length;
   elseif file_version < 80
      unused = fread(fid, 1, 'int32')';			% 4 + 4
      hdr.length2 = fread(fid, 1, 'int32')' + 8;	% 8 + 4
   else
      unused = fread(fid, 1, 'int32')';			% 4 + 4
      hdr.length2 = hdr.length + 8;
   end

   return;						% foreign

%---------------------------------------------------------------------
function hdr = per_chan_type(fid)

   %  Struct						% off + size
   hdr.size = fread(fid, 1, 'short')';			% 0 + 2
   hdr.type = fread(fid, 1, 'short')';			% 2 + 2

   return;						% per_chan_type

%---------------------------------------------------------------------
function data = read_acq(fid, hdr, chan_by_chan)

   start_real_chan = hdr.graph.ext_item_header_len;

   for i = 1:hdr.graph.num_channels
      start_real_chan = start_real_chan + hdr.per_chan_data(i).chan_header_len;

      if hdr.per_chan_type(i).type ~= 1			% if integer
         hdr.per_chan_type(i).size = 2;			% only use int16
      end
   end

   start_real_chan = start_real_chan + hdr.foreign.length2 + 4*hdr.graph.num_channels;

   sample_divider = [hdr.per_chan_data.var_sample_divider];

   if length(unique(sample_divider))==1 & unique(sample_divider)==1
      min_len = min([hdr.per_chan_data.buf_length]);
   else
      min_len = min([hdr.per_chan_data.buf_length].*sample_divider);
   end

   if length(unique([hdr.per_chan_type.type])) & ~chan_by_chan & ...
	length(unique(sample_divider))==1 & unique(sample_divider)==1

      half_chan = round(hdr.graph.num_channels/2);

      for i = 1:half_chan
         fprintf('.');
      end

      if hdr.per_chan_type(i).type == 1			% double

         data=fread(fid,[hdr.graph.num_channels min_len],'double');
         data=data';
      else						% int

         data=fread(fid,[hdr.graph.num_channels min_len],'int16');
         data=data'.*(ones(min_len,1)*[hdr.per_chan_data.ampl_scale]) ...
		    + ones(min_len,1)*[hdr.per_chan_data.ampl_offset];
      end

      for i = 1:(hdr.graph.num_channels-half_chan)
         fprintf('.');
      end

   else				% if we have to do it chan_by_chan

      if length(unique(sample_divider))==1 & unique(sample_divider)==1

         %  Since data are arranged like: "channel in sample"
         %  { s1 of {ch1 ch2 ...}, s2 of {ch1 ch2 ...} ... }
         %  We can either read data sample by sample (all chan at once),
         %  or, channel by channel, but need to skip the rest of chan
         %
         size_all_chan_per_sample = 0;

         for i = 1:hdr.graph.num_channels
            size_all_chan_per_sample = size_all_chan_per_sample + ...
					hdr.per_chan_type(i).size;
         end

         for i = 1:hdr.graph.num_channels

            fprintf('.');
            fseek(fid, start_real_chan, 'bof');

            %  First jump to the start point of the right channel
            %
            start_chan = 0;

            for j = 1 : (i-1)
               start_chan = start_chan + hdr.per_chan_type(j).size;
            end

            fseek(fid, start_chan, 'cof');

            %  Need to skip the rest of chan, in order to read each sample point
            %
            skip_chan = size_all_chan_per_sample - hdr.per_chan_type(i).size;

            if hdr.per_chan_type(i).type == 1		% double

               tmp=fread(fid,hdr.per_chan_data(i).buf_length,'double',skip_chan);

            else					% int

               %  Need to be scaled & shifted by ampl_scale & ampl_offset
               %  for integer data
               %
               tmp=fread(fid,hdr.per_chan_data(i).buf_length,'int16',skip_chan) ...
			* hdr.per_chan_data(i).ampl_scale ...
			+ hdr.per_chan_data(i).ampl_offset;
            end

            data(:,i) = tmp(1:min_len);
         end

      else				% sample_divider>1 or different

         %  If there is a sample_divider>1 in any channel, we have to
         %  read data sample by sample (very slow!)
         %
         data = zeros(min_len, hdr.graph.num_channels);
         mask=zeros(min_len, hdr.graph.num_channels);
         sample_divider = abs(sample_divider);

         for j = 1:hdr.graph.num_channels
            mask(1:sample_divider(j):min_len, j)=1;
         end

         for i = 1:min_len

            if mod(i-1, ceil(min_len/hdr.graph.num_channels))==0
               fprintf('.');
            end

            for j = 1:hdr.graph.num_channels
               if mask(i,j) | sample_divider(j)==1
                  if hdr.per_chan_type(j).type == 1		% double
                     data(i,j) = fread(fid,1,'double');
                  else
                     data(i,j) = fread(fid,1,'int16');		% int

                     %  Need to be scaled & shifted by ampl_scale & ampl_offset
                     %  for integer data
                     %
                     data(i,j) = data(i,j) * hdr.per_chan_data(j).ampl_scale ...
					+ hdr.per_chan_data(j).ampl_offset;
                  end
               else
                  data(i,j) = data(i-1,j);
               end		% if mask ... read sample_divider

            end		% for j
         end		% for i

      end	% if length(unique(sample_divider
   end	% length(unique([hdr.per_chan_type.type

   return;					% read_acq

 %---------------------------------------------------------------------
 function info = read_markers(fid, hdr, data_size)

     % AM foolproof way of getting to the markers: see where data starts and
     % add the size of the data..

     start_real_chan = hdr.graph.ext_item_header_len;

     for i = 1:hdr.graph.num_channels
         start_real_chan = start_real_chan + hdr.per_chan_data(i).chan_header_len;

         if hdr.per_chan_type(i).type ~= 1			% if integer
             hdr.per_chan_type(i).size = 2;			% only use int16
         end
     end

     start_real_chan = start_real_chan + hdr.foreign.length2 + 4*hdr.graph.num_channels;

     size_channel_data = sum([hdr.per_chan_type.size])*data_size(1);
     start_markers = start_real_chan + size_channel_data;

     % AM place the file position in the position where data ends
     fseek(fid,start_markers,'bof');

     % AM then follow specifications; borrowed from code of the
     % non-functioning (at least for me) ACQREAD,
     %    ACQREAD, version 2.0 (2007-08-21)
     %    Copyright (C) 2006-2007  Sebastien Authier and Vincent Finnerty

     info.lLength = fread(fid,1,'*int32');
     info.lMarkers = fread(fid,1,'*int32');		% Number of markers
     if (info.lLength > 0) & (info.lMarkers > 0)
         for n = 1:double(info.lMarkers)
             info.lSample(n) = fread(fid,1,'*int32');	% Location of marker
             info.fSelected(n) = fread(fid,1,'*int16');
             info.fTextLocked(n) = fread(fid,1,'*int16');
             info.fPositionLocked(n) = fread(fid,1,'*int16');
             info.nTextLength(n) = fread(fid,1,'*int16');  % Length of marker text string
             info.szText{n} = deblank(fread(fid,double(info.nTextLength(n))+1,'*char')');  % Marker text string
         end
     else
         info.lSample = [];
         info.fSelected = [];
         info.fTextLocked = [];
         info.fPositionLocked = [];
         info.nTextLength = [];
         info.szText = [];
     end

     return;


function valid = is_valid_handle(hObj)
% valid = is_valid_handle(hObj) or is_valid_handle('get_new_init_key')
%   Check if a handle is valid (has the right data type and init_key matches)
%   Use is_valid_handle('get_new_init_key') to get new init_key from C++;

% a handle is a struct array with the following fields
%   (uint64) ptr      : the pointer to the C++ object
%   (double) init_key : caffe initialization key

persistent init_key;
if isempty(init_key)
  init_key = caffe_('get_init_key');
end

% is_valid_handle('get_new_init_key') to get new init_key from C++;
if ischar(hObj) && strcmp(hObj, 'get_new_init_key')
  init_key = caffe_('get_init_key');
  return
else
  % check whether data types are correct and init_key matches
  valid = isstruct(hObj) ...
    && isscalar(hObj.ptr) && isa(hObj.ptr, 'uint64') ...
    && isscalar(hObj.init_key) && isa(hObj.init_key, 'double') ...
    && hObj.init_key == init_key;
end

end


trx = Trx('trxfilestr','trx.mat',...
                        'moviefilestr','movie.mov',...
                        'perframedir','perframe',...
                        'default_landmark_params',landmark_params,...
                        'perframe_params',perframe_params);
trx.AddExpDir(expdir);

% clean this data to force computation
if forcecompute,
  %deletefns = setdiff(perframefns,Trx.TrajectoryFieldNames());
  trx.CleanPerFrameData();
end

% compute each
for i = 1:nfns,
  fn = perframefns{i};
  fprintf(logfid,'Computing %s...\n',fn);
  trx.(fn);
end


function [ output_struct ] = parsesubapertureinputs( varargin )
%PARSESUBAPERTUREINPUTS Parse input arguments for subaperture processing
%
% Used in both in-memory and in-file version of subaperture processing
%
% Written by: Wade Schwartzkopf
%
% //////////////////////////////////////////
% /// CLASSIFICATION: UNCLASSIFIED       ///
% //////////////////////////////////////////

p = inputParser;
p.KeepUnmatched=true;
p.addParamValue('frames', 7, @(x) isscalar(x)&&(x>=2)&&(mod(x,1)==0));
p.addParamValue('apfraction', 0.25, @(x) isscalar(x)&&(x<1)&&(x>0));
p.addParamValue('method', 'normal', @(x) any(strcmpi(x,{'minimal', 'normal','fullpixel'})));
p.addParamValue('platformdir', 'right', @(x)any(strcmpi(x,{'right','left'})));
p.addParamValue('dim', 1, @(x) isequal(x,1)||isequal(x,2));
p.addParamValue('fill', 1, @(x) isscalar(x)&&(x>=1));
p.FunctionName = 'SUBAPERTURE';
p.parse(varargin{:});

output_struct=p.Results;
output_struct.reverse_frames=(output_struct.dim==1)&&strcmp(output_struct.platformdir, 'right');

end

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


function compareMetaboliteFormulae(modelT)
% Prints out a tab delimited file with the abbreviations, reconstruction
% metabolite formluae, and group contribution metabolite formulae.
%
% USAGE:
%
%    compareMetaboliteFormulae(modelT)
%
% INPUT:
%    modelT:    output of `setupThermoModel`

fid=fopen('metaboliteFormulae.txt','w');

[nMet,nRxn]=size(modelT.S);

for m=1:nMet
    fprintf(fid,'%20s%20s\t%20s\n',modelT.mets{m},modelT.metFormulas{m},modelT.met(m).formulaMarvin);
end
fclose(fid);


function [boxes, scores, num_candidates] = read_candidates_mat(dirname, img_id, subdirlen, coco)
  if nargin < 3
    subdirlen = 4;
  end
  if nargin < 4
    coco = false;
  end

  if coco
    subdirlen1 = 14;
    subdir1 = img_id(1:subdirlen1);
    subdirlen2 = 22;
    subdir2 = img_id(1:subdirlen2);
    subdir = fullfile(subdir1, subdir2);
  else
    subdir = img_id(1:subdirlen);
  end
  matfile = fullfile(dirname, subdir, sprintf('%s.mat', img_id));

  % default value
  num_candidates = 10000;

  load(matfile);
end


function gomakegr() % autogenerated function wrapper
    % This M-file displays a message, then calls makegrid to produce a grid and
    % calculate Cumulative Number curves.
    % turned into function by Celso G Reyes 2017

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

    clf
    set(gca,'visible','off');
    gh = gcf;

    txt4  = text(...
        'Position',[0.0 0.65 0 ],...
        'FontSize',ZmapGlobal.Data.fontsz.m ,...
        'FontWeight','bold',...
        'String', 'Please wait until cursor changes to a CROSS');

    txt4B = text(...
        'Position',[0.0 0.58 0 ],...
        'FontSize',ZmapGlobal.Data.fontsz.m ,...
        'FontWeight','bold',...
        'String', 'and select the edges of a polygon    ');
    txt4 = text(...
        'Position',[0.0 0.51 0 ],...
        'FontSize',ZmapGlobal.Data.fontsz.m ,...
        'FontWeight','bold',...
        'String', 'on the map (using the left mouse buton).');
    txt4B  = text(...
        'Position',[0.0 0.36 0 ],...
        'FontSize',ZmapGlobal.Data.fontsz.m ,...
        'FontWeight','bold',...
        'String', 'Mac Users: Use the character "p" on your      ');
    txt4  = text(...
        'Position',[0.0 0.29 0 ],...
        'FontSize',ZmapGlobal.Data.fontsz.m ,...
        'FontWeight','bold',...
        'String', 'keyboard. Use the right mouse button to select ');
    txt4B  = text(...
        'Position',[0.0 0.22 0 ],...
        'FontSize',ZmapGlobal.Data.fontsz.m ,...
        'FontWeight','bold',...
        'String', 'the final point (or charcter "l")           ');

    pause(0.1)
    makegrid

end


function kern = cmpndKernExpandParamTransformSettings(kern, paramtransformsettings)

% CMPNDKERNEXPANDPARAMTRANSFORMSETTINGS Create kernel structure from CMPND kernel's parameter transformation settings.
%
% FORMAT
%
% DESC returns a compound kernel structure filled with the
% parameter transformation settings in the given cell array. This
% is used as a helper function to enable parameters to be optimised
% in, for example, the NETLAB optimisation functions.
%
% ARG kern : the kernel structure in which the parameters are to be
% placed.
%
% ARG param : cell array of parameter transformation settings which
% are to be placed in the kernel structure. Each setting needs to
% correspond to the transformations used by the kernel. For
% example, some transformation might need knowledge of the desired
% output range, so the transformation setting could be e.g. [0 100],
% whereas some other transformations might need more complicated
% setting information.
%
% RETURN kern : kernel structure with the given parameter
% transformation settings in the relevant locations.
%
% SEEALSO : cmpndKernParamInit, cmpndKernExtractParam, kernExpandParam
%
% COPYRIGHT : Neil D. Lawrence, 2004, 2005, 2006
%
% COPYRIGHT : Jaakko Peltonen, 2011

% KERN

%fprintf(1,'cmpndKernExpandParamTransformSettings step1\n');

%fprintf(1,'cmpndKernExpandParam, params, kern.paramGroups\n')
%params
%full(kern.paramGroups)

% kern.paramGroups
% paramtransformsettings
% length(paramtransformsettings)
% size(kern.paramGroups,2)

% There should be as many transformation settings provided as there
% are shared parameters in the compound kernel.
if length(paramtransformsettings)~=size(kern.paramGroups,2),
  error(sprintf('Problem in cmpndKernExpandParamTransformSettings: expected %d transformation-settings, received %d\n',size(kern.paramGroups,2),length(paramtransformsettings)));
end;

%fprintf(1,'cmpndKernExpandParamTransformSettings step1b\n');
%pause

% In a compound (cmpnd) kernel, some parameters may be shared
% between groups. Each provided transformation-setting is
% assumed to be specific to a single shared parameter, so
% the transformation-setting has to be duplicated for each group
% using that shared parameter.

expandedsettings=cell(size(kern.paramGroups,1),1);

%fprintf(1,'cmpndKernExpandParamTransformSettings step1b2\n');

for k=1:length(expandedsettings),
  %fprintf(1,'cmpndKernExpandParamTransformSettings step1b3\n');
  % Find the shared parameter that correspond to the k:th non-shared parameter
  k2=find(kern.paramGroups(k,:)==1);

  expandedsettings{k}=paramtransformsettings{k2};
end;

%fprintf(1,'expanding CMPND kernel param-transforms settings:\n');
%paramtransformsettings
%expandedsettings
%pause

%fprintf(1,'cmpndKernExpandParamTransformSettings step2\n');

% Distribute each group of transformation-settings into the
% corresponding component-kernel of the compound kernel.
startVal = 1;
endVal = 0;
for i = 1:length(kern.comp)
  % Each component-kernel is assumed to require as many transformation
  % settings as it has parameters.
  endVal = endVal + kern.comp{i}.nParams;
  %fprintf(1,'cmpndKernExpandParamTransformSettings step3\n');
  kern.comp{i} = kernExpandParamTransformSettings(kern.comp{i}, expandedsettings(startVal:endVal));
  %fprintf(1,'cmpndKernExpandParamTransformSettings step4\n');
  startVal = endVal + 1;
end

%fprintf(1,'cmpndKernExpandParamTransformSettings done\n');


function [su_hdr,ex_hdr,se_hdr,im_hdr,pix_hdr,im_offset] = GE_readHeader(IFileName)
%
% [su_hdr,ex_hdr,se_hdr,im_hdr,pix_hdr,im_offset] = GE_readHeader(IFileName)
% Reads the header info from a GE lx2 or 5.X file
%
%
% Souheil J. Inati
% Dartmouth College
% May 2000
% souheil.inati@dartmouth.edu
%

%%%% Open the IFile %%%%%
[fid,message] = fopen(IFileName,'r','b');         %note: 'b' = Big-Endian format
if fid == -1
  error(message)
end

% Check for the magic number at the first word
magic = fread(fid,1,'int32');
if magic == 1229801286
  % This is a 5.X format image
  byte_align = 0;
  pix_hdr_offset = 0;
  su_hdr_size = 114;
  ex_hdr_size = 1024;
  se_hdr_size = 1020;
  im_hdr_size = 1022;
else
  % Magic no. not at the 1st word, try at the LX2 position
  fseek(fid,3228,-1);
  magic = fread(fid,1,'int32');
  if magic == 1229801286
    % This is an LX2 format image
    byte_align = 1;
    pix_hdr_offset = 3228;
    su_hdr_size = 116;
    ex_hdr_size = 1040;
    se_hdr_size = 1028;
    im_hdr_size = 1044;
  else
    msg = 'This is not a 5.X or LX2 format image.  No Magic Number.';
    error(msg);
  end
end

% Load the pixel header
fseek(fid,pix_hdr_offset,-1);
pix_hdr = GE_readHeaderPixel(fid, byte_align);

% Compute the offsets
su_hdr_offset = pix_hdr.img_p_dbHdr;
ex_hdr_offset = su_hdr_offset + su_hdr_size;
se_hdr_offset = ex_hdr_offset + ex_hdr_size;
im_hdr_offset = se_hdr_offset + se_hdr_size;
im_offset = pix_hdr_offset + pix_hdr.img_hdr_length;

% Check for epirecon images
if (pix_hdr.img_l_dbHdr == 0 & byte_align==0)
  error('This is a epirecon image. No header')
end

% Load the suite header
fseek(fid,su_hdr_offset,-1);
su_hdr = GE_readHeaderSuite(fid, byte_align);

% Load the exam header
fseek(fid,ex_hdr_offset,-1);
ex_hdr = GE_readHeaderExam(fid, byte_align);

% Load the series header
fseek(fid,se_hdr_offset,-1);
se_hdr = GE_readHeaderSeries(fid, byte_align);

% Load the image header
fseek(fid,im_hdr_offset,-1);
im_hdr = GE_readHeaderImage(fid, byte_align);

% Close the file
fclose(fid);

return


function fileList = resortFileOrder(fileList)
% this patches the file ordering for matlab, ie. to take into account the re-sorting of length wise as well
% fileList = char(fileList);

sortedT = sort(fileList);

for i = 1:length(sortedT)
   lengthOfEachString(i) = length(char(sortedT(i))) ;
end

sortByLength = sort(lengthOfEachString);

% remove repeated numbers
arrayOfIndices = sortByLength;
uniqueNumbers = unique(arrayOfIndices);
sortByLength = uniqueNumbers;

numberOfGroups = length(sortByLength);

for i = 1:numberOfGroups
   indexToCheckFor = find(sortByLength(i) == lengthOfEachString);
   sortedWithLengthTakenCare{i} = char(sortedT(indexToCheckFor));
end

sortedIndex = [];
% append the clustered list
for i = 1:numberOfGroups
   % fprintf('%s \n', sortedWithLengthTakenCare{i});

   numberOfItemPerCluster = size(sortedWithLengthTakenCare{i}, 1);

   clusterToBeAddressed = cellstr(sortedWithLengthTakenCare{i});

   for j=1:numberOfItemPerCluster
       sortedIndex = [sortedIndex, '', clusterToBeAddressed(j)];
   end
   % sortedIndex = [sortedIndex sortedWithLengthTakenCare{i}];
end

fileList = char(sortedIndex);

end

%{
clc;
clear all;

targetFolder = 'repositoryArchive';
imageFileType = '.jpg';

[imageFileNames, imageFileCount] = listFilesInDirectory( targetFolder, imageFileType );

for i = 1:imageFileCount
    imageChoiceIndex = i;
    imageFileAddressed = cell2str(imageFileNames(imageChoiceIndex));
    % remove '{' and '}'
    imageFileAddressed = regexprep(imageFileAddressed, '{', '');
    imageFileAddressed = regexprep(imageFileAddressed, '}', '');
    imageFileAddressed = regexprep(imageFileAddressed,'''', ''); % remove character '

    numberIndex(i) = str2num(extractNumberIndexFromFileName(imageFileAddressed));
end

sortedFileOrder = sort(numberIndex, 'ascend');

% depicts the file picked in order

for i = 1:imageFileCount
    addressedFile(i) = find (sortedFileOrder(i) == numberIndex);
end
%}


function removeDataType(dataTypeName, queryFlag);
%
%     removeDataType(dataTypeName,[queryFlag=1]);
%
% Remove a dataType from mrSESSION and updates open views appropriately.
% This routine depends on dataTYPES being a global variable.
%
% See also: removeDataTypeByIndex
%
% djh, 3/2001
% dar, 3/2007 - added queryflag (default = 1) to pass to saveSession &
% cleanSession - default loads a dialoge asking if you want to overwrite /
% delete.
mrGlobals
if strcmp(dataTypeName,'Original')
    error('removeDataType: Cannot remove original dataType.\n');
end
if ~exist('queryFlag','var')
    queryFlag=1;
end
dataTypeNum = existDataType(dataTypeName);

% if query flag is 1, ask the user: and DON'T DELETE THE DATA
% TYPE if the user says 'no'.
if queryFlag==1
	q = sprintf('Completely delete data type %s?', dataTypeName);
    confirm = questdlg(q, mfilename);
	if ~isequal(confirm, 'Yes')
		fprintf('[%s]: Aborted removal.', mfilename);
		return
	end
end

% If the dataType exists, (1) remove it from mrSESSION, (2) remove it from the
% popup menu options, (3) adjust the value of the curDataType
% and (4) check whether or not to delete the corresponding subdirectories
if dataTypeNum
    % Adjust the mrSESSION structure
    fprintf('removeDataType: removing %s dataType\n',dataTypeName);
    other = setdiff(1:length(dataTYPES),dataTypeNum);
    dataTYPES = dataTYPES(other);

    saveSession;

    if dataTypeNum > 1 % should always happen, except unusual circumstances
        dataTypeNum = dataTypeNum - 1;
    end

    % Delete all the data files for this dataType
    cleanDataType(dataTypeName, 0);

    % Loop through the open views, switch their curDataType appropriately,
    % and update the dataType popups
    INPLANE = resetDataTypes(INPLANE, dataTypeNum);
    VOLUME = resetDataTypes(VOLUME, dataTypeNum);
    FLAT = resetDataTypes(FLAT, dataTypeNum);

	% ras 02/07: check if a mrVista2 session is open (this shouldn't
	% break anything if the toolbox is not installed)
	global GUI;
	if ~isempty(GUI), try, sessionGUI_selectDataType(dataTypeNum); end; end
else
    fprintf('removeDataType: %s dataType not found.\n',dataTypeName);
end
return;


function ResampledFiberGroup=dtiResampleFiberGroup(fg, value, flag)
%ResampledFiberGroup=resampleFibers(fiberGroup, numNodes, 'N')
%ResampledFiberGroup=resampleFibers(fiberGroup, stepSize, 'L')
%Resamples the fibers so that each has number of nodes = value (if flag=='N')
%or to fibers of step size = value (flag=='L')

%ER 02/2008 SCSNL
warning off;

if ~exist('flag', 'var') || isempty(flag)
flag='N';
end

ResampledFiberGroup=fg;

numFibers=size(fg.fibers,1);

for fiberIndex=1:numFibers
ResampledFiberGroup.fibers{fiberIndex}=dtiFiberResample(fg.fibers{fiberIndex}, value, flag);
end
 warning on;


function view=analysisFlatMenu(view)
%
% view=analysisFlatMenu(view)
%
% Set up the callbacks of the ANALYSIS menu for the FLAT view.
%
% wap, 5/18/99
% arp, 052199
%

analysismenu = uimenu('Label','Analysis','separator','on');

% Cortical distance measurement (prompt for user input)
callBackstr=['measureCorticalDistance(' view.name ');'];
uimenu(analysismenu,'Label','Measure cortical distance (select points)','Separator','off',...
    'CallBack',callBackstr);

% Cortical distance measurement (use current ROI)
callBackstr=['measureCorticalDistance(' view.name ', getCurROIcoords(' view.name ') );'];
uimenu(analysismenu,'Label','Measure cortical distance (current ROI)','Separator','off',...
    'CallBack',callBackstr);

% Cortical distance measurement- sub-sampling method (use current line ROI)
callBackstr=['measureCorticalDistanceLineROI(' view.name ', getCurROIcoords(' view.name ') );'];
uimenu(analysismenu,'Label','Measure cortical distance (subsamples ROI)','Separator','off',...
    'CallBack',callBackstr);

% Cortical distance measurement- Binning method (use current line ROI)
callBackstr=['measureCorticalDistanceBins(' view.name ', getCurROIcoords(' view.name ') , 4);'];
uimenu(analysismenu,'Label','Measure cortical distance (bins ROI, binDist=4mm)','Separator','off',...
    'CallBack',callBackstr);

% Cortical distance measurement- Binning method (use current line ROI)
callBackstr=['measureCorticalDistanceBins(' view.name ', getCurROIcoords(' view.name '));'];
uimenu(analysismenu,'Label','Measure cortical distance (bins ROI, specify binDist)','Separator','off',...
    'CallBack',callBackstr);

% Current ROI surface area measurement
callBackstr=['measureFlatROIArea(' view.name ');'];
uimenu(analysismenu,'Label','ROI surface area (old, slow, inaccurate!)','Separator','on',...
    'CallBack',callBackstr);
callBackstr=[ view.name ' = measureFlatROIAreaMesh(' view.name ');'];
uimenu(analysismenu,'Label','ROI surface area (new mesh method)','Separator','off',...
    'CallBack',callBackstr);

%---------Atlas Version 2----------------------------------------------------

% atlasV2 = uimenu(analysismenu,'Label','Atlas (v. 2)','Separator','on');

% view = atlasCreate(atlasName, ringWedgeScans,view);
atlasCreate = uimenu(analysismenu,'Label','Create atlas','Separator','on');

% view = atlasCreate(atlasName, ringWedgeScans,view);
callBackstr = [ '[' view.name ' corners] = atlasCreate(''Hemifield'',[],', view.name ');'];
uimenu(atlasCreate,'Label','Hemifield','Separator','off','CallBack',callBackstr);

% view = atlasCreate(atlasName, ringWedgeScans,view);
callBackstr = [ '[' view.name ' corners] = atlasCreate(''uqf'',[],', view.name ');'];
uimenu(atlasCreate,'Label','upperquarterfield','Separator','off','CallBack',callBackstr);

% view = atlasCreate(atlasName, ringWedgeScans,view);
callBackstr = [ '[' view.name ' corners] = atlasCreate(''lqf'',[],', view.name ');'];
uimenu(atlasCreate,'Label','lowerquarterfield','Separator','off','CallBack',callBackstr);

% view = atlasCreate(atlasName, ringWedgeScans,view);
callBackstr = [ '[' view.name ' corners] = atlasCreate(''HemiLowerVF'',[],', view.name ');'];
uimenu(atlasCreate,'Label','HemiLowerVF','Separator','off','CallBack',callBackstr);

callBackstr = [ '[' view.name ' corners] = atlasCreate(''HemiUpperVF'',[],', view.name ');'];
uimenu(atlasCreate,'Label','HemiUpperVF (V3v/hV4)','Separator','off','CallBack',callBackstr);

% view = atlasCreate(atlasName, ringWedgeScans,view);
callBackstr = [ '[' view.name ' corners] = atlasCreate(''V1/V2'',[],', view.name ');'];
uimenu(atlasCreate,'Label','V1/V2','Separator','off','CallBack',callBackstr);

% view = atlasCreate(atlasName, ringWedgeScans,view);
callBackstr = [ '[' view.name ' corners] = atlasCreate(''V1/V2/V3'',[],', view.name ');'];
uimenu(atlasCreate,'Label','V1/V2/V3','Separator','off','CallBack',callBackstr);

% view = atlasCreate(atlasName, ringWedgeScans,view);
callBackstr = [ '[' view.name ' corners] = atlasCreate(''ventralV2V3V4'',[],', view.name ');'];
uimenu(atlasCreate,'Label','V2v/V3v/V4v','Separator','off','CallBack',callBackstr);

% view = atlasCreate(atlasName, ringWedgeScans,view);
callBackstr = [ '[' view.name ' corners] = atlasCreate(''V4/V8'',[],', view.name ');'];
uimenu(atlasCreate,'Label','V4/V8','Separator','off','CallBack',callBackstr);

% view = atlasCreate(atlasName, ringWedgeScans,view);
callBackstr = [ '[' view.name ' corners] = atlasCreate(''2hemifields'',[],', view.name ');'];
uimenu(atlasCreate,'Label','2 Hemifields (VO1/VO2)','Separator','off','CallBack',callBackstr);

callBackstr = [ '[' view.name ' corners] = atlasCreate(''4 hemifields'',[],', view.name ');'];
uimenu(atlasCreate,'Label','4 Hemifields (LO-1/2, TO-1/2)','Separator','off','CallBack',callBackstr);

%---------------------------------------------------------
% [view images] = makeAtlasData(view,[],[],corners);
callBackstr=[ '[' view.name  ' images] = makeAtlasData(' view.name ');'];
uimenu(analysismenu,'Label','Create data for the fitting GUI','Separator','off','CallBack',callBackstr);

% gui(images);
callBackstr=[ 'atlasfitGUI(images)'];
uimenu(analysismenu,'Label','Open the fitting GUI','Separator','off','CallBack',callBackstr);

% [images2 images3 images]= RawToCommonAtlas(images, corners, '/biac3/wandell4/data/MT/YM070815/safirData_left0706', '/biac3/wandell4/data/MT/YM070815/safirResult_left0706');
callBackstr=['images = loadPRFsize(' view.name ', images); [images images2 images3] = RawToCommonAtlas(images, corners, ''' pwd '/safirData'',''' pwd '/safirResult''); atlasStore(' view.name ',images)'];
uimenu(analysismenu,'Label','Create data type for the fitted atlas','Separator','off','CallBack',callBackstr);

% view = warpFromViews(view);
callBackstr=[ view.name ' = warpFromViews(' view.name ');'];
uimenu(analysismenu,'Label','Warp Atlas (Atlas view)','Separator','on','CallBack',callBackstr);

% Visual area ROI from atlas
% view = makeAreaROI(view);
callBackstr=[ view.name ' = makeAreaROI(' view.name ');'];
uimenu(analysismenu,'Label','Create Area ROI (Data view)','Separator','off','CallBack',callBackstr);

% view= atlasIsoAngleROIs(view);
callBackstr=[ view.name ' = atlasIsoAngleROIs(' view.name ');'];
uimenu(analysismenu,'Label','Iso-angle ROI (Data view)','Separator','off','CallBack',callBackstr);

% view= atlasIsoEccROIs(view);
callBackstr=[ view.name ' = atlasIsoEccROIs(' view.name ');'];
uimenu(analysismenu,'Label','Iso-eccentricity ROI (Data view)','Separator','off','CallBack',callBackstr);

% Atlas Error
callBackstr=[ view.name ' = atlasError(' view.name ');'];
uimenu(analysismenu,'Label','Compute error (data view)','Separator','off',...
    'CallBack',callBackstr);

%--------------------------------------------------------------------------
% Cortical Magnification computation
callBackstr=[ view.name ' = measureCortMag(' view.name ');'];
uimenu(analysismenu, 'Label', 'Compute cortical magnification', 'Separator', 'on',...
    'CallBack', callBackstr);
callBackstr=[ view.name ' = measureCortMag(' view.name ', [], uigetfile);'];
uimenu(analysismenu, 'Label', 'Compute cortMag from file', 'Separator', 'off',...
    'CallBack', callBackstr);

%------------Atlas V. 1 (Old)---------------------------------------------------------
atlasOldmenu = uimenu(analysismenu,'Label','Atlas (v. 1)','Separator','on');
% Create Rectangle ROI with default name callback
%   view=newROI(view);
%   view=addROIrect(view,1);
%   view=refreshScreen(view,1);

% 2-D Atlas fitting
callBackstr=['createAtlas(' view.name ');'];
uimenu(atlasOldmenu,'Label','Create Retinotopy Atlas (data view)','Separator','on',...
    'CallBack',callBackstr);

% 2-D Atlas phase adjustment
callBackstr=[ view.name ' = fixPhase(' view.name ');'];
uimenu(atlasOldmenu,'Label','Fix atlas phase (atlas view)','Separator','off',...
    'CallBack',callBackstr);

% 2-D Atlas affine transform
callBackstr=[ view.name ' = atlasAffineTransform(' view.name ');'];
uimenu(atlasOldmenu,'Label','Affine transform Atlas (atlas view)','Separator','off',...
    'CallBack',callBackstr);

% 2-D Atlas warping
callBackstr=[ view.name ' = warpFromViews(' view.name ');'];
uimenu(atlasOldmenu,'Label','Warp atlas (atlas view)','Separator','off',...
    'CallBack',callBackstr);
% Visual area ROI from atlas
callBackstr=[ view.name ' = makeAreaROI(' view.name ');'];
uimenu(atlasOldmenu,'Label','Create area ROI (data view)','Separator','off',...
    'CallBack',callBackstr);

% Iso-angle ROI from atlas
callBackstr=[ view.name ' = makeIsoAngleROIs(' view.name ');'];
uimenu(atlasOldmenu,'Label','Create iso-angle ROIs (data view)','Separator','off',...
    'CallBack',callBackstr);

% Iso-angle ROI from atlas
callBackstr=[ view.name ' = makeIsoEccenROIs(' view.name ');'];
uimenu(atlasOldmenu,'Label','Create iso-eccentricity ROIs (data view)','Separator','off',...
    'CallBack',callBackstr);

% Atlas Error Map
callBackstr=[ view.name ' = atlasErrorMap(' view.name ');'];
uimenu(atlasOldmenu,'Label','Compute error map (data view)','Separator','off',...
    'CallBack',callBackstr);

return;


%% Define params
s_cam_definitions;

%% Interpolate all data used for camino masks
mkdir(mask_dir);
files_to_interp = {roi_map_filename};%,ecc_map_filename,var_map_filename,seg_filename,t1_filename};
for ff = 1:length(files_to_interp)
    filename = files_to_interp{ff};
    %[foo1, xform_filename, ext, foo2] = fileparts(filename);
    %xform_filename = ['xform_', xform_filename, ext];
    camAlignImageToDTI( fullfile(dti_dir,b0_filename), ...
            fullfile(ret_dir,filename),...
            fullfile(mask_dir,filename));
end

%% Load all reinterpolated data
ni_seg = niftiRead(fullfile(mask_dir,seg_filename));
ni_var = niftiRead(fullfile(mask_dir,var_map_filename));
ni_ecc = niftiRead(fullfile(mask_dir,ecc_map_filename));
ni_rois = niftiRead(fullfile(mask_dir,roi_map_filename));

%% Gray Matter Mask
% RH
ni_gm = ni_seg;
ni_gm.fname = fullfile(mask_dir,'gm_rh.nii.gz');
% Grab only right hemisphere GM
ni_gm.data(ni_seg.data~=6) = 0;
ni_gm.data(ni_gm.data>0) = 1;
% Only GM within occipital lobe
ni_gm.data(:,occ_exit:end,:)=0;
% Write file
writeFileNifti(ni_gm);

% LH
ni_gm = ni_seg;
ni_gm.fname = fullfile(mask_dir,'gm_lh.nii.gz');
% Grab only right hemisphere GM
ni_gm.data(ni_seg.data~=5) = 0;
ni_gm.data(ni_gm.data>0) = 1;
% Only GM within occipital lobe
ni_gm.data(:,occ_exit:end,:)=0;
% Write file
writeFileNifti(ni_gm);

%% Do the White Matter mask
% RH
ni_wm = ni_seg;
ni_wm.fname = fullfile(mask_dir,'wm_rh.nii.gz');
% Initialize
ni_wm.data=zeros(size(ni_seg.data));
% Get the white matter of RH
ni_wm.data(ni_seg.data==4)=1;
% exit plane
ni_wm.data(:,occ_exit+1:end,:)=0;
%write the file
writeFileNifti(ni_wm);

% RH
ni_wm = ni_seg;
ni_wm.fname = fullfile(mask_dir,'wm_lh.nii.gz');
% Initialize
ni_wm.data=zeros(size(ni_seg.data));
% Get the white matter of LH
ni_wm.data(ni_seg.data==3)=1;
% exit plane
ni_wm.data(:,occ_exit+1:end,:)=0;
%write the file
writeFileNifti(ni_wm);

%% Also create med-res white matter mask for seeds
%camAlignImageToDTI( fullfile(dti_dir,b0_filename), fullfile(mask_dir,'wm_rh.nii.gz'), fullfile(mask_dir,'wm_rh_lowres.nii.gz'), [1 1 1]);
%camAlignImageToDTI( fullfile(dti_dir,b0_filename), fullfile(mask_dir,'wm_lh.nii.gz'), fullfile(mask_dir,'wm_lh_lowres.nii.gz'), [1 1 1]);

%% Do the White Matter exit plane
% RH
ni_exit = ni_seg;
ni_exit.fname = fullfile(mask_dir,'wm_rh_exit.nii.gz');
% Initialize
ni_exit.data=zeros(size(ni_seg.data));
% Get the white matter of RH
ni_exit.data(ni_seg.data==4)=1;
% exit plane
ni_exit.data(:,occ_exit+1:end,:)=0;
ni_exit.data(:,1:occ_exit-1,:)=0;
%write the file
writeFileNifti(ni_exit);

% RH
ni_exit = ni_seg;
ni_exit.fname = fullfile(mask_dir,'wm_lh_exit.nii.gz');
% Initialize
ni_exit.data=zeros(size(ni_seg.data));
% Get the white matter of LH
ni_exit.data(ni_seg.data==3)=1;
% exit plane
ni_exit.data(:,occ_exit+1:end,:)=0;
ni_exit.data(:,1:occ_exit-1,:)=0;
%write the file
writeFileNifti(ni_exit);

%% Occ Lobe Mask
% RH
ni_occ = ni_seg;
ni_occ.fname = fullfile(mask_dir,'occ_rh_mask.nii.gz');
ni_gm = niftiRead(fullfile(mask_dir,'gm_rh.nii.gz'));
% Grab only right hemisphere GM and WM
ni_occ.data(ni_seg.data~=6 & ni_seg.data~=4) = 0;
ni_occ.data(ni_occ.data>0) = 1;
% Make sure all the GM voxels are included
ni_occ.data(ni_gm.data>0) = 1;
% Only GM within occipital lobe
ni_occ.data(:,occ_exit+1:end,:)=0;
% Write file
writeFileNifti(ni_occ);

% LH
ni_occ = ni_seg;
ni_occ.fname = fullfile(mask_dir,'occ_lh_mask.nii.gz');
ni_gm = niftiRead(fullfile(mask_dir,'gm_lh.nii.gz'));
% Grab only left hemisphere GM and WM
ni_occ.data(ni_seg.data~=5 & ni_seg.data~=3) = 0;
ni_occ.data(ni_occ.data>0) = 1;
% Make sure all the GM voxels are included
ni_occ.data(ni_gm.data>0) = 1;
% Only GM within occipital lobe
ni_occ.data(:,occ_exit+1:end,:)=0;
% Write file
writeFileNifti(ni_occ);

%% Create a background mask in native diffusion space
%ni_b0 = niftiRead(fullfile(dti_dir,b0_filename));
%lowres_pixdim = ni_b0.pixdim;
%camAlignImageToDTI( fullfile(dti_dir,b0_filename), fullfile(mask_dir,'occ_rh_mask.nii.gz'), fullfile(mask_dir,'bgmask_rh.nii.gz'), lowres_pixdim);
%camAlignImageToDTI( fullfile(dti_dir,b0_filename), fullfile(mask_dir,'occ_lh_mask.nii.gz'), fullfile(mask_dir,'bgmask_lh.nii.gz'), lowres_pixdim);

%% Define outside occ lobe for exclusion purposes
% RH
ni_occ = niftiRead( fullfile(mask_dir,'occ_rh_mask.nii.gz') );
ni_not_occ = niftiRead(fullfile(mask_dir,'occ_rh_mask.nii.gz'));
ni_not_occ.fname = fullfile(mask_dir,'not_occ_rh_mask.nii.gz');
ni_not_occ.data(ni_occ.data==0) = 1;
ni_not_occ.data(ni_occ.data==1) = 0;
writeFileNifti(ni_not_occ);
% LH
ni_occ = niftiRead( fullfile(mask_dir,'occ_lh_mask.nii.gz') );
ni_not_occ = niftiRead(fullfile(mask_dir,'occ_lh_mask.nii.gz'));
ni_not_occ.fname = fullfile(mask_dir,'not_occ_lh_mask.nii.gz');
ni_not_occ.data(ni_occ.data==0) = 1;
ni_not_occ.data(ni_occ.data==1) = 0;
writeFileNifti(ni_not_occ);

%% Image that defines the occipital exit plane and GM as two ROIs
% RH
ni_occ_exit = niftiRead(fullfile(mask_dir,'wm_rh_exit.nii.gz'));
ni_occ_exit.fname = fullfile(mask_dir,'occ_rh_exit.nii.gz');
ni_gm = niftiRead(fullfile(mask_dir,'gm_rh.nii.gz'));
ni_occ_exit.data(ni_gm.data>0) = 2;
writeFileNifti(ni_occ_exit);
% Now the mask
ni_occ_exit_mask = ni_occ_exit;
ni_occ_exit_mask.fname = fullfile(mask_dir,'occ_rh_exit_mask.nii.gz');
ni_occ_exit_mask.data(ni_occ_exit_mask.data>0) = 1;
writeFileNifti(ni_occ_exit_mask);

% LH
ni_occ_exit = niftiRead(fullfile(mask_dir,'wm_lh_exit.nii.gz'));
ni_occ_exit.fname = fullfile(mask_dir,'occ_lh_exit.nii.gz');
ni_gm = niftiRead(fullfile(mask_dir,'gm_lh.nii.gz'));
ni_occ_exit.data(ni_gm.data>0) = 2;
writeFileNifti(ni_occ_exit);
% Now the mask
ni_occ_exit_mask = ni_occ_exit;
ni_occ_exit_mask.fname = fullfile(mask_dir,'occ_lh_exit_mask.nii.gz');
ni_occ_exit_mask.data(ni_occ_exit_mask.data>0) = 1;
writeFileNifti(ni_occ_exit_mask);

%% Create label map, each voxel in GM map has some meaningful number
% Sweep out various variance explained thresholds
var_thresh = 0.1:0.05:0.3;
for vv = var_thresh
    filename = fullfile(mask_dir,sprintf('atlas_%s_%.2f.nii.gz',var_atlas_root,vv));
    data = ni_var.data;
    data(ni_var.data>vv) = 1;
    data(data<1) = 0;
    dtiWriteNiftiWrapper(data,ni_var.qto_xyz,filename);
    filename = fullfile(mask_dir,sprintf('atlas_%s_%s_%.2f.nii.gz',ecc_atlas_root,var_atlas_root,vv));
    ecc = ni_ecc.data;
    ecc = ecc.*data;
    ecc(ecc>0 & ecc<=5) = 5;
    ecc(ecc>50 & ecc<=10) = 10;
    ecc(ecc>10) = 15;
    dtiWriteNiftiWrapper(ecc,ni_var.qto_xyz,filename);
end

% Ventral ROIs
data = zeros(ni_rois.dim);
data_nov1 = zeros(ni_rois.dim);
for ll = roi_ventral_lbls
    data(ni_rois.data==ll) = 1;
    if ll~=1 && ll~=2
        data_nov1(ni_rois.data==ll) = 1;
    end
end
filename = fullfile(mask_dir,sprintf('atlas_%s.nii.gz',roi_ventral_atlas_root));
dtiWriteNiftiWrapper(data,ni_rois.qto_xyz,filename);
filename = fullfile(mask_dir,sprintf('atlas_%s.nii.gz',roi_ventral_nov1_atlas_root));
dtiWriteNiftiWrapper(data_nov1,ni_rois.qto_xyz,filename);
% Ecc Ventral
var = 0.2;
filename = fullfile(mask_dir,sprintf('atlas_%s_%s_%.2f.nii.gz',ecc_atlas_root,var_atlas_root,var));
ecc = niftiRead(filename);
ecc.data(data==0) = 0;
filename = fullfile(mask_dir,sprintf('atlas_%s_%s_%s_%.2f.nii.gz',roi_ventral_atlas_root,ecc_atlas_root,var_atlas_root,var));
dtiWriteNiftiWrapper(ecc.data,ecc.qto_xyz,filename);

% Dorsal ROIs
data = zeros(ni_rois.dim);
data_nov1 = zeros(ni_rois.dim);
for ll = roi_dorsal_lbls
    data(ni_rois.data==ll) = 1;
    if ll~=1 && ll~=2
        data_nov1(ni_rois.data==ll) = 1;
    end
end
filename = fullfile(mask_dir,sprintf('atlas_%s.nii.gz',roi_dorsal_atlas_root));
dtiWriteNiftiWrapper(data,ni_rois.qto_xyz,filename);
filename = fullfile(mask_dir,sprintf('atlas_%s.nii.gz',roi_dorsal_nov1_atlas_root));
dtiWriteNiftiWrapper(data_nov1,ni_rois.qto_xyz,filename);
% Ecc Dorsal
var = 0.2;
filename = fullfile(mask_dir,sprintf('atlas_%s_%s_%.2f.nii.gz',ecc_atlas_root,var_atlas_root,var));
ecc = niftiRead(filename);
ecc.data(data==0) = 0;
filename = fullfile(mask_dir,sprintf('atlas_%s_%s_%s_%.2f.nii.gz',roi_dorsal_atlas_root,ecc_atlas_root,var_atlas_root,var));
dtiWriteNiftiWrapper(ecc.data,ecc.qto_xyz,filename);

% Visual Field Cluster ROIs

% C1
data = zeros(ni_rois.dim);
for ll = roi_c1_lbls
    data(ni_rois.data==ll) = 1;
end
filename = fullfile(mask_dir,sprintf('atlas_%s.nii.gz',roi_c1_atlas_root));
dtiWriteNiftiWrapper(data,ni_rois.qto_xyz,filename);
filename = fullfile(mask_dir,sprintf('atlas_%s_%s_%.2f.nii.gz',ecc_atlas_root,var_atlas_root,var));
% C1 ECC
var = 0.2;
ecc = niftiRead(filename);
ecc.data(data==0) = 0;
filename = fullfile(mask_dir,sprintf('atlas_%s_%s_%s_%.2f.nii.gz',roi_c1_atlas_root,ecc_atlas_root,var_atlas_root,var));
dtiWriteNiftiWrapper(ecc.data,ecc.qto_xyz,filename);

% CMT
data = zeros(ni_rois.dim);
for ll = roi_cmt_lbls
    data(ni_rois.data==ll) = 1;
end
filename = fullfile(mask_dir,sprintf('atlas_%s.nii.gz',roi_cmt_atlas_root));
dtiWriteNiftiWrapper(data,ni_rois.qto_xyz,filename);
filename = fullfile(mask_dir,sprintf('atlas_%s_%s_%.2f.nii.gz',ecc_atlas_root,var_atlas_root,var));
% CMT ECC
var = 0.2;
ecc = niftiRead(filename);
ecc.data(data==0) = 0;
filename = fullfile(mask_dir,sprintf('atlas_%s_%s_%s_%.2f.nii.gz',roi_cmt_atlas_root,ecc_atlas_root,var_atlas_root,var));
dtiWriteNiftiWrapper(ecc.data,ecc.qto_xyz,filename);

% CVO
data = zeros(ni_rois.dim);
for ll = roi_cvo_lbls
    data(ni_rois.data==ll) = 1;
end
filename = fullfile(mask_dir,sprintf('atlas_%s.nii.gz',roi_cvo_atlas_root));
dtiWriteNiftiWrapper(data,ni_rois.qto_xyz,filename);
filename = fullfile(mask_dir,sprintf('atlas_%s_%s_%.2f.nii.gz',ecc_atlas_root,var_atlas_root,var));
% CVO ECC
var = 0.2;
ecc = niftiRead(filename);
ecc.data(data==0) = 0;
filename = fullfile(mask_dir,sprintf('atlas_%s_%s_%s_%.2f.nii.gz',roi_cvo_atlas_root,ecc_atlas_root,var_atlas_root,var));
dtiWriteNiftiWrapper(ecc.data,ecc.qto_xyz,filename);

% cv3ab
data = zeros(ni_rois.dim);
for ll = roi_cv3ab_lbls
    data(ni_rois.data==ll) = 1;
end
filename = fullfile(mask_dir,sprintf('atlas_%s.nii.gz',roi_cv3ab_atlas_root));
dtiWriteNiftiWrapper(data,ni_rois.qto_xyz,filename);
filename = fullfile(mask_dir,sprintf('atlas_%s_%s_%.2f.nii.gz',ecc_atlas_root,var_atlas_root,var));
% cv3ab ECC
var = 0.2;
ecc = niftiRead(filename);
ecc.data(data==0) = 0;
filename = fullfile(mask_dir,sprintf('atlas_%s_%s_%s_%.2f.nii.gz',roi_cv3ab_atlas_root,ecc_atlas_root,var_atlas_root,var));
dtiWriteNiftiWrapper(ecc.data,ecc.qto_xyz,filename);

%% Plot number of exit voxels vs. variance explained threshold
hem_names = {'lh','rh'};
var_thresh = 0.1:0.05:0.3;
exit_data = zeros(length(hem_names),length(var_thresh));
for hh = 1:2
    hem = hem_names{hh};
    % Load exit wm
    filename = fullfile(mask_dir,sprintf('wm_%s_exit.nii.gz',hem));
    ni = niftiRead(filename);
    num_vox_exit = sum(ni.data(:)>0);
    % Go through each variance explained level
    for vv = 1:length(var_thresh)
        var = var_thresh(vv);
        filename = fullfile(mask_dir,sprintf('%s_%s_%d_%s_%.2f_%s.nii.gz',cbs_root,hem,num_tracks,var_atlas_root,var,lbl_post));
        ni = niftiRead(filename);
        exit_data(hh,vv) = sum(ni.data(:)>0) / num_vox_exit;
    end
end

figure;
bar(var_thresh,exit_data');
legend(hem_names);
xlabel('Variance Explained');
title('Fraction of voxels connected to retinotopic occ. cortex');


function r = subsasgn(r,s,b)
% overloads subsasgn

if isnumeric(r)
  r = b;
  r.a = [];
  r.b = [];
  r.c = [];
  r.d = [];
  r.i = [];
end

if ~isstruct(s)

  if isempty(b)
    r.a(s) = [];
    r.b(s) = [];
    r.c(s) = [];
    r.d(s) = [];
    r.i(s) = [];
  else
    b = rotation(b);
    r.a(s) = b.a;
    r.b(s) = b.b;
    r.c(s) = b.c;
    r.d(s) = b.d;
    r.i(s) = b.i;
  end

else
  switch s(1).type

    case '()'

      if numel(s)>1, b =  builtin('subsasgn',subsref(r,s(1)),s(2:end),b); end

      if isnumeric(b)
        r.a = subsasgn(r.a,s(1),b);
        r.b = subsasgn(r.b,s(1),b);
        r.c = subsasgn(r.c,s(1),b);
        r.d = subsasgn(r.d,s(1),b);
        if isempty(b)
          r.i = subsasgn(r.i,s(1),[]);
        else
          r.i = subsasgn(r.i,s(1),false(size(b)));
        end
      else
        b = rotation(b);
        r.a = subsasgn(r.a,s(1),b.a);
        r.b = subsasgn(r.b,s(1),b.b);
        r.c = subsasgn(r.c,s(1),b.c);
        r.d = subsasgn(r.d,s(1),b.d);
        r.i = subsasgn(r.i,s(1),b.i);
      end
    otherwise
      r =  builtin('subsasgn',r,s,b);
  end
end

end


function printClosedloopData(mpciter, u, x, t_Elapsed,output_data)
    global fst_output_data ;
    global snd_output_data ;
    if size(x,2)==2
        fprintf(' %3d  |%+11.4f %+11.4f         %+11.4f  %+11.4f %+8.3f', ...
            mpciter, u(1), u(2), x(1), x(2), t_Elapsed);
        fst_output_data = [output_data; [mpciter, u(1), u(2), x(1), x(2), t_Elapsed]];
    else
        fprintf(' %3d  |%+11.4f %+11.4f %+11.4f %+11.4f  %+11.4f  %+11.4f', ...
            mpciter, u(1), u(2), u(3), x(1), x(2), x(3));
        snd_output_data = [output_data; [mpciter, u(1), u(2), u(3), x(1), x(2), x(3)]];
    end

end


function [g,m] = do_pedro_transfer(models)
error('deprecated');

m = models;
for i = 1:length(models)
  m{i}.models_name = 'pedroxfer';
end

addpath(genpath('/nfs/hn22/tmalisie/ddip/util/voc-release3.1/'))
load bus_final.mat
fg = get_pascal_bg('test','bus');

allbg = cat(1,get_pascal_bg('trainval'),get_pascal_bg('test'));
curids = cell(length(allbg),1);
for i = 1:length(allbg)
  [tmp,curids{i},tmp] = fileparts(allbg{i});
end

%fg = fg(1:5);
g = cell(length(fg),1);

xs = cellfun2(@(x)x.model.x,models);
xs = cat(2,xs{:});

xs2 = xs;
for i = 1:size(xs2,2)
  xs2(:,i) = xs2(:,i) - mean(xs2(:,i));
end

for i = 1:length(fg)
  I = convert_to_I(fg{i});
  boxes = detect(I,model,model.thresh);
  boxes = nms(boxes,.5);

  %if size(boxes,1)==0
  %  continue
  %end

  %newboxes are in my format, boxes is in pedros format
  newboxes = zeros(size(boxes,1),8);
  if size(boxes,1)>0
    [aa,bb] = sort(boxes(:,end),'descend');
    boxes = boxes(bb,:);
    newboxes(:,1:4) = boxes(:,1:4);
    newboxes(:,end) = boxes(:,end);
  end

  for j = 1:size(boxes,1)
    curm = initialize_model_dt(I,boxes(j,:),...
                               models{1}.model.params.sbin,...
                               models{1}.model.hg_size);

    [tmp,ind] = max(xs2'*curm.x);
    newboxes(j,6) = ind;
  end

  g{i}.bboxes = newboxes;
  g{i}.imbb = [1 1 size(I,2) size(I,1)];
  [tmp,g{i}.curid,tmp] = fileparts(fg{i});

  g{i}.index = find(ismember(g{i}.curid,curids));
  g{i}.extras = [];
  %% no extras, no coarse boxes

  figure(1)
  clf
  imagesc(I)
  if size(newboxes,1)>0
    plot_bbox(newboxes(1,:))
    title('Top Detection');
  end
  % figure(2)
  % [aa,bb] = sort(xs2'*curm.x,'descend');
  % for q = 1:9
  %   subplot(3,3,q)
  %   imagesc(get_exemplar_icon(models,bb(q)));
  % end
  drawnow

end


classdef task_pf_legacy < mp.task_pf & mp.task_shared_legacy
%MP.TASK_PF_LEGACY  MATPOWER task for legacy power flow (PF).
%   MP.TASK_PF_LEGACY provides implementation for power flow problem.
%
%   Properties
%       ?
%
%   Methods
%       ?
%
%   See also MP.TASK_PF

%   MATPOWER
%   Copyright (c) 2020-2022, 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.

    properties
    end

    methods
        %%-----  task methods  -----
        function [d, mpopt] = run_pre(obj, d, mpopt)
            [d, mpopt] = obj.run_pre_legacy(d, mpopt);
            [d, mpopt] = run_pre@mp.task_pf(obj, d, mpopt);
        end

        function obj = run_post(obj, mm, nm, dm, mpopt);
            if obj.nm.np ~= 0
                obj.dm.source = obj.dmc.export(obj.dm, obj.dm.source);
            end
        end

        %%-----  other methods  -----
        function [results, success] = legacy_post_run(obj, mpopt)
            success = obj.success;
            results = obj.dm.source;
            results.task = obj;
        end
    end     %% methods
end         %% classdef


function [a, s]=getarrowslice
% Return the Arrow and Slice based on the GCO

  if isempty(getappdata(gco,'controlarrow')) & ...
        isempty(getappdata(gco,'isosurface'))
    a = gco;
    s = getappdata(a,'arrowslice');
    if isempty(s)
      s=getappdata(a,'arrowiso');
    end
  else
    s = gco;
    if ~isempty(getappdata(s,'isosurface'))
      s=getappdata(s,'isosurface');
    end
    a = getappdata(s,'controlarrow');
  end


function [AddedRxns] = submitGapFill(swift, modelFile, dbFile, dictionaryFile, prepareFGFResults, weightsPerRxnFile, forceRerun, epsilon, blackList, listCompartments)
% A test function for `prepareFastGapFill`, `swiftGapFill`, and
% `fastGapFill`, allowing all files to be optionally specified and not
% requiring `prepareFastGapFill` to be rerun (if relevant variables are saved
% in a specified workspace file) if it has already been run.
%
% This function performs three runs of `fastGapFill` or `swiftGapFill on the
% same prepared model, with weights as specified in the 'Define Runs' section
% of the code.  The 'runs' variable can be appended to or changed to enable
% the running of `fastGapFill` or `swiftGapFill` for different combinations
% of weights (and different `weightsPerRxnFile` files).
%
% This function draws inspiration heavily from the example already
% available for `fastGapFill`, i.e. `runGapFill_example.m`
%
% N.B. The defaults are set for testing all of the functionality of the
% algorithm, including setting a (toy) weight file, which is not necessary
% in running `fastGapFill` or `swiftGapFill` so should be specified as empty
% if running without a weight file.
%
% All inputs are optional, defaults to E. coli model iAF1260 and example files)
%
% USAGE:
%
%    [AddedRxns] = submitGapFill(swift, modelFile, dbFile, dictionaryFile, prepareFGFResults, weightsPerRxnFile, forceRerun, epsilon, blackList, listCompartments)
%
% OPTIONAL INPUTS:
%    swift:                Boolean specifying whether to run swiftGapFill or
%                          fastGapFill (default: false)
%    modelFileIn:          File containing model, either .mat or .xml
%                          (default: 'examples/iAF1260.mat')
%    dbFileIn:             File containing universal database
%                          (default: 'AuxillaryFiles/reaction.lst')
%    dictionaryFileIn:     File containing db metabolite IDs and model
%                          counterparts, either .xls or .tsv
%                          (default: 'AuxillaryFiles/KEGG_dictionary.xls')
%    workspaceFileIn:      File for storing `prepareFastGapFill` results
%                          (default: 'examples/defaultWorkspace.mat')
%    weightsPerRxnFile:    File containing individual weights for reactions
%                          (default: 'examples/sampleWeights.tsv')
%    forceRerun:           Boolean specifying whether to rerun
%                          `prepareFastGapFill` even if it has already been
%                          run. N.B. If this is set to 'true' it will overwrite
%                          the precalculated default results files, unless
%                          `prepareFGFResults` is specified outside the examples
%                          directory (default: false)
%    epsilon:              Float, a fastCore parameter (default: getCobraSolverParams('LP', 'feasTol')*100)
%    blackList:            List of excluded universal DB reactions
%                          (default: none)
%    listCompartments:     List of compartments in the model to be gapFilled N.B.
%                          the default is set within `prepareGapFill`
%                          (default: all compartments specified in the model)
%
% OUTPUT:
%    AddedRxns:            Reactions that have been added from UX matrix to `S`
%
% .. Author:
%   - Will Bryant, Jan 2016
%   - Mojtaba Tefagh, May 2019

global CBTDIR

warning('off','MATLAB:load:variableNotFound') % Preparation - load data. Suppress load warnings and deal with in the function

% Get folder for finding default files relative to submitGapFill
runDir = [CBTDIR filesep 'src' filesep 'reconstruction' filesep 'fastGapFill' filesep];

% fastGapFill results files will be created in the same directory as prepareFGFResults
resultsDir = [CBTDIR filesep 'tutorials' filesep 'reconstruction' filesep 'fastGapFill' filesep];

% Get input files where specified
if ~exist('swift','var') || isempty(swift)
    swift=false;
end
if ~exist('modelFile','var') || isempty(modelFile)
    modelFile = strcat(runDir, ['examples' filesep 'iAF1260.mat']);
end
if ~exist('dbFile','var') || isempty(dbFile)
    dbFile = strcat(runDir, ['AuxillaryFiles' filesep 'reaction.lst']);
end
if ~exist('dictionaryFile','var') || isempty(dictionaryFile)
    dictionaryFile = strcat(runDir, ['AuxillaryFiles' filesep 'KEGG_dictionary.xls']);
end
if ~exist('prepareFGFResults','var') || isempty(prepareFGFResults)
    prepareFGFResults =  strcat(resultsDir, ['example' filesep 'prepareFGFResultsDefault.mat']);
end
if ~exist('weightsPerRxnFile','var') || isempty(weightsPerRxnFile)
    weightsPerRxnFile = strcat(resultsDir, ['example' filesep 'sampleWeights.tsv']);
end

if ~exist('forceRerun','var') || isempty(forceRerun)
    forceRerun=false;
end
if ~exist('epsilon','var') || isempty(epsilon)
    epsilon=getCobraSolverParams('LP', 'feasTol')*100;
end
if ~exist('blackList','var') || isempty(blackList)
    blackList=[];
end
if ~exist('listCompartments','var') || isempty(listCompartments)
    listCompartments=[];
end

%% prepareFastGapFill
% If workspaceFile is present, check for all variables; if consistModel,
% consistMatricesSUX and BlockedRxns are present, do not rerun
% prepareFastGapFill, otherwise run and save workspace; check for but do
% not require prepStats
try
    a = load(prepareFGFResults,'consistModel','consistMatricesSUX','BlockedRxns','model');
catch
    fprintf('Workspace file not found, proceeding with prepareGapFill ...\n')
    a = struct();
end
length_a = length(fieldnames(a));
clear a;
if (length_a == 4) && ~forceRerun
    fprintf('prepareGapFill already run, and forceRerun set to "false", prepareGapFill will not be rerun\n');
else

    % load model using relevant load function
    if regexp(modelFile,'.mat$')
        model = readMlModel(modelFile);
    elseif regexp(modelFile,'.xml$')
        model = readCbModel(modelFile);
        % If subSystems is empty, create a dummy subSystems for mergeTwoModels
        if ~exist('model.subSystems') || length(model.subSystems) ~= length(model.rxnNames)
            model.subSystems = repmat({{''}},length(model.rxns),1);
        end
        if ~exist('model.genes')
            model.genes = repmat({'no_gene'},1);
        end
        if ~exist('model.rxnGeneMat')
            model.rxnGeneMat = zeros(length(model.rxns),1);
        end
        if ~exist('model.grRules')
            model.grRules = repmat({''},length(model.rxns),1);
        end
    end

    % remove constraints from exchange reactions
    EX = strncmp('EX_',model.rxns,3);
    model.lb(EX)=-100;
    model.ub(EX)=100;
    clear EX

%     % Switch all model IDs to lower-case
%     model.mets = cellfun(@lower,model.mets,'UniformOutput',false);

    tic;
    [consistModel,consistMatricesSUX,BlockedRxns] = prepareFastGapFill(model, listCompartments, epsilon, dbFile, dictionaryFile, blackList);
    tpre=toc;

    % Prepare the output table with statistics
    cnt = 1;
    prepStats{cnt,1} = 'Model name';cnt = cnt+1;
    prepStats{cnt,1} = 'Size S (original model)';cnt = cnt+1;
    prepStats{cnt,1} = 'Number of compartments';cnt = cnt+1;
    prepStats{cnt,1} = 'List of compartments';cnt = cnt+1;
    prepStats{cnt,1} = 'Number of blocked reactions';cnt = cnt+1;
    prepStats{cnt,1} = 'Number of solvable blocked reactions';cnt = cnt+1;
    prepStats{cnt,1} = 'Size S (flux consistent)';cnt = cnt+1;
    prepStats{cnt,1} = 'Size SUX (including solvable blocked reactions)';cnt = cnt+1;
    prepStats{cnt,1} = 'Time preprocessing [min]';

    % get stats
    cnt = 1;
    prepStats{cnt,2} = modelFile;cnt = cnt+1;
    [a,b] = size(model.S);
    prepStats{cnt,2} = strcat(num2str(a),'x',num2str(b));cnt = cnt+1;
    [~,rem] = strtok(model.mets,'\[');
    rem = unique(rem);
    prepStats{cnt,2} = num2str(length(rem));cnt = cnt+1;
    Rem = rem{1};
    for j = 2:length(rem)
        Rem = strcat(Rem,',',rem{j});
    end
    prepStats{cnt,2} = Rem;cnt = cnt+1;
    clear Rem rem;
    prepStats{cnt,2} = num2str(length(BlockedRxns.allRxns));cnt = cnt+1;
    prepStats{cnt,2} = num2str(length(BlockedRxns.solvableRxns));cnt = cnt+1;
    [a,b] = size(consistModel.S);
    prepStats{cnt,2} = strcat(num2str(a),'x',num2str(b));cnt = cnt+1;
    [a,b] = size(consistMatricesSUX.S);
    prepStats{cnt,2} = strcat(num2str(a),'x',num2str(b));cnt = cnt+1;
    prepStats{cnt,2} = num2str(tpre/60);cnt = cnt+1;

    % Save data
    save(prepareFGFResults,'consistModel','consistMatricesSUX','BlockedRxns','prepStats','model');
    fprintf('prepareGapFill finished\n')
end

if swift
    fprintf('Running swiftGapFill ...\n')
else
    fprintf('Running fastGapFill ...\n')
end

%% Define Runs
% define weights for reactions to be added - the lower the weight the
% higher the priority
% WARNING: weights should not be 1, as this impacts on the algorithm
% performance

runs = {};

% RUN 1
run.weightsPerReactionFile = weightsPerRxnFile;
run.weights.MetabolicRxns = 0.1; % Kegg metabolic reactions
run.weights.ExchangeRxns = 0.5; % Exchange reactions
run.weights.TransportRxns = 10; % Transport reactions
run.name = 'initial';
runs = [runs; run];

% RUN 2
run.weightsPerReactionFile = weightsPerRxnFile;
run.weights.MetabolicRxns = 0.1; % Kegg metabolic reactions
run.weights.ExchangeRxns = 0.9; % Exchange reactions
run.weights.TransportRxns = 40; % Transport reactions
run.name = 'hw';
runs = [runs; run];

% RUN 3
run.weightsPerReactionFile = '';
run.weights.MetabolicRxns = 0.01; % Kegg metabolic reactions
run.weights.ExchangeRxns = 2.1; % Exchange reactions
run.weights.TransportRxns = 20; % Transport reactions
run.name = 'vhw';
runs = [runs; run];

clear run

%% fastGapFill/swiftGapFill

cnt = 1;
clear Stats;
Stats{cnt,1} = 'Run name';cnt = cnt+1;
Stats{cnt,1} = 'Number of added reactions (all)';cnt = cnt+1;
Stats{cnt,1} = 'Number of added metabolic reactions ';cnt = cnt+1;
Stats{cnt,1} = 'Number of added transport reactions ';cnt = cnt+1;
Stats{cnt,1} = 'Number of added exchange reactions ';cnt = cnt+1;
if swift
    Stats{cnt,1} = 'Time swiftGapFill';cnt = cnt+1;
else
    Stats{cnt,1} = 'Time fastGapFill';cnt = cnt+1;
end
Stats{cnt,1} = 'SFilename';cnt = cnt+1;

try
    a = load(prepareFGFResults,'consistModel','consistMatricesSUX','BlockedRxns','model');
    assert(length(fieldnames(a)) == 4);
    clear a;
    load(prepareFGFResults,'consistModel','consistMatricesSUX','BlockedRxns','model');
    fprintf('Variables loaded from .mat file\n');
    try
        b = load(prepareFGFResults,'prepStats');
        assert(~isempty(b))
        load(prepareFGFResults,'prepStats');
        clear b;
    catch
        fprintf('Warning: no stats for prepareFastGapfill\n');
    end
catch
    fprintf('Using the preloaded variables\n');
end

for i = 1:length(runs)
    run_idx = i+1;
    fprintf('\nRun %i (%s)\n',i,runs{i}.name);
    weights = runs{i}.weights;
    weightsPerReactionFile = runs{i}.weightsPerReactionFile;
    resultsFile = strcat(resultsDir,'results_',runs{i}.name,'.mat');

    % If specified, import weights from weights file (tsv)
    if ~isempty(weightsPerReactionFile)
        file_handle = fopen(weightsPerReactionFile);
        try
            u = textscan(file_handle,'%s\t%s');
        catch
            fprintf('File "%s" could not be found, exiting\n',weightsPerReactionFile)
            return
        end
        weightsPerReaction.rxns = {};
        weightsPerReaction.weights = {};
        for k = 1:length(u{1})
            weightsPerReaction.rxns{k} = u{1}{k};
            weightsPerReaction.weights{k} = str2double(u{2}{k});
        end
        fclose(file_handle);
    else
        weightsPerReaction = [];
    end

    cnt = 1;
    Stats{cnt,run_idx} = runs{i}.name;cnt = cnt+1;

    % fastGapFill/swiftGapFill
    tic;
    if swift
        [~, AddedRxns] = swiftGapFill(consistMatricesSUX,1e-10,weights,weightsPerReaction);
    else
        [AddedRxns] = fastGapFill(consistMatricesSUX,epsilon,weights,weightsPerReaction);
    end
    tgap=toc;
    Stats{cnt,run_idx} = num2str(length(AddedRxns.rxns));cnt = cnt+1;
    save(resultsFile);

    % Postprocessing
    [AddedRxnsExtended] = postProcessGapFillSolutions(AddedRxns,model,BlockedRxns,0);

    try
        Stats{cnt,run_idx} = num2str(AddedRxnsExtended.Stats.metabolicSol);cnt = cnt+1;
        Stats{cnt,run_idx} = num2str(AddedRxnsExtended.Stats.transportSol);cnt = cnt+1;
        Stats{cnt,run_idx} = num2str(AddedRxnsExtended.Stats.exchangeSol);cnt = cnt+1;
    catch
        Stats{cnt,run_idx} = num2str(0);cnt = cnt+1;
        Stats{cnt,run_idx} = num2str(0);cnt = cnt+1;
        Stats{cnt,run_idx} = num2str(0);cnt = cnt+1;
    end
    Stats{cnt,run_idx} = num2str(tgap);cnt = cnt+1;
    Stats{cnt,run_idx} = resultsFile;cnt = cnt+1;
    clear a b

    % Reaction List
    col = 1;
    RxnList={};
    try
        RxnList{1,col}=resultsFile;RxnList(2:length(AddedRxnsExtended.rxns)+1,col) = AddedRxnsExtended.rxns; col = col + 1;
        RxnList{1,col}=resultsFile;RxnList(2:length(AddedRxnsExtended.rxns)+1,col) = AddedRxnsExtended.rxnFormula; col = col + 1;
        RxnList{1,col}=resultsFile;RxnList(2:length(AddedRxnsExtended.rxns)+1,col) = AddedRxnsExtended.subSystem; col = col + 1;
    catch
        RxnList{1,col}=resultsFile; col = col + 1;
        RxnList{1,col}=resultsFile; col = col + 1;
        RxnList{1,col}=resultsFile; col = col + 1;
    end

    save(resultsFile);
end


function res = mtimes(a,x)
% performs the SPIRIT operator
% see mtimes

res = mtimes(a,x);


%% housekeeping
clear
close all
clc

%%

noclearall=true;

txt=which('driver_all');

lastsep=find(txt==filesep,1,'last');

folder=txt(1:lastsep-1);

w=what(folder);

w=regexp(w.m,'driver\d{2}','match');

w=[w{:}];

bigm=rise.empty();

for ii=1:numel(w)

    run(w{ii})

    bigm(ii)=mest;
end


% This is the demo script for ASRCF

clear;
clc;
close all;
setup_path();

% get seq information
base_path  = './seq';
video_path = [base_path '/' 'FaceOcc1'];
[seq, ground_truth] = load_video_info(video_path,'FaceOcc1');
seq.startFrame = 1;
seq.endFrame = seq.len;
seq.ground_truth=ground_truth;

% Run ASRCF- main function
results = run_ASRCF(seq, video_path);


%Coded by Dr. T. Gu (gu@ohio.edu). Copyright 2009.
%A Pro version is available for up to 99 equations.
%User can import equations and export results
function varargout = MfigExtract(varargin)
% MFIGEXTRACT M-file for MfigExtract.fig
%      MFIGEXTRACT, by itself, creates a new MFIGEXTRACT or raises the existing
%      singleton*.
%
%      H = MFIGEXTRACT returns the handle to a new MFIGEXTRACT or the handle to
%      the existing singleton*.
%
%      MFIGEXTRACT('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in MFIGEXTRACT.M with the given input arguments.
%
%      MFIGEXTRACT('Property','Value',...) creates a new MFIGEXTRACT or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before MfigExtract_OpeningFunction gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to MfigExtract_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 MfigExtract

% Last Modified by GUIDE v2.5 23-Apr-2009 13:49:27

% Begin initialization code - DO NOT EDIT

thisver=version; %prepare to check version = R14 or above?
if isempty(strfind(thisver,'R13'))~=1 | isempty(strfind(thisver,'R12'))~=1
    disp('This software requires MATLAB R14 or above! Yours is lower. Quit.')
    return
end

gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @MfigExtract_OpeningFcn, ...
                   'gui_OutputFcn',  @MfigExtract_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 MfigExtract is made visible.
function MfigExtract_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 MfigExtract (see VARARGIN)

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

% Update handles structure
guidata(hObject, handles);

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

% --- Outputs from this function are returned to the command line.
function varargout = MfigExtract_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 on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%Let's close figure windows before opening new figure to extract
figs = findobj('Type','figure');
figs = sort(figs);
if length(figs) > 1  %if more than just GUI main
   for n = 1:(length(figs)-1) %skip last figure (GUI main)
       close(figs(n)); pause(0.0000001); %delay needed
   end
end

extractxydata_Callback(hObject, eventdata, handles)

function extractxydata_Callback(hObject, eventdata, handles)
% hObject    handle to extractxydata (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global pathname2 filename2  %for View Excel file button

[filename1 pathname1]=uigetfile('*.fig','Select a figure file to extract x-y data');
if isequal(filename1,0) | isequal(pathname1,0); return; end %User pressed Cancel

[filename2, pathname2] = uiputfile('*.xls', 'Provide an Excel file name to save the x-y data');
if isequal(filename2,0) | isequal(pathname2,0)
    return
end %User pressed Cancel

if isempty(strfind(filename2,'.xls'));
    filename2=[filename2 '.xls'];
end

s = openfig(fullfile(pathname1,filename1)); % open figure and get handle to figure
delete(legend);  %legends add extra data to output. Remove legends

%get line handles
h = findobj(s,'Type','line');   %line is the type of your figure file.
	if isempty(h)
	line{1}='Your figure file does not contain x-y data.';
    line{2}='Did you accidentally load a wrong file?';
	line{3}='Your can view your figures using the File menu.';
	line{4}='Make sure you do not load a wrong file.';
	uiwait(msgbox(line, 'No x-y data in your file','warn'));
	close(s)
    return
	end

x=get(h,'xdata');
y=get(h,'ydata');
close(s) %close figure with legends removed
s=hgload(fullfile(pathname1,filename1));  %show original figure with legends

[n dummy]=size(x);  %n= number of x-y sets in the figure.

fid=fopen(fullfile(pathname2,filename2), 'wt');
fprintf(fid,'%s %s\n', 'x, y data extracted from ', [pathname1, filename1]);
if n==1   %because x{i} becomes invalid symbol below if n=1
fprintf(fid,'%s\t %s\n', '      x1', '      y1');
fprintf(fid,'%g\t %g\n', [x;y]);
elseif n > 1

%x{1}=x1 series, y{1} is y1 series, etc.
%find out maximum x{i} length
maxsize=length(x{1});
for i=2:n
    if length(x{i}) > maxsize
        maxsize=length(x{i});
    end
end

%find out whether all the x series are the same
xseriessame=1;
for i=2:n
    if isequal(x{1},x{i})==0  %0 means not equal
        xseriessame=0;
    end
end

if xseriessame==1;  %write x y1 y2... header
fprintf(fid,'All the x series in the figure are found to be the same.\n');
fprintf(fid,'       x\t');
    for i=1:n
    fprintf(fid,'       y%g\t',i);
    end
fprintf(fid,'\n'); %carriage return for header line

%Write each x,y pair horizontally in the output file
    for j=1:maxsize
        fprintf(fid,'%g\t',x{1}(j));  %x series are the same! Write x{1} for all
        for i=1:n
            fprintf(fid,'%g\t',y{i}(j));
        end
    fprintf(fid,'\n');  %carriage return at end of each row
    end
elseif xseriessame==0

%write x, y column header
for i=1:n
       fprintf(fid,'       x%g\t        y%g\t',i,i);
end
fprintf(fid,'\n'); %carriage return for header line

%Write each x,y pair horizontally in the output file
for j=1:maxsize
        for i=1:n
            if j > length(x{i})   %the x-y pair has ended earlier than others
                fprintf(fid,'\t \t');  %mark current x, y as empty
            elseif j <= length(x{i})
                fprintf(fid,'%g\t %g\t',x{i}(j),y{i}(j));
            end
        end
fprintf(fid,'\n');  %carriage return at end of each row
end

end   %ending elseif xseriessame==0 statement
end   %ending elseif n>1 statement

fclose(fid);
message{1}='Output from last run:';
message{3}=sprintf('File = %s',filename2);
message{5}=sprintf('Directory = %s',pathname2);
set(handles.text4,'String',message);
set(handles.pushbutton2,'Visible','on')

% --------------------------------------------------------------------
function viewfigure_Callback(hObject, eventdata, handles)
% hObject    handle to viewfigure (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[filename pathname]=uigetfile('*.fig','Select a figure file to extract x-y data');
if isequal(filename,0) | isequal(pathname,0); return; end %User pressed Cancel
s=hgload(fullfile(pathname,filename));

% --------------------------------------------------------------------
function viewExcelfile_Callback(hObject, eventdata, handles)
% hObject    handle to viewExcelfile (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[filename pathname]=uigetfile('*.xls; *.xlsx','Select a figure file to extract x-y data');
if isequal(filename,0) | isequal(pathname,0); return; end %User pressed Cancel
winopen(fullfile(pathname,filename));

% --------------------------------------------------------------------
function about_Callback(hObject, eventdata, handles)
% hObject    handle to about (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
message{1}='This freeware was coded by:';
message{2}='Dr. Tingyue Gu ( gu@ohio.edu )';
message{3}='Department of Chemical and Biomolecular Eng.';
message{4}='Ohio University, Athens, Ohio 45701, USA';
msgbox(message,'About MfigExtract','none');

% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global pathname2 filename2
winopen(fullfile(pathname2,filename2))


% Code that clears an empty variable, or a NaN vsriable.
% Does not clear structures, or cells.

if exist('var2fix')==1,
    if   eval(['exist(''' var2fix ''') == 1']),
        if eval(['isempty(' var2fix ')']),
            eval(['clear ' var2fix ]);
        else
            if eval(['~isstruct(' var2fix ')']),
                if eval(['~iscell(' var2fix ')']),
                    if eval(['isnan(' var2fix '(1))']),
                        eval(['clear ' var2fix ]);
                    end;
                end;
            end;
        end;
    end;
end;


function [wp_stack]=get_wpstack(host, port)
% [WP_STACK]=GET_WPSTACK(HOST, PORT)
%
% Read number of waypoints in stack from Flightgear over socket
% connection (HOST, PORT).
% Run Flightgear on HOST (e.g. '127.0.0.1' = localhost) with
% parameter "--props = PORT".

import java.net.Socket
import java.io.*

fg_socket = Socket(host, port);
out = PrintWriter(fg_socket.getOutputStream(), true);
in = BufferedReader(InputStreamReader(fg_socket.getInputStream()));

% Waypoints in stack
out.println(sprintf('get /autopilot/route-manager/route/num\r\n'));
wp_stack_str = char(in.readLine());
j = findstr(wp_stack_str,'''');
wp_stack = str2double(wp_stack_str(j(1)+1:j(2)-1));

out.close();
in.close();
fg_socket.close();

end


%%% This script alets the user enter the name of the images (base name, numbering scheme,...

% Checks that there are some images in the directory:

l_ras = dir('*ras');
s_ras = size(l_ras,1);
l_bmp = dir('*bmp');
s_bmp = size(l_bmp,1);
l_tif = dir('*tif');
s_tif = size(l_tif,1);
l_pgm = dir('*pgm');
s_pgm = size(l_pgm,1);
l_ppm = dir('*ppm');
s_ppm = size(l_ppm,1);
l_jpg = dir('*jpg');
s_jpg = size(l_jpg,1);

s_tot = s_ras + s_bmp + s_tif + s_pgm + s_jpg + s_ppm;

if s_tot < 1,
   fprintf(1,'No image in this directory in either ras, bmp, tif, pgm, ppm or jpg format. Change directory and try again.\n');
   break;
end;

% IF yes, display the directory content:

dir;

Nima_valid = 0;

while (Nima_valid==0),

   fprintf(1,'\n');
   calib_name = input('Basename camera calibration images (without number nor suffix): ','s');

   format_image = '0';

	while format_image == '0',

   	format_image =  input('Image format: ([]=''r''=''ras'', ''b''=''bmp'', ''t''=''tif'', ''p''=''pgm'', ''j''=''jpg'', ''m''=''ppm'') ','s');

		if isempty(format_image),
   		format_image = 'ras';
		end;

      if lower(format_image(1)) == 'm',
         format_image = 'ppm';
      else
         if lower(format_image(1)) == 'b',
            format_image = 'bmp';
         else
            if lower(format_image(1)) == 't',
               format_image = 'tif';
            else
               if lower(format_image(1)) == 'p',
                  format_image = 'pgm';
               else
                  if lower(format_image(1)) == 'j',
                     format_image = 'jpg';
                  else
                     if lower(format_image(1)) == 'r',
                        format_image = 'ras';
                     else
                        disp('Invalid image format');
                        format_image = '0'; % Ask for format once again
                     end;
                  end;
               end;
            end;
         end;
      end;
   end;

   check_directory;

end;

if (Nima_valid~=0),
   % Reading images:

   ima_read_calib_no_read; % may be launched from the toolbox itself

   fprintf(1,'\n');

   fprintf(1,'To display the thumbnail images of all the calibration images, you may run mosaic_no_read (may be slow)\n');

end;


function imagelist_to_sds(imnames, imgdir, mcgdir, ovoutdir, sptextdir, regspimgdir, featdir, refinedoutdir, scorefile,topk)
%%%%%%
%MCG
%%%%%%
fprintf('Computing MCG. Note that this can be parallelized\n');

if(~exist(mcgdir, 'file')) mkdir(mcgdir); end

for i=1:numel(imnames)
    fprintf('MCG : %d/%d\n', i, numel(imnames));
    imname=imnames{i};
    imgfile=fullfile(imgdir, [imname '.jpg']);
    img=imread(imgfile);
    candidates_file=fullfile(mcgdir,[imname '.mat']);
    if(~exist(candidates_file))

        candidates=im2mcg(img, 'accurate');
        save(candidates_file, 'candidates');
    end
end

%%%%%%%%%%%
%Preprocess
%%%%%%%%%%%
fprintf('Preprocessing candidates.\n');
[region_meta_info]=preprocess_mcg_candidates(imnames, mcgdir, [], ovoutdir, sptextdir, regspimgdir, 2000);

%%%%%%%%%%%%%
%Load network
%%%%%%%%%%%%%
model_def_file='prototxts/pinetwork_extract_fc7.prototxt';
model_file='sds_pretrained_models/nets/C';
assert(exist(model_def_file, 'file')>0);
assert(exist(model_file, 'file')>0);
rcnn_model=rcnn_create_model(model_def_file,model_file);
rcnn_model=rcnn_load_model(rcnn_model);

%%%%%%%%%%%%%%%%%
%Extract features
%%%%%%%%%%%%%%%%%
fprintf('Saving features..\n');
save_features(imnames, imgdir, sptextdir, regspimgdir, featdir, rcnn_model);

%%%%%%%%%%%%%%%%%
%Score candidates
%%%%%%%%%%%%%%%%%
fprintf('Scoring using SVMs..\n');
svmfile='sds_pretrained_models/svms/C.mat';
tmp=load(svmfile);
scores=test_svms(tmp.models, imnames,featdir);

%%%%%%%%%%%%%%%%%%
%NMS and pick top
%%%%%%%%%%%%%%%%%%
fprintf('Refining and picking top detections\n');
[chosen, chosenscores]=region_nms(ovoutdir, imnames, scores, region_meta_info, 20);
%keep only topk per category
[topchosen, topscores]=get_top_regions(chosen, chosenscores, region_meta_info.overlaps, topk);
save(scorefile, 'scores', 'topchosen', 'topscores');

%%%%%%%%%%%%%%%%
%Refine
%%%%%%%%%%%%%%%%
tmp=load('sds_pretrained_models/refinement_models.mat');
for i=1:20
    fprintf('Refining for category %d\n', i);
    test_save_refiner(imnames, fullfile(refinedoutdir, int2str(i)), topchosen{i}, region_meta_info, featdir, sptextdir, regspimgdir, tmp.refinement_models{i},[10 10] );
end


function model = vargplvmDynamicsUpdateStats(model)
% VARGPLVMDYNAMICSUPDATESTATS wrapper function which according to the type
% of the model dynamics calls the appropriate function to perform the
% precomputations needed for the dynamics model
% DESC
% ARG model: the model that contains the dynamics for which the statistics
% must be updated
% RETURN model : the updated model
%
% COPYRIGHT Andreas C. Damianou, Michalis Titsias, Neil Lawrence, 2010-2011
%
% VARGPLVM

fhandle = str2func([model.dynamics.type 'UpdateStats']);
model = fhandle(model);


%kkbitxor 'Output = Input 1 XOR (Input 2 or Constant)'
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros kbitxor.pane file
%
% Parameters:
% InputFile: i1 'Input 1', required: 'First input data object'
% OutputFile: o 'Output', required: 'Resulting output data object'
% InputFile: i2 'Input 2', optional: 'Second input data object'
% Integer: real 'Constant', default: 0: 'Constant value'
%
% Example: o = kkbitxor({i1, i2}, {'i1','';'o','';'i2','';'real',0})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% kbitxor - Output = Input 1  XOR  (Input 2 or Constant)
%
%  DESCRIPTION
% The bitwise XOR operator performs a bitwise Exclusive OR between each point in
% \fBInput 1" and either \fBInput 2\fP or the \fBConstant\fP value, which
% ever is specified by the user.
%
%  "Data Type - Single Input" 5
% .cI $DATAMANIP/repos/shared/man/sections/value_type_1input
%
%  "Data Type - Two Input Objects" 5
% .cI $DATAMANIP/repos/shared/man/sections/value_type_2input
% The bitwise operators will not operate on float or complex data types.
%
%  "Map Data" 5
% The bitwise operations have not been written to be fully polymorphic yet.
% They does not
% check for map data, and will therefore always operate on the value data,
% even if a map exists.  This will most likely corrupt indexing into the map.
% In the case of a single input, it is recommended to use the "Copy to
% Value" (kcptoval) segment operator to temporarily move the map data into
% the value segment, run the bitwise operation on the data, then move it
% back to the map with the "Copy from Value" (kcpfromval) operator.
% When operating with two input objects, where at least one of the objects
% contains map data, data should be mapped prior to running the bitwise
% operator.  The "Map Data" operator (kmapdata) can be used to perform
% the mapping operation.
%
%  "Validity Mask - Single Input" 5
% .cI $DATAMANIP/repos/shared/man/sections/mask_1input
%
%  "Validity Mask - Two Input Objects" 5
% Masking has not been implemented yet for the bitwise operators.  Therefore,
% only the mask from the first input object will be transferred to the output.
%
%  "Input Objects of Different Sizes" 5
% .cI $DATAMANIP/repos/shared/man/sections/resize_2input
% The value used to pad the data when the input files are not the same size is
% zero.
%
%  "Explicit Location and Time Data - Single Input" 5
% .cI $DATAMANIP/repos/shared/man/sections/loc_and_time_1input
%
%  "Explicit Location and Time Data - Two Input Objects" 5
% The bitwise operations have not been extended to understand location and
% time data.  Therefore, only location and time data present in the first input
% object will be transferred to the output.
%
% Executing \fBXOR" runs the program "kbitwise\fP with the -xor flag.
%
%
%
%  EXAMPLES
%
%  "SEE ALSO"
% DATAMANIP::kbitwise
%
%  RESTRICTIONS
%
% THIS ROUTINE is still under development, and has not been modified to fully
% support the polymorphic data model.  See paragraphs above for discussions
% concerning the polymorphic data segments.
%
% All processing is currently performed as UNSIGNED long, so the operations
% may not work properly on negative values.
%
% The bitwise operators will not operate on float or complex data types.
%
%  REFERENCES
%
%  COPYRIGHT
% Copyright (C) 1993 - 1997, Khoral Research, Inc. ("KRI")  All rights reserved.
%

function varargout = kkbitxor(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,..] = kkbitxor(Inputs,arglist).');
end
if size(arglist,2)~=2
  error('arglist must be of form {''ParameterTag1'',value1;''ParameterTag2'',value2}')
 end
narglist={'i1', '__input';'o', '__output';'i2', '__input';'real', 0};
maxval={0,0,1,0};
minval={0,0,1,0};
istoggle=[0,0,1,1];
was_set=istoggle * 0;
paramtype={'InputFile','OutputFile','InputFile','Integer'};
% 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 'kbitwise"  -xor'],Inputs,narglist);