function varargout = ProjectSetup(varargin)
% PROJECTSETUP MATLAB code for ProjectSetup.fig
%      PROJECTSETUP, by itself, creates a new PROJECTSETUP or raises the existing
%      singleton*.
%
%      H = PROJECTSETUP returns the handle to a new PROJECTSETUP or the handle to
%      the existing singleton*.
%
%      PROJECTSETUP('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in PROJECTSETUP.M with the given input arguments.
%
%      PROJECTSETUP('Property','Value',...) creates a new PROJECTSETUP or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before ProjectSetup_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to ProjectSetup_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 ProjectSetup

% Last Modified by GUIDE v2.5 11-Dec-2020 11:13:31

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @ProjectSetup_OpeningFcn, ...
                   'gui_OutputFcn',  @ProjectSetup_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 ProjectSetup is made visible.
function ProjectSetup_OpeningFcn(hObject, ~, handles, varargin)
% ProjectSetup(p1,v1,...)
%
% ProjectSetup configures a JAABA project. It can optionally accept an
% existing project configuration (basicParamsStruct). It returns a
% configured project in the supplied 'handleobj'. A project configuration
% currently looks like a stripped-down Macguffin and consists of
%   - Names of behaviors/classifiers
%   - Name of experimental movie files
%   - etc.
%
% Call ProjectSetup as follows:
% hobj = HandleObj;
% uiwait(ProjectSetup('handleobj',hobj,...<other args>...));
% processResultsOrDoWhatever(hobj.data); % hobj.data is a Macguffin
%
% P-V arguments:
% * basicParamsStruct: Either [], or Macguffin (or Macguffin-like struct).
% Supplies initial values for project parameters. If basicParamStruct==[],
% then we are creating a new project.
% * handleobj: A HandleObj.

handles.output = hObject;

[figureJLabel, ...
 basicParamsStruct,...
 defaultmoviefilename,...
 defaultmovieindexfilename,...
 defaulttrxfilename,...
 defaultlbl_file,...
 handles.handleobj] = ...
   myparse(varargin,...
           'figureJLabel',[],...
           'basicParamsStruct',[],...
           'defaultmoviefilename',0,...
           'defaultmovieindexfilename',0,...
           'defaulttrxfilename',0,...
           'defaultlbl_file',0,...
           'handleobj',[]);
handles.new = isempty(basicParamsStruct);
handles.figureJLabel = figureJLabel;
handles.basicParamsStruct = basicParamsStruct;

adjustColorsIfMac(hObject);

% Need to derive the basic and advanced sizes (part of the model) from
% the current figure dimensions
handles = setBasicAndAdvancedSizesToMatchFigure(handles);
handles.mode = 'basic';
handles = updateFigurePosition(handles);
centerOnParentFigure(hObject,figureJLabel);
% ADD THIS FOR DEBUGGING WITH AUTOMATION
% set(handles.figureProjectSetup,'Position',[413   588   585   347]);

% Initialize the list of possible feature lexicon names
[handles.featureLexiconNameList,xmlList] = getFeatureLexiconListsFromXML();
handles.featureLexiconNameListIsST = cellfun(@xmlParamsIsST,xmlList);
assert(numel(handles.featureLexiconNameList)==numel(handles.featureLexiconNameListIsST));

% Populate the featureLexiconName popuplist with options
set(handles.featureconfigpopup,'String',handles.featureLexiconNameList);

if isempty(basicParamsStruct)
  % New project
  warnst = warning('off','MATLAB:structOnObject');
  handles.basicParamsStruct = struct(Macguffin('flies')); % the default featureLexiconName
  warning(warnst);
  if ischar(defaultmoviefilename)
    handles.basicParamsStruct.file.moviefilename = defaultmoviefilename;
  end
  if ischar(defaultmovieindexfilename)
    handles.basicParamsStruct.file.movieindexfilename = defaultmovieindexfilename;
  end
  if ischar(defaulttrxfilename)
    handles.basicParamsStruct.file.trxfilename = defaulttrxfilename;
  end
  if ischar(defaultlbl_file),
    handles.basicParamsStruct.lbl_file = defaultlbl_file;
  end
else
  warnst = warning('off','MATLAB:structOnObject');
  handles.basicParamsStruct = struct(basicParamsStruct);
  warning(warnst);

  % Quirk: basicParamsStruct.behaviors
  % For existing projects basicParamsStruct.behaviors.names includes the
  % no-behavior names (eg 'None', 'No_Chase', etc). In ProjectSetup, the
  % user currently only specifies the positive names.
  % So, within ProjectSetup, we truncate .behaviors.names to just the real
  % names; as a quirk, we leave .behaviors.labelcolors unmodified, so
  % .labelcolors DOES include no-behaviors, as the user may want to change
  % those colors.
  behnames = Labels.verifyBehaviorNames(handles.basicParamsStruct.behaviors.names);
  handles.basicParamsStruct.behaviors.names = behnames;
end

if ~isfield(handles.basicParamsStruct,'extra'),
  handles.basicParamsStruct.extra = struct;
end
if ~isfield(handles.basicParamsStruct.extra,'usePastOnly'),
  handles.basicParamsStruct.extra.usePastOnly = false;
end

% Update the configuration table in the GUI
updateConfigTable(handles);

set(hObject,'name',fif(handles.new,'New...','Edit...'));
onoff = fif(handles.new,'on','off');
set(handles.featureconfigpopup,'enable',onoff);
set(handles.pushbutton_copy,'visible',onoff);
set(handles.editName,'enable',onoff);
set(handles.edittrxfilename,'enable',onoff);
set(handles.pushbutton_perframe,'visible',onoff);

% Set the current score-as-feature file
fileNameList = {handles.basicParamsStruct.scoreFeatures(:).classifierfile};
handles.indexOfScoreFeaturesFile = fif(isempty(fileNameList),[],1);

guidata(hObject, handles);

% Update all the text fields in the figure
updateEditsListboxesAndPopupmenus(handles);

% Make the figure visible
set(hObject,'Visible','on');

return

% -------------------------------------------------------------------------
% --- Outputs from this function are returned to the command line.
function varargout = ProjectSetup_OutputFcn(hObject, ~, handles)  %#ok
% 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;
%varargout{2} = handles.outfile;
%delete(handles.figureProjectSetup);
return

% -------------------------------------------------------------------------
function handles=setBasicAndAdvancedSizesToMatchFigure(handles)
% Derive the basic and advanced sizes (part of the model) from
% the current figure dimensions
curPos = get(handles.figureProjectSetup,'Position');
tablePos = get(handles.config_table,'Position');
reducedWidth = tablePos(1)-15;
reducedHeight = curPos(4);
handles.advancedSize = curPos(3:4);
handles.basicSize = [reducedWidth reducedHeight];
return

% -------------------------------------------------------------------------
function handles = updateFigurePosition(handles)
% Update the figure to match the current mode (which is in the model)
if strcmp(handles.mode,'basic')
  curPos = get(handles.figureProjectSetup,'Position');
  set(handles.figureProjectSetup,'Position',[curPos(1:2) handles.basicSize]);
  set(handles.togglebutton_advanced,'Value',0);
else
  curPos = get(handles.figureProjectSetup,'Position');
  set(handles.figureProjectSetup,'Position',[curPos(1:2) handles.advancedSize]);
  set(handles.togglebutton_advanced,'Value',1);
end
return

% -------------------------------------------------------------------------
function updateEditsListboxesAndPopupmenus(handles)

% update the behavior name editbox
if isfield(handles.basicParamsStruct.behaviors,'names');
  names = handles.basicParamsStruct.behaviors.names;
  if numel(names)>0
    namestr = String.cellstr2CommaSepList(names);
  else
    namestr = '';
  end
  set(handles.editName,'String',namestr);
else
  set(handles.editName,'String','');
end

fnames = {'scorefilename','moviefilename','trxfilename'};
boxnames = {'editscorefilename','editmoviefilename','edittrxfilename'};
for ndx = 1:numel(fnames)
  curf = fnames{ndx};
  curbox = boxnames{ndx};
  if isfield(handles.basicParamsStruct.file,curf);
    val = handles.basicParamsStruct.file.(curf);
    if iscellstr(val)
      val = String.cellstr2CommaSepList(val);
    end
    set(handles.(curbox),'String',val);
  else
    set(handles.(curbox),'String','');
  end
end

% Update the select feature dictionary name
indexOfFeatureLexicon = find(strcmp(handles.basicParamsStruct.featureLexiconName,handles.featureLexiconNameList));
if isempty(indexOfFeatureLexicon),
  indexOfFeatureLexicon = 1;
end
set(handles.featureconfigpopup,'Value',indexOfFeatureLexicon);
tfST = handles.featureLexiconNameListIsST(indexOfFeatureLexicon);
if tfST
  visVal = 'on';
else
  visVal = 'off';
end
set(handles.txST,'Visible',visVal);

% % Update the list of scores-an-inputs
% fileNameList = {handles.basicParamsStruct.scoreFeatures(:).classifierfile};
% set(handles.listbox_inputscores,'String',fileNameList);
% set(handles.listbox_inputscores,'Value',handles.indexOfScoreFeaturesFile);

% % Disble the Remove button iff the list of scores-as-inputs is empty
% set(handles.pushbutton_removelist,'enable',offIff(isempty(fileNameList)));

return

% -------------------------------------------------------------------------
function handles = fileNameEditTwiddled(handles,editName)
% Deal with one of the file name edits being modified.
% This is like a controller method.
varName=editName(5:end);  % trim 'edit' off of start
newFileName=strtrim(get(handles.(editName),'String'));
allowEmpty = ismember(varName,{'moviefilename'});
allowMulti = ismember(varName,{'scorefilename','moviefilename'});
[handles,whatHappened]=setFileName(handles,varName,newFileName,allowEmpty,allowMulti);
warnIfInvalid(varName,whatHappened);
updateFileNameEdit(handles,editName);
updateConfigTable(handles);
return

% -------------------------------------------------------------------------
function [handles,whatHappened] = setFileName(handles,varName,newFileName,allowEmpty,allowMulti)
% Set the given file name in the model, if it's a valid name.  whatHappened
% is a string that can be 'notChanged', 'emptyEntry','changed', or
% 'invalidEntry', depending.

fileName=handles.basicParamsStruct.file.(varName);

if allowEmpty && isempty(newFileName),
  handles.basicParamsStruct.file.(varName)=newFileName;
  if strcmp(newFileName,fileName),
    whatHappened='notChanged';
  else
    whatHappened='changed';
  end
  return;
end

if isequal(newFileName,fileName)
  whatHappened='notChanged';
elseif isempty(newFileName)
  whatHappened='emptyEntry';
elseif ~allowMulti && IsNiceFileName(newFileName)
  whatHappened='changed';
  handles.basicParamsStruct.file.(varName)=newFileName;
elseif allowMulti
  newFileNameCellStr = String.commaSepList2CellStr(newFileName);
  if all(cellfun(@IsNiceFileName,newFileNameCellStr))
    whatHappened = 'changed';
    handles.basicParamsStruct.file.(varName)=newFileNameCellStr;
  else
    whatHappened = 'invalidEntry';
  end
else
  whatHappened='invalidEntry';
end

return

% -------------------------------------------------------------------------
function warnIfInvalid(varName,whatHappened)
% Throw up a warning dialog if whatHappened equals 'invalidEntry'
if isequal(whatHappened,'invalidEntry')
  message=...
    sprintf(['The name specified for %s cannot have special characters.'...
             'Please use only alphanumeric characters and underscore.'],varName);
  title='Invalid File Name';
  uiwait(warndlg(message,title,'modal'));
end
return

% -------------------------------------------------------------------------
function updateFileNameEdit(handles,editName)
  % Update the named file name edit to match the model.
  varName=editName(5:end);  % trim 'edit' off of start
  val = handles.basicParamsStruct.file.(varName);
  if iscellstr(val)
    val = String.cellstr2CommaSepList(val);
  end
  set(handles.(editName),'String',val);
return

% -------------------------------------------------------------------------
function updateConfigTable(handles)
% Update the config table (a GUI element) to match the current "model"
% state
basicParamsStruct = handles.basicParamsStruct;
fields2remove = {'featureLexicon','windowFeaturesParams','scoreFeatures', ...
                 'sublexiconPFNames','labels','gtLabels','expDirNames', ...
                 'gtExpDirNames', 'classifierStuff', 'version','classifierfile',...
                 'windowFeaturesParams','aptInfo'};
if ~handles.new
  editModeRemove = {'featureLexiconName' 'behaviors.names' 'behaviors.type' ...
    'behaviors.nbeh' 'file.trxfilename' 'extra.perframe'};
  fields2remove = [fields2remove editModeRemove];
end
basicParamsStruct = structrmfield(basicParamsStruct,fields2remove);
data = GetParamsAsTable(basicParamsStruct);
set(handles.config_table,'Data',data);
return

% -------------------------------------------------------------------------
function data = GetParamsAsTable(basicParamsStruct)
data = addToList(basicParamsStruct,{},'');
idx = cellfun(@iscell,data(:,2));
if any(idx),
  for i = find(idx(:)'),
    if all(cellfun(@ischar,data{i,2})),
      data{i,2} = sprintf('%s,',data{i,2}{:});
      if numel(data{i,2})>0 && data{i,2}(end) == ',',
        data{i,2} = data{i,2}(1:end-1);
      end
    end
  end
end

if any(cellfun(@iscell,data(:,2))),
  data = {};
  return;
end

% -------------------------------------------------------------------------
function list = addToList(curStruct,list,pathTillNow)
if isempty(fieldnames(curStruct)), return; end
fnames = fieldnames(curStruct);
for ndx = 1:numel(fnames)
  if isstruct(curStruct.(fnames{ndx})),
    list = addToList(curStruct.(fnames{ndx}),list,[pathTillNow fnames{ndx} '.']);
  else
    list{end+1,1} = [pathTillNow fnames{ndx}]; %#ok<AGROW>
    param = curStruct.(fnames{ndx});
    if isnumeric(param)
      if isempty(param)
        q='';
      else
        q = num2str(param(1));
        for jj = 2:numel(param)
          q = [q ',' num2str(param(jj))]; %#ok<AGROW>
        end
      end
      list{end,2} = q;
    else
      list{end,2} = param;
    end
  end
end

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

% Hints: get(hObject,'String') returns contents of editName as text
%        str2double(get(hObject,'String')) returns contents of editName as a double
name = String.commaSepList2CellStr(get(hObject,'String'));
if any(cellfun(@(x)isempty(regexp(x,'^[a-zA-Z][\w_,]*$','once','start')),name));
   uiwait(warndlg(['The behavior name cannot have special characters.'...
                   'Please use only alphanumeric characters and _']));
   updateEditsListboxesAndPopupmenus(handles);
   return
end

handles.basicParamsStruct.behaviors.names = name;
if numel(name)>1
  % multiple classifiers; set labelcolors
  nlabels = 2*numel(name);
  clrs = Labels.cropOrAugmentLabelColors(zeros(1,0),nlabels,'lines');
  handles.basicParamsStruct.behaviors.labelcolors = clrs;
end
handles.basicParamsStruct.file.scorefilename = cellfun(@(x)sprintf('scores_%s.mat',x),name,'uni',0);
guidata(hObject,handles);
updateEditsListboxesAndPopupmenus(handles);
updateConfigTable(handles);
return

function behaviorsStruct = enforceBehaviorParamConstraints(behaviorsStruct,dowarn)

if ~exist('dowarn','var')
  dowarn = false;
end

% Add no-behavior names
behaviorsStruct.names = Labels.behnames2labelnames(behaviorsStruct.names);

nlabels = numel(behaviorsStruct.names);
if numel(behaviorsStruct.labelcolors)~=3*nlabels
  if dowarn
    warning('ProjectSetup:behaviorParams',...
      'Specified label colors not consistent with number of behaviors. Updating.');
  end
  behaviorsStruct.labelcolors = Labels.cropOrAugmentLabelColors(behaviorsStruct.labelcolors,nlabels,'lines');
end

% -------------------------------------------------------------------------
function editName_CreateFcn(hObject, eventdata, handles)  %#ok
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
return

% -------------------------------------------------------------------------
% --- Executes on selection change in featureconfigpopup.
function featureconfigpopup_Callback(hObject, eventdata, handles)  %#ok
% hObject    handle to featureconfigpopup (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
iFeatureLexicon=get(hObject,'Value');
featureLexiconNameNew = handles.featureLexiconNameList{iFeatureLexicon};
% Save the current values of the main four fields
% (Note that any changes in the advanced part of the window will be lost.)
behaviorName=handles.basicParamsStruct.behaviors.names;
movieFileName=handles.basicParamsStruct.file.moviefilename;
movieIndexFileName=handles.basicParamsStruct.file.movieindexfilename;
trackFileName=handles.basicParamsStruct.file.trxfilename;
scoreFileName=handles.basicParamsStruct.file.scorefilename;
% Replace basicParamsStruct with one appropriate to the new feature lexicon
% name
old=warning('query','MATLAB:structOnObject');
warning('off','MATLAB:structOnObject');  % turn off annoying warning
handles.basicParamsStruct = struct(Macguffin(featureLexiconNameNew));
warning(old);  % restore annoying warning
% Now restore fields from the old basicParamsStruct
handles.basicParamsStruct.behaviors.names=behaviorName;
handles.basicParamsStruct.file.moviefilename=movieFileName;
handles.basicParamsStruct.file.movieindexfilename=movieIndexFileName;
handles.basicParamsStruct.file.trxfilename=trackFileName;
handles.basicParamsStruct.file.scorefilename=scoreFileName;
guidata(hObject,handles);
updateConfigTable(handles);
updateEditsListboxesAndPopupmenus(handles);
return

% -------------------------------------------------------------------------
% --- Executes during object creation, after setting all properties.
function featureconfigpopup_CreateFcn(hObject, ~, ~)  %#ok
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% -------------------------------------------------------------------------
function editscorefilename_Callback(hObject, eventdata, handles)  %#ok
editName=get(hObject,'tag');
handles = fileNameEditTwiddled(handles,editName);
guidata(hObject,handles);

% -------------------------------------------------------------------------
function editscorefilename_CreateFcn(hObject, eventdata, handles)  %#ok
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% -------------------------------------------------------------------------
function editmoviefilename_Callback(hObject, eventdata, handles)  %#ok
editName=get(hObject,'tag');
handles = fileNameEditTwiddled(handles,editName);
guidata(hObject,handles);

% -------------------------------------------------------------------------
function editmoviefilename_CreateFcn(hObject, eventdata, handles)  %#ok
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% -------------------------------------------------------------------------
function edittrxfilename_Callback(hObject, eventdata, handles)  %#ok
editName=get(hObject,'tag');
handles = fileNameEditTwiddled(handles,editName);
guidata(hObject,handles);

% -------------------------------------------------------------------------
% --- Executes during object creation, after setting all properties.
function edittrxfilename_CreateFcn(hObject, eventdata, handles)  %#ok
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% -------------------------------------------------------------------------
function pushbutton_cancel_Callback(hObject, eventdata, handles)  %#ok
handles.outfile = 0;
guidata(hObject,handles);
delete(findAncestorFigure(hObject));
%uiresume(handles.figureProjectSetup);
return

% -------------------------------------------------------------------------
function pushbutton_done_Callback(hObject, ~, handles)  %#ok
behaviorName = handles.basicParamsStruct.behaviors.names;
if isempty(behaviorName)
  uiwait(errordlg('You must enter a behavior name.', ...
                  'No behavior name', ...
                  'modal'));
  return
end

% Check for an empty track file name
trackFileName = handles.basicParamsStruct.file.trxfilename;
if isempty(trackFileName)
  uiwait(errordlg('You must enter a track file name.', ...
                  'No track file name', ...
                  'modal'));
  return
end

% Check for an empty score file name
scoreFileName = handles.basicParamsStruct.file.scorefilename;
if isempty(scoreFileName)
  uiwait(errordlg('You must enter a score file name.', ...
                  'No score file name', ...
                  'modal'));
  return
end

nbehavior = numel(handles.basicParamsStruct.behaviors.names);
assert(iscellstr(handles.basicParamsStruct.file.scorefilename));
nscorefile = numel(handles.basicParamsStruct.file.scorefilename);
if nbehavior~=nscorefile
  uiwait(errordlg('The number of score files must match the number of behaviors.', ...
                  'Invalid score file names', ...
                  'modal'));
  return
end

% if movie is an mjpg, ask for an index file
if ischar(handles.basicParamsStruct.file.moviefilename)
  [~,~,ext] = fileparts(handles.basicParamsStruct.file.moviefilename);
else
  [~,~,ext] = fileparts(handles.basicParamsStruct.file.moviefilename{1});
end
if ismember(lower(ext),{'.mjpg','.mjpeg'}),

  res = questdlg('Is this an indexed MJPG file? If so, you will be prompted to select the corresponding index file location.');
  if strcmpi(res,'Yes'),
    if isfield(handles.basicParamsStruct.file,'movieindexfilename') && ...
        ischar(handles.basicParamsStruct.file.movieindexfilename),
      defaultindexfile = handles.basicParamsStruct.file.movieindexfilename;
    else
      defaultindexfile = 'index.txt';
    end
    res = inputdlg({'MJPG index file name: '},'MJPG index file name',1,{defaultindexfile});
    % cancel
    if isempty(res),
      return;
    end
    handles.basicParamsStruct.file.movieindexfilename = res{1};
  else
    handles.basicParamsStruct.file.movieindexfilename = 0;
  end

else
  handles.basicParamsStruct.file.movieindexfilename = 0;
end

% Finish initialization of basicParamsStruct and return as Macguffin in handleobj
handles.basicParamsStruct.behaviors = ...
  enforceBehaviorParamConstraints(handles.basicParamsStruct.behaviors,true);

if handles.new
  for i = nbehavior:-1:1
    cs(i,1) = ClassifierStuff();
    wfp{i,1} = handles.basicParamsStruct.windowFeaturesParams{1};
  end
  handles.basicParamsStruct.classifierStuff = cs;
  handles.basicParamsStruct.windowFeaturesParams = wfp;
end

basicParamsStruct = handles.basicParamsStruct;
% AL: Not sure why we return a Macguffin vs just the struct, prob doesn't
% make a difference
if basicParamsStruct.fromAPT
  behaviorName=basicParamsStruct.behaviors.names;
  labelColors=basicParamsStruct.behaviors.labelcolors;
  movieFileName=basicParamsStruct.file.moviefilename;
  movieIndexFileName=basicParamsStruct.file.movieindexfilename;
  trackFileName=basicParamsStruct.file.trxfilename;
  scoreFileName=basicParamsStruct.file.scorefilename;
  wfparams=basicParamsStruct.windowFeaturesParams;
  cstuff=basicParamsStruct.classifierStuff;
  everythingParams = Macguffin(basicParamsStruct.featureLexiconName,basicParamsStruct.aptInfo);
  everythingParams.behaviors.names=behaviorName;
  everythingParams.behaviors.labelcolors=labelColors;
  everythingParams.file.moviefilename=movieFileName;
  everythingParams.file.movieindexfilename=movieIndexFileName;
  everythingParams.file.trxfilename=trackFileName;
  everythingParams.file.scorefilename=scoreFileName;
  everythingParams.windowFeaturesParams=wfparams;
  everythingParams.classifierStuff=cstuff;
else
  everythingParams = Macguffin(basicParamsStruct);
end
assert(~isempty(handles.handleobj));
handles.handleobj.data = everythingParams;

% Delete the ProjectSetup window
delete(get(hObject,'parent'));

% -------------------------------------------------------------------------
% --- Executes on button press in pushbutton_copy.
function pushbutton_copy_Callback(hObject, eventdata, handles) %#ok
% hObject    handle to pushbutton_copy (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[fnames,pname] = uigetfile('*.jab','Select a project to copy settings from');
if fnames == 0; return; end;

list = {'Target Type','Behavior Name and File Names','Window Features',...
  'List of perframe features','Classifier files used as input',...
  'Classifier Settings',...
  'Advanced Parameters'};

dstr = {'Select the parameters to copy.','Use Control/Command click to select multiple entries'};
[sel,ok] = listdlg('PromptString',dstr,'ListSize',[350 120],'Name','Parameters to copy',...
  'ListString',list);
sellist = list(sel);

if ok == 0, return; end

try

  origparams = load(fullfile(pname,fnames),'-mat');

if ismember('Target Type',sellist)
    handles.basicParamsStruct.featureLexiconName = origparams.x.featureLexiconName;
    handles.basicParamsStruct.featureLexicon = origparams.x.featureLexicon;
end

if ismember('Behavior Name and File Names',sellist)
  behnames = origparams.x.behaviors.names;
  isNone=strcmpi('none',behnames);
  behnames=behnames(~isNone);
  handles.basicParamsStruct.behaviors.names = behnames;
  handles.basicParamsStruct.file = origparams.x.file;
end

if ismember('List of perframe features',sellist)
  if ~isequal(handles.basicParamsStruct.featureLexicon,origparams.x.featureLexicon),
    res = questdlg(['Target type (or one of the target settings) are not the same for the current project '...
        'and the original project. Are you sure you want to import the list of perframe features?'],...
        'Import list of perframe features','Yes','No','No');
      if strcmp(res,'Yes')
        handles.basicParamsStruct.sublexiconPFNames= origparams.x.sublexiconPFNames;
      end
  else
    handles.basicParamsStruct.sublexiconPFNames= origparams.x.sublexiconPFNames;

  end
end

if ismember('Window Features',sellist),
  if ~isequal(handles.basicParamsStruct.featureLexicon,origparams.x.featureLexicon) || ...
    ~isequal(handles.basicParamsStruct.sublexiconPFNames,origparams.x.sublexiconPFNames)
    res = questdlg(['Target type or list of perframe features (or one of the traget settings) are not the same for the current project '...
      'and the original project. Are you sure you want to import the window features?'],...
      'Import Window features','Yes','No','No');
    if strcmp(res,'Yes')
      handles.basicParamsStruct.windowFeaturesParams = origparams.x.windowFeaturesParams;
    end
  else
      handles.basicParamsStruct.windowFeaturesParams = origparams.x.windowFeaturesParams;
  end
end

if ismember('Classifier files used as input', sellist);
  handles.basicParamsStruct.scoreFeatures = origparams.x.scoreFeatures;
end

if ismember('Classifier Settings',sellist),
  clf_params_specific = {'classifierStuff.type'
    'classifierStuff.postProcessParams'
    'classifierStuff.trainingParams'
    'classifierStuff.savewindowdata'
    'classifierStuff.selFeatures'
    'classifierStuff.predictOnlyCurrentFly'
    };

  for str = clf_params_specific(:)',
    try %#ok<TRYNC>
      eval(sprintf('handles.basicParamsStruct.%s = origparams.x.%s;',str{1},str{1}));
    end
  end

end

if ismember('Advanced Parameters',sellist),
  adv_params_specific = {'behaviors.labelcolors'
    'behaviors.unknowncolor'
    'trxGraphicParams'
    'extra'};

  for str = adv_params_specific(:)',
    try %#ok<TRYNC>
      eval(sprintf('handles.basicParamsStruct.%s = origparams.x.%s;',str{1},str{1}));
    end
  end

end

guidata(hObject,handles);
updateEditsListboxesAndPopupmenus(handles);
updateConfigTable(handles);

catch ME,
  uiwait(warndlg(sprintf('Could not copy settings from previous project:%s',ME.message)));
end
return

% -------------------------------------------------------------------------
% --- Executes on button press in togglebutton_advanced.
function togglebutton_advanced_Callback(hObject, eventdata, handles)  %#ok
handles.mode=fif(get(hObject,'Value'),'advanced','basic');
handles = updateFigurePosition(handles);
guidata(hObject,handles);
return

% -------------------------------------------------------------------------
% --- Executes on button press in pushbutton_perframe.
function pushbutton_perframe_Callback(hObject, eventdata, handles)  %#ok
featureLexiconName=handles.basicParamsStruct.featureLexiconName;
sublexiconPFNames = handles.basicParamsStruct.sublexiconPFNames;

if ~get(handles.radiobutton_apt,'Value')
  featureLexicon=featureLexiconFromFeatureLexiconName(featureLexiconName);
  [featureLexiconPFNames,isSelected,missingPFNames] = ...
    GetAllPerframeList(featureLexicon,sublexiconPFNames);

  % If some to-be-calculated PFs are not in the lexicon, warn the user.
  if ~isempty(missingPFNames),
    list = naturalLanguageListFromStringList(missingPFNames);
    if length(missingPFNames)==1
      wstr = ...
        sprintf(['Perframe feature %s is defined in the project file ' ...
                 'but is not defined for the current target type.\n' ...
                 'Ignoring it.'],...
                list);
    else
      wstr = ...
        sprintf(['Perframe features %s are defined in the project file ' ...
                 'but are not defined for the current target type.\n' ...
                 'Ignoring them.'],...
                list);
    end
    uiwait(warndlg(wstr));
  end
else
  featureLexicon = handles.basicParamsStruct.featureLexicon;
  [featureLexiconPFNames,isSelected,missingPFNames] = ...
    GetAllPerframeList(featureLexicon,sublexiconPFNames);
  assert(isempty(missingPFNames),'No PF feature should be missing');
end
% Put up the dialog that allows users to pick which PFs will be computed

[isSelected,ok] = listdlg('ListString',featureLexiconPFNames, ...
                          'InitialValue',find(isSelected), ...
                          'Name','Selecte perframe features',...
                          'PromptString',{sprintf('%s-click to',fif(ismac(),'Command','Control')), ...
                                          'select/deselect perframe features'}, ...
                                          'ListSize',[250,700]);

% If the user clicked OK, update the list of to-be-calculated PFs
if ok,
  sublexiconPFNames=featureLexiconPFNames(isSelected);
  handles.basicParamsStruct.sublexiconPFNames = sublexiconPFNames;
  guidata(hObject,handles);
end

return

% -------------------------------------------------------------------------
function [featureLexiconPFNames,isSelected,missingPFNames]= ...
  GetAllPerframeList(featureLexicon,sublexiconPFNames)
% Returns the list of all per-frame feature names in the lexicon indicated
% by featureLexiconName.  Also returns isSelected, a boolean array of the
% same size as featureLexiconPFNames, which is true iff that PF is in the
% sublexiconPFNames list.  Finally, missingPFNames is a list of all PF
% names in sublexiconPFNames that are not present in
% featureLexiconPFNames.

%featureLexiconName=handles.basicParamsStruct.featureLexiconName;
%featureconfigfile = basicParamsStruct.file.featureconfigfile;
%basicParamsStruct = ReadXMLParams(featureconfigfile);
%allPfList = fieldnames(basicParamsStruct.perframe);
featureLexiconPFNames = fieldnames(featureLexicon.perframe);
nFeatureLexiconPFNames=length(featureLexiconPFNames);
isSelected = false(nFeatureLexiconPFNames,1);
missingPFNames = {};
%toBeCalculatedPFNames = basicParamsStruct.toBeCalculatedPFNames;
if isempty(sublexiconPFNames),
  isSelected = true(nFeatureLexiconPFNames,1);
  missingPFNames = {};
else
  for ndx = 1:length(sublexiconPFNames),
    sublexiconPFName=sublexiconPFNames{ndx};
    allndx = find(strcmp(sublexiconPFName,featureLexiconPFNames));
    if isempty(allndx)
      missingPFNames{end+1} = sublexiconPFName;  %#ok
    else
      isSelected(allndx) = true;
    end
  end
end
return

% -------------------------------------------------------------------------
% --- Executes on button press in pushbutton_addadvanced.
function pushbutton_addadvanced_Callback(hObject, eventdata, handles)  %#ok
in = inputdlg({'Configuration Parameter Name','Configuration Parameter Value'});
if isempty(in) || length(in) < 2
  return;
end

handles = AddConfig(handles,in{1},in{2});
updateConfigTable(handles);
updateEditsListboxesAndPopupmenus(handles);
guidata(hObject,handles);

% -------------------------------------------------------------------------
% --- Executes on button press in pushbutton_removeadvanced.
function pushbutton_removeadvanced_Callback(hObject, eventdata, handles)  %#ok
data = get(handles.config_table,'Data');

jUIScrollPane = findjobj(handles.config_table);
jUITable = jUIScrollPane.getViewport.getView;
allndx = jUITable.getSelectedRows + 1;
if numel(allndx)==1 && allndx <1, return, end

for ndx = allndx(:)'
  handles = RemoveConfig(handles,data{ndx,1});
end
updateConfigTable(handles);
updateEditsListboxesAndPopupmenus(handles);
guidata(hObject,handles);
return

% -------------------------------------------------------------------------
% --- Executes when entered data in editable cell(s) in config_table.
function config_table_CellEditCallback(hObject, eventdata, handles)  %#ok
% hObject    handle to config_table (see GCBO)
% eventdata  structure with the following fields (see UITABLE)
%	Indices: row and column indices of the cell(s) edited
%	PreviousData: previous data for the cell(s) edited
%	EditData: string(s) entered by the user
%	NewData: EditData or its converted form set on the Data property. Empty if Data was not changed
%	Error: error string when failed to convert EditData to appropriate value for Data
% handles    structure with handles and user data (see GUIDATA)
if isempty(eventdata.Indices); return; end
data = get(handles.config_table,'Data');
ndx = eventdata.Indices(1);
if eventdata.Indices(2) == 2
  handles = EditConfigValue(handles,data{ndx,1},data{ndx,2});
else
  handles = EditConfigName(handles,eventdata.PreviousData,eventdata.NewData);
end
updateEditsListboxesAndPopupmenus(handles);
guidata(hObject,handles);

% -------------------------------------------------------------------------
function handles = RemoveConfig(handles,name)

[fieldNamePath,dotLastField] = splitext(name);
if isempty(dotLastField)
  handles.basicParamsStruct = rmfield(handles.basicParamsStruct,fieldNamePath);
else
  lastField=dotLastField(2:end);  %#ok
  evalStr = sprintf(...
    'handles.basicParamsStruct.%s = rmfield(handles.basicParamsStruct.%s,lastField);',...
    fieldNamePath,fieldNamePath);
  eval(evalStr);
end

% -------------------------------------------------------------------------
function handles = EditConfigName(handles,oldName,newName)
eval_str = sprintf(...
  'value = handles.basicParamsStruct.%s;',...
  oldName);
eval(eval_str);
handles = AddConfig(handles,newName,value);
handles = RemoveConfig(handles,oldName);
return

% -------------------------------------------------------------------------
function handles = EditConfigValue(handles,name,value)

switch name
  case 'behaviors.names'
    value = regexp(value,',','split'); %#ok<NASGU>
  otherwise
end

% try to convert it to a number if possible
valuen = regexp(value,',','split');
valuen = str2double(valuen);
if all(~isnan(valuen)),
  value = valuen; %#ok<NASGU>
end
eval_str = sprintf('handles.basicParamsStruct.%s = value;',name);
eval(eval_str);
return

% -------------------------------------------------------------------------
function handles = AddConfig(handles,name,value)

% If value is a string, convert to a double matrix, if that works
if ischar(value) && ~isempty(str2num(value)),  %#ok<ST2NM>
  value = str2num(value);  %#ok
end
evalStr=sprintf('handles.basicParamsStruct.%s = value;',name);
eval(evalStr);

return

% -------------------------------------------------------------------------
function figureProjectSetup_CloseRequestFcn(hObject, eventdata, handles)  %#ok
% Hint: delete(hObject) closes the figure
%uiresume(hObject);
pushbutton_cancel_Callback(hObject, eventdata, handles)
return

% -------------------------------------------------------------------------
% --- Executes on key press with focus on figureProjectSetup and none of its controls.
function figureProjectSetup_WindowKeyPressFcn(hObject, eventdata, handles)  %#ok
% hObject    handle to figureProjectSetup (see GCBO)
% eventdata  structure with the following fields (see FIGURE)
%	Key: name of the key that was pressed, in lower case
%	Character: character interpretation of the key(s) that was pressed
%	Modifier: name(s) of the modifier key(s) (i.e., control, shift) pressed
% handles    structure with handles and user data (see GUIDATA)

if isequal(eventdata.Key,'f') && isControlLike(eventdata.Modifier)
  handles.basicParamsStruct.file.moviefilename = 'movie.ufmf';
  handles.basicParamsStruct.file.trxfilename = 'registered_trx.mat';
  guidata(hObject,handles);  % write the changes to the figure
  updateEditsListboxesAndPopupmenus(handles);
end

return

% --- Executes when selected object is changed in uibuttongroup1.
function uibuttongroup1_SelectionChangedFcn(hObject, eventdata, handles)
% hObject    handle to the selected object in uibuttongroup1
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

if ~get(handles.radiobutton_apt,'Value')
  set(handles.featureconfigpopup,'Enable','on');
  set(handles.text_apt,'Visible','Off');
  set(handles.pushbutton_edit_APT,'Visible','off');
  featureconfigpopup_Callback(handles.featureconfigpopup, eventdata, handles)
  return;
end
% Do stuff if init from APT project is selected
if isfield(handles.basicParamsStruct,'lbl_file') && ...
    ischar(handles.basicParamsStruct.lbl_file),
  defaultlbl_file = handles.basicParamsStruct.lbl_file;
else
  defaultlbl_file = '';
end
debug = false;
if debug
  Q = load('~/temp/aptprojdata');
  aptStruct = Q.qq;
else
  [fname,fpath] = uigetfile('*.lbl','Select APT project File..',defaultlbl_file);
  if fname == 0
    set(handles.radiobutton_apt,'Value',0);
    set(handles.radiobutton_list,'Value',1);
    return;
  end
  % Get the detail of APT
  lbl_file = fullfile(fpath,fname);
  aptStruct = APTProject('lbl_file',lbl_file);
end

if isempty(aptStruct.featureLexicon)
  set(handles.radiobutton_apt,'Value',0);
  set(handles.radiobutton_list,'Value',1);
  return;
end
% Update the GUI.
set(handles.featureconfigpopup,'Enable','off');
set(handles.text_apt,'Visible','On');
set(handles.text_apt,'String',aptStruct.featureLexiconName);
set(handles.pushbutton_edit_APT,'Visible','on');

% Save the current values of the main four fields
% (Note that any changes in the advanced part of the window will be lost.)
behaviorName=handles.basicParamsStruct.behaviors.names;
movieFileName=handles.basicParamsStruct.file.moviefilename;
movieIndexFileName=handles.basicParamsStruct.file.movieindexfilename;
trackFileName=handles.basicParamsStruct.file.trxfilename;
scoreFileName=handles.basicParamsStruct.file.scorefilename;
% Replace basicParamsStruct with one appropriate to the new feature lexicon
% name
old=warning('query','MATLAB:structOnObject');
warning('off','MATLAB:structOnObject');  % turn off annoying warning
handles.basicParamsStruct = struct(Macguffin(handles.basicParamsStruct,aptStruct));
warning(old);  % restore annoying warning
% Now restore fields from the old basicParamsStruct
handles.basicParamsStruct.behaviors.names=behaviorName;
handles.basicParamsStruct.file.moviefilename=movieFileName;
handles.basicParamsStruct.file.movieindexfilename=movieIndexFileName;
handles.basicParamsStruct.file.trxfilename=trackFileName;
handles.basicParamsStruct.file.scorefilename=scoreFileName;
guidata(hObject,handles);
updateConfigTable(handles);
updateEditsListboxesAndPopupmenus(handles);

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

% Hint: get(hObject,'Value') returns toggle state of radiobutton_list

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

% Hint: get(hObject,'Value') returns toggle state of radiobutton_apt

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

% Hint: get(hObject,'Value') returns toggle state of checkbox_st

if ~get(hObject,'Value')
   handles.basicParamsStruct.stFeatures = false;
   guidata(hObject,handles);
   return;
end

fname = uigetdir('.','Select an example JAABA experiment directory');
if fname == 0
  mov_file = '';
  trx_file = '';
  set(hObject,'Value',0);
  return
else
  mov_file = fullfile(fname,handles.basicParamsStruct.file.moviefilename);
  trx_file = fullfile(fname,handles.basicParamsStruct.file.trxfilename);
  if ~exist(mov_file,'file')
      errmsg = sprintf('Movie file %s does not exist',mov_file);
      errordlg(errmsg);
      set(hObject,'Value',0);
      return;
  end
  if ~exist(trx_file,'file'),trx_file=''; end
end

set(handles.figureProjectSetup, 'pointer', 'watch')
[useST,stInfo] = spaceTimeOptions('mov_file',mov_file,...
                    'trx_file',trx_file,...
                    'prev_st',handles.basicParamsStruct.stInfo);

set(handles.figureProjectSetup, 'pointer', 'arrow')
if useST
    handles.basicParamsStruct.stFeatures = true;
    handles.basicParamsStruct.stInfo = stInfo;
else
    handles.basicParamsStruct.stFeatures = false;
    set(hObject,'Value',0);
end
guidata(hObject,handles);

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

% Do stuff if init from APT project is selected
[fname,fpath] = uigetfile('*.lbl','Select APT project File..',handles.basicParamsStruct.aptInfo.lbl_file);
if fname == 0,
  return;
end
% Get the detail of APT
lbl_file = fullfile(fpath,fname);
aptStruct = APTProject('lbl_file',lbl_file,'aptStruct',handles.basicParamsStruct.aptInfo);
if isempty(aptStruct.featureLexicon)
  set(handles.radiobutton_apt,'Value',0);
  set(handles.radiobutton_list,'Value',1);
  return;
end


classdef Builder_DesignVarMonitor_Abstract < handle

    properties (Access = protected)
        monitor
    end

    methods (Access = protected, Abstract)

        createCamera(obj)

    end

    methods (Access = public)

        function build(obj,monitor)
            obj.init(monitor)
            obj.setCamera();
        end

    end

    methods (Access = private)

        function init(obj,monitor)
            obj.monitor = monitor;
        end

        function setCamera(obj)
            cam = obj.createCamera();
            obj.monitor.setCamera(cam);
        end

    end

end


function toggletoolbar(varargin)
%TOGGLETOOLBAR Toggle distribution fit plot toolbar on or off

%   $Revision: 1.1.6.2 $  $Date: 2004/01/24 09:35:56 $
%   Copyright 2003-2004 The MathWorks, Inc.

if (nargin>0 & ishandle(varargin{1}) & ...
               isequal(get(varargin{1},'Type'),'figure'))
   dffig = varargin{1};
else
   dffig = gcbf;
end

tbstate = get(dffig,'toolbar');
h = findall(dffig,'Type','uitoolbar');
if isequal(tbstate,'none') | isempty(h)
   % Create toolbar for the first time
   set(dffig,'toolbar','figure');
   dfadjusttoolbar(dffig);
elseif nargin>1 & isequal(varargin{2},'on')
   % Hide toolbar
   set(h,'Visible','on');
else
   % Show toolbar
   set(h,'Visible','off');
end


function versionPhysio = tapas_physio_version()
% returns version number of this copy of PhysIO
%
%   versionPhysio = tapas_physio_version()
%
% IN
%
% OUT
%
% EXAMPLE
%   tapas_physio_version
%
%   See also

% Author: Lars Kasper
% Created: 2018-10-19
% Copyright (C) 2018 TNU, Institute for Biomedical Engineering,
%                    University of Zurich and ETH Zurich.
%
% This file is part of the TAPAS PhysIO Toolbox, which is released under
% the terms of the GNU General Public License (GPL), version 3. You can
% redistribute it and/or modify it under the terms of the GPL (either
% version 3 or, at your option, any later version). For further details,
% see the file COPYING or <http://www.gnu.org/licenses/>.
%
versionPhysio = 'R2022a-v8.1.0';


function result = cached_argument(name,default)
% Helper: return an arg_nogui() specifier with the given name/default value
% Result = cached_argument(Name,Default)
%
% This function is an optimization for internal use by the argument system.
%
% In:
%   Name : name of the argument
%
%   Default : default value of the argument
%
% Out:
%   Result : an argument specifier struct, with value pre-assigned.
%
%                                Christian Kothe, Swartz Center for Computational Neuroscience, UCSD
%                                2014-02-03

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

persistent keys values;
try
    key = [name '_' char('a'+default)];
    try
        result = values{strcmp(keys,key)};
    catch %#ok<CTCH>
        result = arg_nogui(name,default);
        result = feval(result{1},[],result{2}{:});
        result.value = result.defaults{1};
        if ~iscell(keys)
            keys = {key};
            values = {result};
        else
            keys{end+1} = key;
            values{end+1} = result;
        end
    end
catch %#ok<CTCH>
    result = arg_nogui(name,default);
    result = feval(result{1},[],result{2}{:});
    result.value = result.defaults{1};
end


function microbeID=adaptDraftModelID(modelIDIn)
% This function adapts the name of the draft reconstruction entered into
% the pipeline into a suitable curated reconstruction ID.
%
% USAGE: microbeID = adaptKBaseModelID(modelIDIn)
%
% INPUT
% modelIDIn     name of the KBase draft reconstruction file to refine
%
% OUTPUT
% microbeID     name of the resulting refined reconstruction
%
% AUTHOR: Almut Heinken, 06/2020.

microbeID=modelIDIn;
microbeID=strrep(microbeID,'.fbamodel.sbml','');
microbeID=strrep(microbeID,'.model.sbml','');
microbeID=strrep(microbeID,'___RAST','');
microbeID=strrep(microbeID,'__.RAST','');
microbeID=strrep(microbeID,'_.RAST','');
microbeID=strrep(microbeID,'-.RAST','');
microbeID=strrep(microbeID,'..RAST','');
microbeID=strrep(microbeID,'.RAST','');
microbeID=strrep(microbeID,'_RAST','');
microbeID=strrep(microbeID,'.fna','');
microbeID=strrep(microbeID,'.fa','');
microbeID=strrep(microbeID,'_DraftModel','');
microbeID=strrep(microbeID,'.contigs','');
microbeID=strrep(microbeID,'__genome','');
microbeID=strrep(microbeID,'_genome','');
microbeID=strrep(microbeID,'_assembly','');
microbeID=strrep(microbeID,'.sbml','');
microbeID=strrep(microbeID,'.mat','');
microbeID=strrep(microbeID,' ','_');
microbeID=strrep(microbeID,'.','_');
microbeID=strrep(microbeID,'-','_');
microbeID=strrep(microbeID,'(','_');
microbeID=strrep(microbeID,')','_');
microbeID=strrep(microbeID,'\','_');
microbeID=strrep(microbeID,'/','_');
microbeID=strrep(microbeID,'+','_');
microbeID=strrep(microbeID,'©','_');
microbeID=strrep(microbeID,'____','_');
microbeID=strrep(microbeID,'___','_');
microbeID=strrep(microbeID,'__','_');
microbeID=strrep(microbeID,',','_');
end


function dep = dep_add(cdep, dep, ntgt_input, njtsubs)

% augment cdep tsubs references, and add them to dependency list
%
% This code is part of a batch job configuration system for MATLAB. See
%      help matlabbatch
% for a general overview.
%_______________________________________________________________________
% Copyright (C) 2007 Freiburg Brain Imaging

% Volkmar Glauche
% $Id: dep_add.m 2512 2008-12-01 13:21:29Z volkmar $

rev = '$Rev: 2512 $'; %#ok

for k = 1:numel(cdep)
    cdep(k).tgt_input = [ntgt_input cdep(k).tgt_input];
    cdep(k).jtsubs = [njtsubs cdep(k).jtsubs];
end;
if isempty(dep)
    dep = cdep(:);
else
    dep = [dep(:); cdep(:)];
end;