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

% Last Modified by GUIDE v2.5 01-Apr-2013 01:56:42

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @SelectFeatures_OpeningFcn, ...
                   'gui_OutputFcn',  @SelectFeatures_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 SelectFeatures is made visible.-----------------
function SelectFeatures_OpeningFcn(hObject, eventdata, handles, varargin)  %#ok
% 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 SelectFeatures (see VARARGIN)

% So that we can't be closed before we're done opening
handles.doneWithOpeningFunction = false;
guidata(hObject,handles);

% Process input arguments
figureJLabel = varargin{1};

%
% Populate various aspects that are model-like
%

% Need to keep the parent JLabel's JLabelData object around (a ref to it,
% really), for various annoying reasons
jld = JLabel('getJLabelData',figureJLabel);
handles.jld = jld;

% Get the cached version of maxWindowRadiusCommon out of JLabel
maxWindowRadiusCommonCached= ...
  JLabel('getMaxWindowRadiusCommonCached', ...
         figureJLabel);

% This is the main aspect of the model---the feature vocabulary, in a form
% well-suited to SelectFeatures
featureLexicon = jld.featureLexicon;
scoreFeatures = jld.scoreFeatures;
toBeCalculatedPFNames = jld.allperframefns;
% For now, windowFeatureParams are the same for all JLD classifiers
windowFeatureParams = jld.GetPerframeParams();
assert(iscell(windowFeatureParams) && ~isempty(windowFeatureParams));
assert(all(cellfun(@(x)isequaln(x,windowFeatureParams{1}),...
    windowFeatureParams(2:end))));
windowFeatureParams = windowFeatureParams{1};
handles.featureVocabulary= ...
  FeatureVocabularyForSelectFeatures(featureLexicon, ...
                                     scoreFeatures, ...
                                     toBeCalculatedPFNames, ...
                                     windowFeatureParams, ...
                                     maxWindowRadiusCommonCached);

% initialize histogramData
handles.histogramData = struct;
handles.histogramData.lastPfNdx = nan;
handles.histogramData.lastType = '';
handles.histogramData.perframe_idx = [];
handles.histogramData.hhist = [];
handles.histogramData.frac = {};
handles.histogramData.frac_outside = {};
handles.histogramData.edges = {};
handles.histogramData.centers_plot = {};

% Want to keep this around so we can send a "message" to it when user
% clicks on "Done"
handles.figureJLabel=figureJLabel;

%
% Initialize things that would be part of the View in an MVC arrangement
%

% Set the initial selected per-frame feature and window-feature type
% (indexes to them, actually)
handles.pfNdx = [];
handles.wfTypeNdx = [];

% Compute the figure size in basic and advanced mode, store them
curPos = get(handles.figure_SelectFeatures,'Position');
tablePos = get(handles.basicTable,'Position');
reducedWidth = tablePos(1)+tablePos(3) + 15;
reducedHeight = curPos(4);
handles.advancedSize = curPos(3:4);
handles.basicSize = [reducedWidth reducedHeight];

% Set the initial mode: basic or advanced.  This also sets the figure size
% appropriately.
handles=setViewMode(handles,'basic');

% Center SelectFeatures on the JLabel window
centerOnParentFigure(handles.figure_SelectFeatures,figureJLabel);

% This is the end of initializing the view variables that are not actualy
% graphics objects (although setViewMode() does manipulate some graphics
% objects)

% Commit changes to the figure guidata
guidata(hObject,handles);

%
% Update the graphics objects to match the model and the
% non-graphics-object view instance variables
%

% Change a few things so they still work well on Mac
adjustColorsIfMac(hObject);
% Create the basic table uitable
initializeBasicTable(hObject);
% Put an initial max window radius in the appropriate editbox in the
% "Basic" side of the UI
% And other stuff...
initializeWindowTable(hObject);
initializeCopyFromMenus(hObject);
initializeDescriptionPanels(hObject);
compatibleBasicAdvanced(handles);
%set(hObject,'Visible','on');  % have to do this b/c of Java hacking
initializePfTable(hObject);
%removeRowHeaders(hObject);

% Make sure the graphics items are consistent with the model state
updateMaxWindowRadiusEditBox(handles);
updateWindowTableAndEnablement(handles);
updateWinParamsAndEnablement(handles);

% OK, now it's OK to close the figure
handles=guidata(hObject);
handles.doneWithOpeningFunction=true;
guidata(hObject,handles);

return

% -------------------------------------------------------------------------
% --- Outputs from this function are returned to the command line.
function varargout = SelectFeatures_OutputFcn(hObject, eventdata, 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.figure_SelectFeatures;
return

% % -------------------------------------------------------------------------
% function setJLDobj(hObject,jld)
% % Set the JLabelDataObject.
% handles = guidata(hObject);
% % handles.JLDobj = JLDobj;
%
% % handles.windowComp = {'default','mean','min','max','hist','prctile',...
% %    'change','std','harmonic','diff_neighbor_mean',...
% %    'diff_neighbor_min','diff_neighbor_max','zscore_neighbors'};
% %
% % handles.winextraParams = {'','','','','hist_edges','prctiles','change_window_radii',...
% %   '','num_harmonic','','','',''};
% %
% % handles.winParams = {'max_window_radius','min_window_radius','nwindow_radii',...
% %   'trans_types','window_offsets'};
% %
% % handles.winextraDefaultParams = {[],[],[],[],[-400000 0 40000],[5 10 30 50 70 90 95],[1 3],...
% %   [],[2],[],[],[],[]};
% % handles.defaultWinParams = {10,1,3,{'none'},0};
%
% guidata(hObject,handles);
%
% windowFeatureParams = jld.GetPerframeParams();
% featureLexicon= jld.featureLexicon;
% initData(hObject,windowFeatureParams,featureLexicon,jld);
%
% return

% % -------------------------------------------------------------------------
% % Initialize the data structure.
% function initData(hObject,featureLexicon,jld)
% readFeatureLexicon(hObject,featureLexicon);
% createBasicTable(hObject,jld);
%
% handles = guidata(hObject);
% if ~isempty(jld.featureWindowSize)
%   set(handles.editSize,'String',num2str(jld.featureWindowSize));
% end
%
% % initialize histogramData
% handles.histogramData = struct;
% handles.histogramData.lastPfNdx = nan;
% handles.histogramData.lastType = '';
% handles.histogramData.perframe_idx = [];
% handles.histogramData.hhist = [];
% handles.histogramData.frac = {};
% handles.histogramData.frac_outside = {};
% handles.histogramData.edges = {};
% handles.histogramData.centers_plot = {};
%
% % handles.data = data;
% handles.pfNdx = [];
% handles.wfTypeNdx = [];
% guidata(hObject,handles);
% createPfTable(hObject);
% createWindowTable(hObject);
% createCopyFromMenus(hObject);
% createDescriptionPanels(hObject);
% compatibleBasicAdvanced(handles);
% return

% -------------------------------------------------------------------------
function initializeWindowTable(hObject)
% Sets values for the window table.

handles = guidata(hObject);

% Deal with windowTable
fv=handles.featureVocabulary;
wfTypes=fv.wfTypes;
set(handles.windowTable, ...
    'ColumnName',{'Computation Type','Select'});

% Initialize the table data
nWFTypes=length(wfTypes);
nRows=nWFTypes-1;  % don't want to show 'default' pseudo WF type
windowData = cell(nRows,2);
for rowIndex = 1:nRows
  wfTypeIndex=rowIndex+1;
  wfType = fv.wfTypes{wfTypeIndex};
  windowData{rowIndex,1} = wfType;
  windowData{rowIndex,2} = false;
end
set(handles.windowTable,'Data',windowData);

set(handles.windowTable','ColumnWidth',{135 'auto'});
set(handles.windowTable,'ColumnEditable',[false,true]);
set(handles.windowTable,'CellSelectionCallback',@windowSelect);
set(handles.windowTable,'CellEditCallback',@windowEdit);

return

% -------------------------------------------------------------------------
function initializePfTable(hObject)
% Initialize the per-frame feature table.
handles = guidata(hObject);
set(handles.pfTable,'ColumnName',{'Features','Select','Amount','Category'});
set(handles.pfTable,'ColumnEditable',[false,true,true,false]);
set(handles.pfTable, ...
    'ColumnFormat', ...
    {'char',...
     'logical', ...
     [handles.featureVocabulary.wfAmounts' 'custom'], ...
     'char'} );
set(handles.pfTable,'ColumnWidth',{190,50,75,95});
set(handles.pfTable,'CellSelectionCallback',@pfSelect);
set(handles.pfTable,'CellEditCallback',@pfEdit);

% init the static cols of the table
fv=handles.featureVocabulary;  % a ref
pfNameList = fv.subdialectPFNames;
nPFs=length(pfNameList);
tableData = cell(nPFs,4);
for ndx = 1:nPFs
  tableData{ndx,1} = pfNameList{ndx};
  tableData{ndx,2} = false;  % place-holder
  tableData{ndx,3}='normal';  % place-holder
  pfCategories=fv.pfCategoriesFromName.(pfNameList{ndx});
  str = sprintf('%s',pfCategories{1});
  for sndx = 2:numel(pfCategories)
    str = sprintf('%s,%s',str,pfCategories{sndx});
  end
  tableData{ndx,4} = str;
end
set(handles.pfTable,'Data',tableData);

% Now do an update to properly populate the dynamic cols
updatePFTable(handles);
return

% -------------------------------------------------------------------------
function updatePFTable(handles)
% Updates the contents of the per-frame feature table.

% Generate the table data, based on the feature vocabulary
fv=handles.featureVocabulary;  % a ref
pfList = fv.subdialectPFNames;
nPFs=length(pfList);
tableData=get(handles.pfTable,'Data');
for ndx = 1:nPFs
  tableData{ndx,2} = fv.vocabulary{ndx}.enabled;
  tableData{ndx,3}=fv.getWFAmountForPF(ndx);
end

% Update the graphics object
set(handles.pfTable,'Data',tableData);

% % do Java stuff to select the corrent element
% jscrollpane = findjobj(handles.pfTable);
% jtable = jscrollpane.getViewport.getView;
% pfNdx=handles.pfNdx;
% if isempty(pfNdx)
%   jtable.changeSelection(0,0, false, false);
% else
%   jtable.changeSelection(pfNdx-1,0, false, false);
% end

return

% -------------------------------------------------------------------------
function updatePFTableForCurrentPF(handles)
% Updates the contents of the per-frame feature table, for just the current
% PF.

% Generate the table data, based on the feature vocabulary
fv=handles.featureVocabulary;  % a ref
pfNdx=handles.pfNdx;
% pfList = fv.subdialectPFNames;
% nPFs=length(pfList);
tableData=get(handles.pfTable,'Data');
tableData{pfNdx,2} = fv.vocabulary{pfNdx}.enabled;
tableData{pfNdx,3}=fv.getWFAmountForPF(pfNdx);
set(handles.pfTable,'Data',tableData);

% % do Java stuff to select the current element
% jscrollpane = findjobj(handles.pfTable);
% jtable = jscrollpane.getViewport.getView;
% pfNdx=handles.pfNdx;
% if isempty(pfNdx)
%   jtable.changeSelection(0,0, false, false);
% else
%   jtable.changeSelection(pfNdx-1,0, false, false);
% end

return

% -------------------------------------------------------------------------
function initializeBasicTable(hObject)
handles = guidata(hObject);

% Set the simple parts of the uitable
set(handles.basicTable,'ColumnName',{'Categories','Select','Amount'});
set(handles.basicTable, ...
    'ColumnFormat', ...
    {'char',...
     {'all' 'none' 'custom'}, ...
     [handles.featureVocabulary.wfAmounts' 'custom']} );
set(handles.basicTable,'ColumnEditable',[false,true,true]);
set(handles.basicTable,'ColumnWidth',{85,65,75});
set(handles.basicTable,'CellSelectionCallback',@basicSelect);
set(handles.basicTable,'CellEditCallback',@basicEdit);

% Get a list of the categories that actually have PFs in them (e.g. scores
% category often has no PFs in it)
fv=handles.featureVocabulary;
pfCategoryNames=fv.pfCategoryNames;
categoryIsNonEmpty= ...
  @(pfCategoryName)(~isempty(fv.getPFNamesInCategory(pfCategoryName)));
pfCategoryNamesNonEmpty= ...
  cellFilter(categoryIsNonEmpty,pfCategoryNames);

% Populate the static parts of the table cells
nPFCategoriesNonEmpty=length(pfCategoryNamesNonEmpty);
tableData = cell(nPFCategoriesNonEmpty,3);
for i = 1:nPFCategoriesNonEmpty
  tableData{i,1} = pfCategoryNamesNonEmpty{i};
  tableData{i,2} = 'none';  % placeholder
  tableData{i,3} = 'normal';  % placeholder
end
set(handles.basicTable,'Data',tableData);

% Call update to populate the dynamic parts of the table
updateBasicTable(handles);
return

% -------------------------------------------------------------------------
function updateBasicTable(handles)
fv=handles.featureVocabulary;
tableData = get(handles.basicTable,'Data');
pfCategoryNames=tableData(:,1);  % these are the nonempty categories
nPFCategories=length(pfCategoryNames);
for i=1:nPFCategories
  pfCategoryName=pfCategoryNames{i};
  tableData{i,2} = fv.getPFCategoryLevel(pfCategoryName);
  tableData{i,3} = fv.getWFAmountForPFCategory(pfCategoryName);
end
set(handles.basicTable,'Data',tableData);
return

% % -------------------------------------------------------------------------
% function updateBasicTableOnePFCategory(handles,pfCategoryName)
% fv=handles.featureVocabulary;
% pfCategoryList=fv.pfCategoryNames;
% pfCategoryIndex=find(strcmp(pfCategoryName,pfCategoryList));
% tableData = get(handles.basicTable,'Data');
% tableData{pfCategoryIndex,2} = fv.getPFCategoryLevel(pfCategoryName);
% tableData{pfCategoryIndex,3} = fv.getWFAmountForPFCategory(pfCategoryName);
% set(handles.basicTable,'Data',tableData);
% return

% -------------------------------------------------------------------------
function updateBasicTableAllCategoriesOfCurrentPF(handles)
fv=handles.featureVocabulary;
pfNameList=fv.subdialectPFNames;
pfName=pfNameList{handles.pfNdx};
pfCategoriesThisName=fv.pfCategoriesFromName.(pfName);
allPFCategories=fv.pfCategoryNames;
pfCategoryIndicesThisName = find(ismember(allPFCategories,pfCategoriesThisName));
basicData = get(handles.basicTable,'Data');
pfCategoryNamesInTable=basicData(:,1);
for i = 1:numel(pfCategoryIndicesThisName)
  pfCategoryName=pfCategoriesThisName{i};
  rowIndex=find(strcmp(pfCategoryName,pfCategoryNamesInTable));
  basicData{rowIndex,2} = fv.getPFCategoryLevel(pfCategoryName);
  basicData{rowIndex,3} = fv.getWFAmountForPFCategory(pfCategoryName);
end
set(handles.basicTable,'Data',basicData);
return

% % -------------------------------------------------------------------------
% function initializeMaxWindowRadiusEditBox(handles,maxWindowRadius)
% if ~isempty(maxWindowRadius)
%   % set the global maxWindowRadius to the given value
%   fv=handles.featureVocabulary;
%   fv.setMaxWindowRadiusForAllWFs(maxWindowRadius);
%   fv.setMaxWindowRadiusForAllWFAmounts(maxWindowRadius);
% end
% % Update the view
% updateMaxWindowRadiusEditBox(handles);
% return

% -------------------------------------------------------------------------
function updateMaxWindowRadiusEditBox(handles)
fv=handles.featureVocabulary;
[thereIsConsensus,maxWindowRadiusConsensus]= ...
  fv.getConsensusMaxWindowRadiusForAllWFs();
if thereIsConsensus ,
  set(handles.editSize,'String',num2str(maxWindowRadiusConsensus), ...
                       'FontAngle','normal');
else
  set(handles.editSize,'String','Custom', ...
                       'FontAngle','italic');
end
return

% % -------------------------------------------------------------------------
% function removeRowHeaders(hObject)
% % Tweaking the table. Use underlying java objects to do that. Found
% % this at http://undocumentedmatlab.com/blog/uitable-sorting/
%
% handles = guidata(hObject);
%
% % Basic Table
% jscrollpane = findjobj(handles.basicTable);
% jtable = jscrollpane.getViewport.getView;
% jtable.setSortable(false);
% jtable.setAutoResort(false);
% jtable.setMultiColumnSortable(true);
%
% % Set the size for the row headers.
% rowHeaderViewport=jscrollpane.getComponent(4);
% rowHeader=rowHeaderViewport.getComponent(0);
% newWidth=0;
% rowHeaderViewport.setPreferredSize(java.awt.Dimension(newWidth,0));
% height=rowHeader.getHeight;
% rowHeader.setPreferredSize(java.awt.Dimension(newWidth,height));
% rowHeader.setSize(newWidth,height);
%
% % Pf Table.
% jscrollpane = findjobj(handles.pfTable);
% jtable = jscrollpane.getViewport.getView;
% jtable.setSortable(false);
% jtable.setAutoResort(false);
% jtable.setMultiColumnSortable(false);
%
% % Set the size for the row headers.
% rowHeaderViewport=jscrollpane.getComponent(4);
% rowHeader=rowHeaderViewport.getComponent(0);
% newWidth=0;
% rowHeaderViewport.setPreferredSize(java.awt.Dimension(newWidth,0));
% height=rowHeader.getHeight;
% rowHeader.setPreferredSize(java.awt.Dimension(newWidth,height));
% rowHeader.setSize(newWidth,height);
%
% % Window Table.
% jscroll=findjobj(handles.windowTable);
% rowHeaderViewport=jscroll.getComponent(4);
% rowHeader=rowHeaderViewport.getComponent(0);
% rowHeader.setSize(80,360);
%
% %resize the row header
% newWidth=0; %100 pixels.
% rowHeaderViewport.setPreferredSize(java.awt.Dimension(newWidth,0));
% height=rowHeader.getHeight;
% rowHeader.setPreferredSize(java.awt.Dimension(newWidth,height));
% rowHeader.setSize(newWidth,height);
% return

% -------------------------------------------------------------------------
function initializeCopyFromMenus(hObject)

handles = guidata(hObject);
% can copy from any window feature type
fv=handles.featureVocabulary;
wfTypes=fv.wfTypes;
pfNameList=fv.subdialectPFNames;
set(handles.popupmenu_copy_windowparams, ...
    'String',[wfTypes,{'---'}],...
    'Value',numel(wfTypes)+1);
% can copy from any per-frame feature
set(handles.popupmenu_copy_windowtypes, ...
    'String',[pfNameList;{'---'}],...
    'Value',numel(pfNameList)+1);
return

% -------------------------------------------------------------------------
function initializeDescriptionPanels(hObject)

handles = guidata(hObject);

% which tab to show
handles.currentTab = 'perframehistogram';
set(handles.togglebutton_tabperframehistogram,'Value',1);

% set visibility
uipanel_tabs_SelectionChangeFcn(handles.uipanel_tabs, struct('NewValue',handles.togglebutton_tabdescription), handles);

guidata(hObject,handles);

% -------------------------------------------------------------------------
function basicSelect(hObject,eventData)  %#ok
return

% -------------------------------------------------------------------------
function basicEdit(hObject,eventData)
% the user selects the category
if isempty(eventData.Indices); return; end
oldPointer=pointerToWatch(hObject);
if eventData.Indices(2)==2
  % User made a selection in the 2nd column, to select 'all' or 'none' of
  % the PFs in that category.  They can also select 'custom', but that does
  % nothing.
  pfCategoryLevelChanged(hObject,eventData);
elseif eventData.Indices(2) == 3
  pfCategoryWFAmountChanged(hObject,eventData);
end
restorePointer(hObject,oldPointer);
return

% -------------------------------------------------------------------------
function pfCategoryLevelChanged(hObject,eventData)
  % User selected the level (all, none, custom) for a PF category in the
  % basic table.  Note that custom will be ignored, and the level will be
  % changed back to what it was before.
  handles = guidata(hObject);
  fv=handles.featureVocabulary;  % a ref
  rowIndex=eventData.Indices(1);
  basicData = get(handles.basicTable,'Data');
  pfCategoryName=basicData{rowIndex,1};
  wfAmount=basicData{rowIndex,3};
  newLevel=eventData.NewData;
  switch newLevel
    case 'none'
      h = waitbar(0,'Unselecting the perframe features');
      pfNames=fv.getPFNamesInCategory(pfCategoryName);
      for i = 1:length(pfNames)
        fv.disablePerframeFeature(pfNames{i});
      end
      close(h);
    case 'all'
      h = waitbar(0,'Selecting the perframe features');
      if ~isequal(wfAmount,'custom')
        fv.setAllPFsInCategoryToWFAmount(pfCategoryName,wfAmount);
      end
      fv.enableAllPFsInCategory(pfCategoryName);
      close(h);
    case 'custom'
      % don't change the model at all---the custom item is only there for
      % when the user adds/deletes individual PFs using the Advanced tab.
  end
  guidata(hObject,handles);
  updateBasicTable(handles);
  updatePFTable(handles);
  updateWindowTableAndEnablement(handles);
  updateWinParamsEnablement(handles);
return

% -------------------------------------------------------------------------
function pfCategoryWFAmountChanged(hObject,eventData)
  % User selected the window-feature
  % amount for a PF category, in the basic table.  Note that selecting
  % 'custom' does nothing.
  handles = guidata(hObject);
  fv=handles.featureVocabulary;  % a ref
  rowIndex=eventData.Indices(1);
  basicData=get(handles.basicTable,'Data');
  pfCategoryName=basicData{rowIndex,1};
  newWFAmount=eventData.NewData;
  if ~isequal(newWFAmount,'custom'),
    fv.setAllPFsInCategoryToWFAmount(pfCategoryName,newWFAmount);
  end
  updateBasicTable(handles);
  updatePFTable(handles);
  updateWindowTableAndEnablement(handles);
  updateWinParamsAndEnablement(handles);
return

% % -------------------------------------------------------------------------
% function handles = applyCategoryType(handles,iSelectedCategory)
% % get some variables out of handles
% basicData = get(handles.basicTable,'Data');
% wfAmount = basicData{iSelectedCategory,3};
%   % The amount of window features to use.  Can be 'normal', 'more', or
%   % 'less'
% fv=handles.featureVocabulary;
% selectedCategory = handles.pfCategoryNames{iSelectedCategory};
% pfList=handles.pfList;
% pfCategoriesFromName=handles.pfCategoriesFromName;
% % Copy the parameters.
% % Iterate over the per-frame features, looking for ones that are
% % within the selected category.
% for iPF = 1:numel(pfList)
%   thisPF=pfList{iPF};
%   categoriesThisPFIsIn=pfCategoriesFromName.(thisPF);
%   if ismember(selectedCategory,categoriesThisPFIsIn)
%     % if the selected category contains this per-frame feature,
%     % do something...
%     handles.data{iPF}.valid = true;
%     for winfnNdx = 1:numel(fv.wfTypes)
%       curFn = fv.wfTypes{winfnNdx};
%       if ~handles.wfParamsFromAmount.(wfAmount).(curFn).valid
%         handles.data{iPF}.(curFn).valid = false;
%         continue;
%       end
%       handles = CopyDefaultWindowParams(handles,...
%                                         wfAmount, iPF, winfnNdx);
%       curFn = fv.wfTypes{winfnNdx};
%       handles.data{iPF}.(curFn).values.trans_types = handles.transType.(pfList{iPF});
%     end
%   end
% end

% -------------------------------------------------------------------------
function compatibleBasicAdvanced(handles)
% What does this do?  --ALT, Mar 31, 2013
basicTable = get(handles.basicTable,'Data');
incompatible = '';
fv=handles.featureVocabulary;
pfNameList=fv.subdialectPFNames;
for ndx = 1:numel(pfNameList)
  pfName=pfNameList{ndx};
  pfCategories=fv.pfCategoriesFromName.(pfName);
  selected = false;
  for bndx = 1:size(basicTable,1)
    if ~any(strcmp(pfCategories,basicTable{bndx,1})),
      continue;
    end
    if strcmpi(basicTable{bndx,2},'all')
       selected = true;
    end
    if selected && ~fv.pfIsInVocabulary(ndx)
      incompatible = sprintf('%s %s', incompatible,pfNameList{ndx});
    end

  end
end
if numel(incompatible)>0
  uiwait(warndlg(sprintf('Perframe feature(s) %s are not selected but should have been based on the category selection',incompatible),...
    'Mismatch in categories and perframe features'));
end

% -------------------------------------------------------------------------
function pfSelect(hObject,eventData)
% Called when user selects cells in the per-frame feature table.

% fprintf('pfSelect() called.\n');
if isempty(eventData.Indices)
  return;
end

oldPointer=pointerToWatch(hObject);

handles = guidata(hObject);

%pfData = get(handles.pfTable,'Data');

if size(eventData.Indices,1)>1 ,
  % If multiple elements have been selected, select none of the PFs,
  % because, you know, what the hell are we supposed to do with that?
  handles.pfNdx=[];
  %disableWindowTable(handles);
else
  % the usual case---a single cell is selected
  pfNdx = eventData.Indices(1,1);
  handles.pfNdx = pfNdx;
end
handles = UpdateDescriptionPanels(handles);
guidata(hObject,handles);
updateWindowTableAndEnablement(handles);
updateWinParamsAndEnablement(handles);
restorePointer(hObject,oldPointer);

return

% -------------------------------------------------------------------------
function pfEdit(hObject,eventData)
% Called when a perframe feature is added or removed in the pfTable.

oldPointer=pointerToWatch(hObject);

% Update the figure guidata
handles = guidata(hObject);

pfNdx = eventData.Indices(1,1);
handles.pfNdx = pfNdx;
guidata(hObject,handles);

% Call the appropriate sub-handler
tableColumnIndex=eventData.Indices(2);
if tableColumnIndex==2,
  % User edited the enable/disable column
  pfEnablementChanged(handles,eventData);
elseif tableColumnIndex==3,
  % User edited the amount column
  pfAmountChanged(handles,eventData);
end

restorePointer(hObject,oldPointer);

return

% -------------------------------------------------------------------------
function pfEnablementChanged(handles,eventData)
  % This is a "private" "method" of the "controller".
  fv=handles.featureVocabulary;  % a ref
  pfIndex=eventData.Indices(1);
  enabled=eventData.NewData;
  fv.setPFEnablement(pfIndex,enabled);
  % Now update the view
  updateBasicTable(handles);
  updateWindowTableAndEnablement(handles);
  updateWinParamsAndEnablement(handles);
return

% -------------------------------------------------------------------------
function pfAmountChanged(handles,eventData)
  % This is a "private" "method" of the "controller".
  fv=handles.featureVocabulary;  % a ref
  pfIndex=eventData.Indices(1);
  newWFAmount=eventData.NewData;
  fv.setPFToWFAmount(pfIndex,newWFAmount);
  % Now update the view
  updatePFTableForCurrentPF(handles);
  updateBasicTable(handles);
  updateWindowTableAndEnablement(handles);
  updateWinParamsAndEnablement(handles);
return

% -------------------------------------------------------------------------
function updateWindowTableAndEnablement(handles)
updateWindowTable(handles);
updateWindowTableEnablement(handles);
return

% -------------------------------------------------------------------------
function updateWindowTable(handles)
% Sets the data in window table based on selections made in pfTable.
pfNdx=handles.pfNdx;
fv=handles.featureVocabulary;
nWFTypes=length(fv.wfTypes);
%windowData = cell(nWFTypes,2);
windowData=get(handles.windowTable,'Data');
if isempty(pfNdx) ,
  pfParams=struct([]);  % empty struct with no fields
else
  pfParams = fv.vocabulary{pfNdx};
end
nRows=nWFTypes-1; % b/c default not shown
for rowIndex = 1:nRows
  wfTypeIndex=rowIndex+1;
  wfType = fv.wfTypes{wfTypeIndex};
  if isfield(pfParams,wfType),
    %windowData{wfTypeIndex,1} = wfType;
    windowData{rowIndex,2} = pfParams.(wfType).enabled;
  else
    % warning('This error is occurring!');
      % this isn't an error anymore -- it can happen by design if pfNdx is
      % empty
    %windowData{wfTypeIndex,1} = wfType;
    windowData{rowIndex,2} = false;
  end
end
set(handles.windowTable,'Data',windowData);
% jscrollpane = findjobj(handles.windowTable);
% jtable = jscrollpane.getViewport.getView;
% wfTypeNdx=handles.wfTypeNdx;
% if isempty(wfTypeNdx)
%   jtable.changeSelection(0,0, false, false);
% else
%   jtable.changeSelection(wfTypeNdx-1,0, false, false);
% end
return

% -------------------------------------------------------------------------
function updateWindowTableRow(handles,rowIndex)
% Updates the checkbox for wfType wfTypeIndex, i.e. one row of the window
% table.
wfTypeIndex=rowIndex+1;  % b/c 'default' not shown
pfNdx=handles.pfNdx;
fv=handles.featureVocabulary;
pfParams = fv.vocabulary{pfNdx};
windowData = get(handles.windowTable,'Data');
wfType = fv.wfTypes{wfTypeIndex};
if ~isfield(pfParams,wfType),
  warning('This error is occurring!');
  windowData{rowIndex,2} = false;
else
  windowData{rowIndex,2} = pfParams.(wfType).enabled;
end
set(handles.windowTable,'Data',windowData);
return

% -------------------------------------------------------------------------
function windowSelect(hObject,eventData)
% Called when user selects cells in windowTable.
% Also seems to get called when the windowTable has been disabled and then
% gets enabled...
%fprintf('In windowSelect()\n');

% When something changes in the pfTable window.
if isempty(eventData.Indices)
  return;
end

oldPointer=pointerToWatch(hObject);

handles = guidata(hObject);
%winData = get(handles.windowTable,'Data');

if (size(eventData.Indices,1)>1)
  % If more than one cell selected, just don't even try to deal.
  handles.wfTypeNdx = [];
  %disableWinParams(handles);
else
  rowIndex = eventData.Indices(1,1);
  handles.wfTypeNdx = rowIndex+1;  % +1 b/c default is not shown
%   if winData{ndx,2},
%     updateWinParams(handles);
%     enableWinParams(handles);
%   else
%     disableWinParams(handles);
%   end
end
guidata(hObject,handles);
updateWinParamsAndEnablement(handles);
restorePointer(hObject,oldPointer);
return

% -------------------------------------------------------------------------
function windowEdit(hObject,eventData)
% Called when the window-feature type uitable is edited.

oldPointer=pointerToWatch(hObject);

handles = guidata(hObject);
fv=handles.featureVocabulary;  % a ref
%updatePFCategoryAmountForCurrentPF(handles);
rowIndex=eventData.Indices(1);
wfTypeNdx = rowIndex+1;  % +1 b/c default is not shown
handles.wfTypeNdx = wfTypeNdx;
wfType = fv.wfTypes{wfTypeNdx};
%handles.data{handles.pfNdx}.(wfType).enabled = eventData.NewData;

% Enable/disable the selected window-feature type in the model
% Unless the the window-feature type is 'default', which cannot be disabled
% except by disabling the per-frame feature
if ~isequal(wfType,'default')
  pfNdx=handles.pfNdx;
  pfName=fv.subdialectPFNames{pfNdx};
  fv.setWFTypeEnablement(pfName,wfType,eventData.NewData)
end

guidata(hObject,handles);
updateWindowTableRow(handles,rowIndex)
updateWinParamsAndEnablement(handles);
updatePFTableForCurrentPF(handles);
updateBasicTableAllCategoriesOfCurrentPF(handles);
% if eventData.NewData
%   updateWinParams(handles);
%   enableWinParams(handles);
% else
%   disableWinParams(handles);
% end
restorePointer(hObject,oldPointer);
return

% % -------------------------------------------------------------------------
% function updateBasicTablePFCategoryLevel(handles,pfCategoryIndex)
% % Update the amount displayed for a particular per-frame feature category
% % in the basic table.
% fv=handles.featureVocabulary;
% pfCategoryName=fv.pfCategoryNames{pfCategoryIndex};
% basicData = get(handles.basicTable,'Data');
% basicData{pfCategoryIndex,2} = fv.getPFCategoryLevel(pfCategoryName);
% set(handles.basicTable,'Data',basicData);
% return

% -------------------------------------------------------------------------
function updateWinParams(handles)
% Update the GUI controls displaying window-feature parameters to match the current
% model state.

pfNdx=handles.pfNdx;
winNdx=handles.wfTypeNdx;
if isempty(pfNdx) || isempty(winNdx),
  set(handles.MinWindow,'String','');
  set(handles.MaxWindow,'String','');
  set(handles.WindowStep,'String','');
  set(handles.WindowOffsets,'String','');
  set(handles.TransNone,'Value',false);
  set(handles.TransFlip,'Value',false);
  set(handles.TransAbs,'Value',false);
  set(handles.TransRel,'Value',false);
  set(handles.ExtraParams,'String','');
  set(handles.extraParamStatic,'String','No extra params','FontAngle','italic');
else
  fv=handles.featureVocabulary;
  wfType = fv.wfTypes{winNdx};
  wfParamsThisType = fv.vocabulary{pfNdx}.(wfType);
  set(handles.MinWindow,'String',num2str(wfParamsThisType.values.min_window_radius));
  set(handles.MaxWindow,'String',num2str(wfParamsThisType.values.max_window_radius));
  set(handles.WindowStep,'String',num2str(wfParamsThisType.values.nwindow_radii));
  set(handles.WindowOffsets,'String',num2str(wfParamsThisType.values.window_offsets));
  set(handles.TransNone,'Value',...
      any(strcmp('none',wfParamsThisType.values.trans_types)));
      %bitand(1,curParams.values.trans_types));
  set(handles.TransFlip,'Value',...
      any(strcmp('flip',wfParamsThisType.values.trans_types)));
      %bitand(4,curParams.values.trans_types));
  set(handles.TransAbs,'Value',...
      any(strcmp('abs',wfParamsThisType.values.trans_types)));
      %bitand(2,curParams.values.trans_types));
  set(handles.TransRel,'Value',...
      any(strcmp('relative',wfParamsThisType.values.trans_types)));
      %bitand(8,curParams.values.trans_types));
  if isfield(wfParamsThisType.values,fv.wfExtraParamNames{winNdx})
    extraParam = fv.wfExtraParamNames{winNdx};
    set(handles.ExtraParams, ...
        'String',wfParamsThisType.values.(extraParam));
    set(handles.extraParamStatic, ...
        'String',extraParam, ...
        'FontAngle','normal');
  else
    set(handles.ExtraParams,'String','');
    set(handles.extraParamStatic,'String','No extra params','FontAngle','italic');
    % set(handles.ExtraParams,'Enable','off','String','--');
    % set(handles.extraParamStatic,'String','Feature Specific');
  end
end
return

% -------------------------------------------------------------------------
function updateWinParamsAndEnablement(handles)
% Update the GUI controls displaying window-feature parameters to match the current
% model state, and also the enablement/disablement of these controls.
updateWinParams(handles);
updateWinParamsEnablement(handles)
return

% % -------------------------------------------------------------------------
% function windowFeatureParams = convertData(handles)
% % Converts the data into format used by JLabelData.
%
% fv=handles.featureVocabulary;
%
% windowFeatureParams = struct;
%
% for ndx = 1:numel(handles.pfList)
%   curPf = handles.pfList{ndx};
%   if ~fv.vocabulary{ndx}.valid; continue;end
%   curD = fv.vocabulary{ndx};
%   windowFeatureParams.(curPf).sanitycheck = curD.sanitycheck;
%
%   for winParamsNdx = 1:numel(handles.winParams)
%     curType = handles.winParams{winParamsNdx};
%     windowFeatureParams.(curPf).(curType) = curD.default.values.(curType);
%   end
%
%   for winfnNdx = 2:numel(fv.wfTypes)
%     curFn = fv.wfTypes{winfnNdx};
%
%     if curD.(curFn).valid,
%       for winParamsNdx = 1:numel(handles.winParams)
%         curType = handles.winParams{winParamsNdx};
%         windowFeatureParams.(curPf).(curFn).(curType) =...
%             curD.(curFn).values.(curType);
%       end
%       if ~isempty(fv.wfExtraParamNames{winfnNdx})
%         extraParam = fv.wfExtraParamNames{winfnNdx};
%         extraParamVal = curD.(curFn).values.(extraParam);
%         windowFeatureParams.(curPf).(curFn).(extraParam) = extraParamVal;
%       end
%     end
%
%   end
%
% end
%
% return

% -------------------------------------------------------------------------
function docNode = createParamsXML(params,basicData,inFeatureWindowSize)
docNode = com.mathworks.xml.XMLUtils.createDocument('configuration');
toc = docNode.getDocumentElement;
basicStruct = struct;
for ndx = 1:size(basicData,1)
  curCat = basicData{ndx,1};
  basicStruct.(curCat).mode = basicData{ndx,2};
  basicStruct.(curCat).selection = basicData{ndx,3};
end
featureWindowSize = struct;
featureWindowSize.size = inFeatureWindowSize;
toc.appendChild(createXMLNode(docNode,'basicParams',basicStruct));
toc.appendChild(createXMLNode(docNode,'featureWindowSize',featureWindowSize));
toc.appendChild(createXMLNode(docNode,'params',params));

% att = fieldnames(params);
% for ndx = 1:numel(att)
%   toc.appendChild(createXMLNode(docNode,att{ndx},params.(att{ndx})));
% end
return

% % -------------------------------------------------------------------------
% function disableWindowTable(handles)
% set(handles.windowTable,'enable','off');
% set(handles.pushbutton_copy_windowtypes,'enable','off');
% disableWinParams(handles);
%
%
% % -------------------------------------------------------------------------
% function enableWindowTable(handles)
% set(handles.windowTable,'enable','on');
% set(handles.pushbutton_copy_windowtypes,'enable','on');

% -------------------------------------------------------------------------
function updateWindowTableEnablement(handles)
fv=handles.featureVocabulary;  % a ref
pfNdx=handles.pfNdx;
if isempty(pfNdx)
  enabled=false;
else
  enabled=fv.pfIsInVocabulary(pfNdx);
end
set(handles.windowTable,'enable',onIff(enabled));
set(handles.pushbutton_copy_windowtypes,'enable',onIff(enabled));
set(handles.popupmenu_copy_windowtypes,'enable',onIff(enabled));
return

% -------------------------------------------------------------------------
function updateWinParamsEnablement(handles)
pfNdx=handles.pfNdx;
wfTypeNdx=handles.wfTypeNdx;
if isempty(pfNdx) || isempty(wfTypeNdx),
  disableWinParams(handles);
else
  fv=handles.featureVocabulary;   % a ref
  %pfInVocab=fv.pfIsInVocabulary(pfNdx);
  %wfTypeInVocab=fv.wfTypeIsInVocabulary(pfNdx,wfTypeNdx);
  if fv.pfIsInVocabulary(pfNdx) && ...
     fv.wfTypeIsInVocabulary(pfNdx,wfTypeNdx) ,
    enableWinParams(handles);
  else
    disableWinParams(handles);
  end
end
return

% -------------------------------------------------------------------------
function disableWinParams(handles)
% fprintf('In disableWinParams()\n');
set(handles.MinWindow,'enable','off');
set(handles.MaxWindow,'enable','off');
set(handles.WindowStep,'enable','off');
set(handles.WindowOffsets,'enable','off');
set(handles.TransNone,'enable','off');
set(handles.TransFlip,'enable','off');
set(handles.TransAbs,'enable','off');
set(handles.TransRel,'enable','off');
set(handles.ExtraParams,'enable','off');
set(handles.popupmenu_copy_windowparams,'enable','off');
set(handles.pushbutton_copy_windowparams,'enable','off');
return

% -------------------------------------------------------------------------
function enableWinParams(handles)
%defBack = get(handles.text5,'BackgroundColor');
%defFore = [0 0 0];
set(handles.MinWindow,'enable','on');%,'BackgroundColor',defBack,'ForegroundColor',defFore);
set(handles.MaxWindow,'enable','on');%,'BackgroundColor',defBack,'ForegroundColor',defFore);
set(handles.WindowStep,'enable','on');%,'BackgroundColor',defBack,'ForegroundColor',defFore);
set(handles.WindowOffsets,'enable','on');%,'BackgroundColor',defBack,'ForegroundColor',defFore);

fv=handles.featureVocabulary;   % a ref
if ~isempty(fv.wfExtraParamNames{handles.wfTypeNdx})
  set(handles.ExtraParams,'enable','on');
  %set(handles.extraParamStatic,'String',fv.wfExtraParamNames{handles.wfTypeNdx});
else
  set(handles.ExtraParams,'enable','off');
  %set(handles.extraParamStatic,'String','');
end

set(handles.TransNone,'enable','on');
set(handles.TransFlip,'enable','on');
set(handles.TransAbs,'enable','on');
set(handles.TransRel,'enable','on');
set(handles.popupmenu_copy_windowparams,'enable','on');
set(handles.pushbutton_copy_windowparams,'enable','on');
return

% -------------------------------------------------------------------------
function MinWindow_Callback(hObject, eventdata, handles)  %#ok
% hObject    handle to MinWindow (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 MinWindow as text
%        str2double(get(hObject,'String')) returns contents of MinWindow as a double
curVal = str2double(get(hObject,'String'));
if isnan(curVal)||(round(curVal)-curVal)~=0
  msgbox('Enter numerical values');
end
handles = guidata(hObject);
fv=handles.featureVocabulary;
%wfType = fv.wfTypes{handles.wfTypeNdx};
%handles.data{handles.pfNdx}.(wfType).values.min_window_radius = curVal;

% set in featureVocabulary
pfName=fv.subdialectPFNames{handles.pfNdx};
wfType = FeatureVocabularyForSelectFeatures.wfTypes{handles.wfTypeNdx};
wfParamName='min_window_radius';
fv.setWFParam(pfName,wfType,wfParamName,curVal);

guidata(hObject,handles);
updateBasicTableAllCategoriesOfCurrentPF(handles);
updatePFTableForCurrentPF(handles);
return

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

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

% -------------------------------------------------------------------------
function MaxWindow_Callback(hObject, eventdata, handles)  %#ok
% hObject    handle to MaxWindow (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 MaxWindow as text
%        str2double(get(hObject,'String')) returns contents of MaxWindow as a double
curVal = str2double(get(hObject,'String'));
if isnan(curVal)||(round(curVal)-curVal)~=0
  msgbox('Enter numerical values');
end
handles = guidata(hObject);
fv=handles.featureVocabulary;
wfType = fv.wfTypes{handles.wfTypeNdx};
%handles.data{handles.pfNdx}.(wfType).values.max_window_radius = curVal;

% set in featureVocabulary
pfName=fv.subdialectPFNames{handles.pfNdx};
%wfType = FeatureVocabularyForSelectFeatures.wfTypes{handles.wfTypeNdx};
wfParamName='max_window_radius';
fv.setWFParam(pfName,wfType,wfParamName,curVal);

guidata(hObject,handles);
updateMaxWindowRadiusEditBox(handles);
updateBasicTableAllCategoriesOfCurrentPF(handles);
updatePFTableForCurrentPF(handles);
return

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

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

% -------------------------------------------------------------------------
function WindowStep_Callback(hObject, eventdata, handles)  %#ok
% hObject    handle to WindowStep (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 WindowStep as text
%        str2double(get(hObject,'String')) returns contents of WindowStep as a double
curVal = str2double(get(hObject,'String'));
if isnan(curVal) || (round(curVal)-curVal)~=0
  msgbox('Enter an integer value');
end
handles = guidata(hObject);
fv=handles.featureVocabulary;
wfType = fv.wfTypes{handles.wfTypeNdx};
%handles.data{handles.pfNdx}.(wfType).values.nwindow_radii = curVal;

% set in featureVocabulary
pfName=fv.subdialectPFNames{handles.pfNdx};
%wfType = FeatureVocabularyForSelectFeatures.wfTypes{handles.wfTypeNdx};
wfParamName='nwindow_radii';
fv.setWFParam(pfName,wfType,wfParamName,curVal);

guidata(hObject,handles);
updateBasicTableAllCategoriesOfCurrentPF(handles);
updatePFTableForCurrentPF(handles);
return

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

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

% -------------------------------------------------------------------------
function WindowOffsets_Callback(hObject, eventdata, handles)  %#ok
% hObject    handle to WindowOffsets (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 WindowOffsets as text
%        str2double(get(hObject,'String')) returns contents of WindowOffsets as a double
curVal = str2double(get(hObject,'String'));
if isempty(curVal)
  msgbox('Enter numerical values. eg: "-1 0 1" (without with quotes)');
end
handles = guidata(hObject);
fv=handles.featureVocabulary;
wfType = fv.wfTypes{handles.wfTypeNdx};
%handles.data{handles.pfNdx}.(wfType).values.window_offsets = curVal;

% set in featureVocabulary
pfName=fv.subdialectPFNames{handles.pfNdx};
%wfType = FeatureVocabularyForSelectFeatures.wfTypes{handles.wfTypeNdx};
wfParamName='window_offsets';
fv.setWFParam(pfName,wfType,wfParamName,curVal);

guidata(hObject,handles);
updateBasicTableAllCategoriesOfCurrentPF(handles);
updatePFTableForCurrentPF(handles);
return

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

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

% -------------------------------------------------------------------------
% --- Executes on button press in TransNone.
function TransNone_Callback(hObject, eventdata, handles)  %#ok
% hObject    handle to TransNone (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 TransNone
fv=handles.featureVocabulary;
%curFn = fv.wfTypes{handles.wfTypeNdx};
handles = guidata(hObject);
% curT = handles.data{handles.pfNdx}.(curFn).values.trans_types;
% if get(hObject,'Value')
%   %curT=bitor(1,curT);
%   if ~any(strcmp('none',curT))
%    handles.data{handles.pfNdx}.(curFn).values.trans_types{end+1} = 'none';
%   end
% else
% %   curT=bitand(14,curT);
%   allNdx = strcmp('none',curT);
%   handles.data{handles.pfNdx}.(curFn).values.trans_types(allNdx) = [];
%   if isempty(handles.data{handles.pfNdx}.(curFn).values.trans_types),
% %  if handles.data{handles.pfNdx}.(curFn).values.trans_types==0,
%     warndlg('Select at least one transformation type');
%   end
% end

% update featureVocabulary
pfName=fv.subdialectPFNames{handles.pfNdx};
wfType = fv.wfTypes{handles.wfTypeNdx};
transformation='none';
if get(hObject,'Value')
  fv.addWFTransformation(pfName,wfType,transformation);
else
  fv.removeWFTransformation(pfName,wfType,transformation);
end
% Update the translation checkbox to reflect the model (the change can fail
% to happen if the user is trying to turn off the only transformation)
checked=fv.isWFTransformation(pfName,wfType,transformation);
set(hObject,'Value',checked);

guidata(hObject,handles);
updateBasicTableAllCategoriesOfCurrentPF(handles);
updatePFTableForCurrentPF(handles);
return

% -------------------------------------------------------------------------
% --- Executes on button press in TransFlip.
function TransFlip_Callback(hObject, eventdata, handles)  %#ok
% hObject    handle to TransFlip (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 TransFlip
fv=handles.featureVocabulary;
%curFn = fv.wfTypes{handles.wfTypeNdx};
handles = guidata(hObject);
% curT = handles.data{handles.pfNdx}.(curFn).values.trans_types;
% if get(hObject,'Value')
% %   curT=bitor(1,curT);
%   if ~any(strcmp('flip',curT))
%    handles.data{handles.pfNdx}.(curFn).values.trans_types{end+1} = 'flip';
%   end
% else
% %   curT=bitand(14,curT);
%   allNdx = find(strcmp('flip',curT));
%   handles.data{handles.pfNdx}.(curFn).values.trans_types(allNdx) = [];
%   if isempty(handles.data{handles.pfNdx}.(curFn).values.trans_types),
% %   if handles.data{handles.pfNdx}.(curFn).values.trans_types==0,
%     warndlg('Select at least one transformation type');
%   end
% end

% update featureVocabulary
featureVocabulary=handles.featureVocabulary;  % a ref
pfName=handles.featureVocabulary.subdialectPFNames{handles.pfNdx};
wfType = fv.wfTypes{handles.wfTypeNdx};
transformation='flip';
if get(hObject,'Value')
  featureVocabulary.addWFTransformation(pfName,wfType,transformation);
else
  featureVocabulary.removeWFTransformation(pfName,wfType,transformation);
end
% Update the translation checkbox to reflect the model (the change can fail
% to happen if the user is trying to turn off the only transformation)
checked=featureVocabulary.isWFTransformation(pfName,wfType,transformation);
set(hObject,'Value',checked);

guidata(hObject,handles);
updateBasicTableAllCategoriesOfCurrentPF(handles);
updatePFTableForCurrentPF(handles);
return

% -------------------------------------------------------------------------
% --- Executes on button press in TransAbs.
function TransAbs_Callback(hObject, eventdata, handles)  %#ok
% hObject    handle to TransAbs (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 TransAbs

fv=handles.featureVocabulary;
%curFn = fv.wfTypes{handles.wfTypeNdx};
handles = guidata(hObject);
% curT = handles.data{handles.pfNdx}.(curFn).values.trans_types;
% if get(hObject,'Value')
% %   curT=bitor(1,curT);
%   if ~any(strcmp('abs',curT))
%    handles.data{handles.pfNdx}.(curFn).values.trans_types{end+1} = 'abs';
%   end
% else
% %   curT=bitand(14,curT);
%   allNdx = find(strcmp('abs',curT));
%   handles.data{handles.pfNdx}.(curFn).values.trans_types(allNdx) = [];
%   if isempty(handles.data{handles.pfNdx}.(curFn).values.trans_types),
% %   if handles.data{handles.pfNdx}.(curFn).values.trans_types==0,
%     warndlg('Select at least one transformation type');
%   end
% end

% update featureVocabulary
featureVocabulary=handles.featureVocabulary;  % a ref
pfName=handles.featureVocabulary.subdialectPFNames{handles.pfNdx};
wfType = fv.wfTypes{handles.wfTypeNdx};
transformation='abs';
if get(hObject,'Value')
  featureVocabulary.addWFTransformation(pfName,wfType,transformation);
else
  featureVocabulary.removeWFTransformation(pfName,wfType,transformation);
end
% Update the translation checkbox to reflect the model (the change can fail
% to happen if the user is trying to turn off the only transformation)
checked=featureVocabulary.isWFTransformation(pfName,wfType,transformation);
set(hObject,'Value',checked);

guidata(hObject,handles);
updateBasicTableAllCategoriesOfCurrentPF(handles);
updatePFTableForCurrentPF(handles);
return

% -------------------------------------------------------------------------
% --- Executes on button press in TransRel.
function TransRel_Callback(hObject, eventdata, handles)  %#ok
% hObject    handle to TransRel (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 TransRel

fv=handles.featureVocabulary;
%curFn = fv.wfTypes{handles.wfTypeNdx};
handles = guidata(hObject);
% curT = handles.data{handles.pfNdx}.(curFn).values.trans_types;
% if get(hObject,'Value')
% %   curT=bitor(1,curT);
%   if ~any(strcmp('relative',curT))
%    handles.data{handles.pfNdx}.(curFn).values.trans_types{end+1} = 'relative';
%   end
% else
% %   curT=bitand(14,curT);
%   allNdx = find(strcmp('relative',curT));
%   handles.data{handles.pfNdx}.(curFn).values.trans_types(allNdx) = [];
%   if isempty(handles.data{handles.pfNdx}.(curFn).values.trans_types),
% %   if handles.data{handles.pfNdx}.(curFn).values.trans_types==0,
%     warndlg('Select at least one transformation type');
%   end
% end

% update featureVocabulary
featureVocabulary=handles.featureVocabulary;  % a ref
pfName=handles.featureVocabulary.subdialectPFNames{handles.pfNdx};
wfType = fv.wfTypes{handles.wfTypeNdx};
transformation='relative';
if get(hObject,'Value')
  featureVocabulary.addWFTransformation(pfName,wfType,transformation);
else
  featureVocabulary.removeWFTransformation(pfName,wfType,transformation);
end
% Update the translation checkbox to reflect the model (the change can fail
% to happen if the user is trying to turn off the only transformation)
checked=featureVocabulary.isWFTransformation(pfName,wfType,transformation);
set(hObject,'Value',checked);

guidata(hObject,handles);
updateBasicTableAllCategoriesOfCurrentPF(handles);
updatePFTableForCurrentPF(handles);
return

% -------------------------------------------------------------------------
% --- Executes on button press in push_cancel.
function push_cancel_Callback(hObject, eventdata, handles)  %#ok
% hObject    handle to push_cancel (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
%uiresume(handles.figure_SelectFeatures);
if handles.doneWithOpeningFunction ,
  delete(handles.figure_SelectFeatures);
end
return

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

res = questdlg('All cached window data and current classifier will be deleted. Are you sure you meant to click "Done"?');

if ~strcmpi(res,'Yes'),
  return;
end

hashist = false;
for ndx = 1:numel(handles.featureVocabulary.vocabulary)
  if handles.featureVocabulary.vocabulary{ndx}.hist.enabled
    hashist = true;
  end
end

if hashist
  qstr = {'Hist computation was selected for features.'
    'Run find hist bins to find the bin edges appropriate for the current dataset? '
    '(Recommended the first time you select hist features'};
  res = questdlg(qstr,'Run find hist bins','Yes','No','Cancel','Yes');
  if strcmpi(res,'Yes')
    pushbutton_hist_Callback(hObject,eventdata,handles);
  else strcmpi(res,'Cancel');
    return;
  end
end

%basicData = get(handles.basicTable,'Data');
fv=handles.featureVocabulary;
[thereIsConsensus,maxWindowRadiusConsensus]= ...
  fv.getConsensusMaxWindowRadiusForAllWFs();
if ~thereIsConsensus ,
  maxWindowRadiusConsensus=[];
end
%featureWindowSize = str2double(get(handles.editSize,'String'));
%windowFeaturesParams = convertData(handles);
windowFeaturesParams = handles.featureVocabulary.getInJLabelDataFormat();
set(handles.figure_SelectFeatures,'Visible','off');
% handles.jld.UpdatePerframeParams(windowFeaturesParams, ...
%                                  basicData, ...
%                                  featureWindowSize);
% notify the JLabel 'object' that SelectFeatures is done
% Currently, we pass basicData and featureWindowSize back to JLabel so
% that they can be restored to their current state if user does Select
% Features... again.  This is a hack, and it would be nice to fix at some
% point.  That table and the featureWindowSize should be calculated from
% the feature vocabulary.
JLabel('selectFeaturesDone', ...
       handles.figureJLabel, ...
       windowFeaturesParams, ...
       maxWindowRadiusConsensus);
return

% -------------------------------------------------------------------------
function ExtraParams_Callback(hObject, eventdata, handles)  %#ok
% hObject    handle to ExtraParams (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 ExtraParams as text
%        str2double(get(hObject,'String')) returns contents of ExtraParams as a double

fv=handles.featureVocabulary;
if isempty(fv.wfExtraParamNames{handles.wfTypeNdx}), return; end

str = get(hObject,'String');
str = strtrim(str);
newValue = str2double(str);
%extraParam = fv.wfExtraParamNames{handles.wfTypeNdx};
wfType = fv.wfTypes{handles.wfTypeNdx};
%handles.data{handles.pfNdx}.(wfType).values.(extraParam) = newValue;

% set in featureVocabulary
pfName=fv.subdialectPFNames{handles.pfNdx};
%wfType = handles.featureVocabulary.wfTypes{handles.wfTypeNdx};
wfParamName=fv.wfExtraParamNames{handles.wfTypeNdx};
fv.setWFParam(pfName,wfType,wfParamName,newValue);

guidata(hObject,handles);
updateBasicTableAllCategoriesOfCurrentPF(handles);
updatePFTableForCurrentPF(handles);
return

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

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

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

% Use project name.
paramsdir = deployedRelative2Global('params');
[fName,pName] = uiputfile(fullfile(paramsdir,'*.xml'),'Save feature configurations to..');
if ~fName
  return;
end

params = convertData(handles);
basicData = get(handles.basicTable,'Data');
featureWindowSize = round(str2double(get(handles.editSize,'String')));
docNode = createParamsXML(params,basicData,featureWindowSize);
fName = fullfile(pName,fName);
xmlwrite(fName,docNode);
return

% -------------------------------------------------------------------------
% --- Executes on button press in Load.
function Load_Callback(hObject, eventdata, handles)  %#ok
% hObject    handle to Load (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
handles = guidata(hObject);
[fname,pname]= uigetfile('*.xml');
if ~fname; return; end;

featureparamsfilename = fullfile(pname,fname);
[params,~,basicTable,windowSize] = ...
  ReadPerFrameParams(featureparamsfilename,handles.jld.featureConfigFile);
guidata(hObject,handles);
initData(hObject,params);
set(handles.basicTable,'Data',basicTable);
set(handles.editSize,'String',num2str(windowSize));
return

% -------------------------------------------------------------------------
% --- Executes on selection change in popupmenu_copy_windowparams.
function popupmenu_copy_windowparams_Callback(hObject, eventdata, handles)  %#ok
% hObject    handle to popupmenu_copy_windowparams (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns popupmenu_copy_windowparams contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupmenu_copy_windowparams

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

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

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

if isempty(handles.pfNdx) || isempty(handles.wfTypeNdx),
  return;
end
fv=handles.featureVocabulary;
windowComp = fv.wfTypes;

% which perframe fn are we on?
pfNdx = handles.pfNdx;

% which window fn are we copying to?
winNdxTo = handles.wfTypeNdx;

% which windwo fn are we copying from?
winNdxFrom = get(handles.popupmenu_copy_windowparams,'Value');

% --- selected?
if winNdxTo > numel(windowComp),
  return;
end

%handles = CopyWindowParams(handles,pfNdx,winNdxFrom,pfNdx,winNdxTo);
handles.featureVocabulary.copyWFParams(pfNdx,winNdxFrom,pfNdx,winNdxTo);

% Update the view
updateWinParams(handles);
updateWinParamsEnablement(handles);

guidata(hObject,handles);
updateBasicTableAllCategoriesOfCurrentPF(handles);
updatePFTableForCurrentPF(handles);
return

% -------------------------------------------------------------------------
% --- Executes on selection change in popupmenu_copy_windowtypes.
function popupmenu_copy_windowtypes_Callback(hObject, eventdata, handles)  %#ok
% hObject    handle to popupmenu_copy_windowtypes (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns popupmenu_copy_windowtypes contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupmenu_copy_windowtypes

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

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

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

if isempty(handles.pfNdx),
  return;
end

fv=handles.featureVocabulary;
pfNameList = fv.subdialectPFNames;
windowComp = fv.wfTypes;

% which perframe fn are we copying to?
pfNdxTo = handles.pfNdx;
if ~fv.pfIsInVocabulary(pfNdxTo),
  return;
end

% which perframe fn are we copying from?
pfNdxFrom = get(handles.popupmenu_copy_windowtypes,'Value');

% --- selected?
if pfNdxFrom > numel(pfNameList),
  return;
end

% if ~handles.data{pfNdxFrom}.valid,
%   return;
% end

for winfnNdx = 1:numel(windowComp),
  %handles = CopyWindowParams(handles,pfNdxFrom,winfnNdx,pfNdxTo,winfnNdx);
  handles.featureVocabulary.copyWFParams(pfNdxFrom,winfnNdx,pfNdxTo,winfnNdx);
end

% update the view
updateWindowTable(handles);
updateWindowTableEnablement(handles);
%enableWindowTable(handles);
updateWinParams(handles);
updateWinParamsEnablement(handles);
% curFn = fv.wfTypes{handles.wfTypeNdx};
% if handles.data{handles.pfNdx}.(curFn).valid,
%   enableWinParams(handles);
% end

guidata(hObject,handles);
updateBasicTableAllCategoriesOfCurrentPF(handles);
updatePFTableForCurrentPF(handles);
return

% % -------------------------------------------------------------------------
% function handles = CopyWindowParams(handles,pfNdxFrom,winfnNdxFrom,pfNdxTo,winfnNdxTo)
%
% fv=handles.featureVocabulary;
% curFnFrom = fv.wfTypes{winfnNdxFrom};
% % something to copy from?
% if ~isfield(handles.data{pfNdxFrom},curFnFrom),
%   return;
% end
% curFnTo = fv.wfTypes{winfnNdxTo};
% handles.data{pfNdxTo}.(curFnTo).valid = handles.data{pfNdxFrom}.(curFnFrom).valid;
% for winParamsNdx = 1:numel(handles.winParams),
%   curType = handles.winParams{winParamsNdx};
%   handles.data{pfNdxTo}.(curFnTo).values.(curType) = ...
%     handles.data{pfNdxFrom}.(curFnFrom).values.(curType);
% end
% if ~isempty(fv.wfExtraParamNames{winfnNdxTo})
%   extraParam = fv.wfExtraParamNames{winfnNdxTo};
%   if isfield(handles.data{pfNdxFrom}.(curFnFrom).values,extraParam)
%     handles.data{pfNdxTo}.(curFnTo).values.(extraParam) = ...
%       handles.data{pfNdxFrom}.(curFnFrom).values.(extraParam);
%   else
%     handles.data{pfNdxTo}.(curFnTo).values.(extraParam) = '';
%   end
% end
% % updateWinParams(handles,winfnNdxTo);
% % if handles.data{pfNdxTo}.(curFnTo).valid,
% %   enableWinParams(handles);
% % end
% return

% % -------------------------------------------------------------------------
% function handles = CopyDefaultWindowParams(handles,wfAmount,pfNdxTo,winfnNdx)
% % For the per-frame feature with index pfNDxTo, sets the window features
% % with type given by index winfnNdx to the amount given by wfAmount (one of
% % 'normal', 'more', or 'less').
%
% fv=handles.featureVocabulary;
% curFn = fv.wfTypes{winfnNdx};
% % something to copy from?
% if ~isfield(handles.wfParamsFromAmount.(wfAmount),curFn) &&...
%     isfield(handles.data{pfNdxTo},curFn),
%     handles.data{pfNdxTo}.(curFn).valid = false;
%   return;
% end
% handles.data{pfNdxTo}.(curFn).valid = handles.wfParamsFromAmount.(wfAmount).(curFn).valid;
% for winParamsNdx = 1:numel(handles.winParams),
%   curType = handles.winParams{winParamsNdx};
%   handles.data{pfNdxTo}.(curFn).values.(curType) = ...
%     handles.wfParamsFromAmount.(wfAmount).(curFn).values.(curType);
% end
% if ~isempty(fv.wfExtraParamNames{winfnNdx})
%   extraParam = fv.wfExtraParamNames{winfnNdx};
%   handles.data{pfNdxTo}.(curFn).values.(extraParam) = ...
%     handles.wfParamsFromAmount.(wfAmount).(curFn).values.(extraParam);
% end
% return

% -------------------------------------------------------------------------
% --- Executes when selected object is changed in uipanel_tabs.
function uipanel_tabs_SelectionChangeFcn(hObject, eventdata, handles)
% hObject    handle to the selected object in uipanel_tabs
% eventdata  structure with the following fields (see UIBUTTONGROUP)
%	EventName: string 'SelectionChanged' (read only)
%	OldValue: handle of the previously selected object or empty if none was selected
%	NewValue: handle of the currently selected object
% handles    structure with handles and user data (see GUIDATA)

oldPointer=pointerToWatch(hObject);

if eventdata.NewValue == handles.togglebutton_tabdescription,
  handles.currentTab = 'description';
elseif eventdata.NewValue == handles.togglebutton_tabperframehistogram,
  handles.currentTab = 'perframehistogram';
end

handles = UpdateDescriptionPanels(handles);
guidata(hObject,handles);

restorePointer(hObject,oldPointer);

return

% -------------------------------------------------------------------------
function handles = UpdateDescriptionPanels(handles)

if isempty(handles.pfNdx),
  return;
end

fv=handles.featureVocabulary;

% update visibility
if strcmpi(handles.currentTab,'description')
  set(handles.uipanel_description,'Visible','on');
  set(handles.uipanel_histogram,'Visible','off');
else
  set(handles.uipanel_description,'Visible','off');
  set(handles.uipanel_histogram,'Visible','on');
end

% histogram if necessary
if strcmpi(handles.currentTab,'perframehistogram') && ...
   (handles.histogramData.lastPfNdx ~= handles.pfNdx || ...
    ~strcmpi(handles.histogramData.lastType,'perframe') ) && ...
   (handles.jld.nexps>0),
  i = find(handles.histogramData.perframe_idx == handles.pfNdx,1);
  if isempty(i),
    i = numel(handles.histogramData.perframe_idx)+1;
    [handles.histogramData.hhist,...
     ~,~,hleg,hxlabel,hylabel,...
     handles.histogramData.frac{i},handles.histogramData.frac_outside{i},...
     handles.histogramData.edges{i},handles.histogramData.centers_plot{i}] = ...
      HistogramPerFrameFeature(handles.jld,fv.subdialectPFNames{handles.pfNdx},...
                               'axes',handles.axes_histogram,...
                               'unknowncolor','w',...
                               'labelcolors',jet(handles.jld.nbehaviors)*.7);
    handles.histogramData.perframe_idx(i) = handles.pfNdx;
  else
    [handles.histogramData.hhist,...
     ~,~,hleg,hxlabel,hylabel,...
     handles.histogramData.frac{i},handles.histogramData.frac_outside{i},...
     handles.histogramData.edges{i},handles.histogramData.centers_plot{i}] = ...
      HistogramPerFrameFeature(handles.jld,fv.subdialectPFNames{handles.pfNdx},...
                               'axes',handles.axes_histogram,...
                               'edges',handles.histogramData.edges{i},...
                               'frac',handles.histogramData.frac{i},...
                               'frac_outside',handles.histogramData.frac_outside{i},...
                               'unknowncolor','w',...
                               'labelcolors',jet(handles.jld.nbehaviors)*.7);
  end
  handles.histogramData.lastPfNdx = handles.pfNdx;
  handles.histogramData.lastType = 'perframe';
  textcolor = get(handles.togglebutton_tabdescription,'ForegroundColor');
  set(handles.axes_histogram,'XColor',textcolor,'YColor',textcolor,'Color','k','Box','off');
  set(hxlabel,'Color',textcolor);
  set(hylabel,'Color',textcolor);
  set(hleg,'Color','k','TextColor',textcolor,'Box','off','Location','Best');
end

% -------------------------------------------------------------------------
function editSize_Callback(hObject, eventdata, handles)  %#ok
% hObject    handle to editSize (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 editSize as text
%        str2double(get(hObject,'String')) returns contents of editSize as a double

oldPointer=pointerToWatch(hObject);

curVal = str2double(get(hObject,'String'));
if isempty(curVal) || (round(curVal)-curVal)~=0 || curVal<=0 ,
  updateMaxWindowRadiusEditBox(handles);
  restorePointer(hObject,oldPointer);
  return
end

% Set the max window radius in all the window features, _and_
% in all the WF amount presets.  This will mean that any future selection
% of a preset amount with get the new value of max_window_radius.
fv=handles.featureVocabulary;
fv.setMaxWindowRadiusForAllWFs(curVal);
fv.setMaxWindowRadiusForAllWFAmounts(curVal);

% Update the view
updateMaxWindowRadiusEditBox(handles);
updateWinParams(handles);
drawnow('update');  % want to see that number change in window params pronto!
updateBasicTable(handles);
updatePFTable(handles);

restorePointer(hObject,oldPointer);

return

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

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

% -------------------------------------------------------------------------
% --- Executes on button press in togglebuttonMode.
function togglebuttonMode_Callback(hObject, eventdata, handles)  %#ok
% hObject    handle to togglebuttonMode (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
if get(hObject,'Value')
  handles=setViewMode(handles,'advanced');
else
  handles=setViewMode(handles,'basic');
end
guidata(handles.figure_SelectFeatures,handles);
return

% -------------------------------------------------------------------------
function handles=setViewMode(handles,newMode)
% Set the mode of the view (to 'basic' or 'advanced')

curLoc = get(handles.figure_SelectFeatures,'Position');
if isequal(newMode,'advanced')
  handles.mode = 'advanced';
  set(handles.figure_SelectFeatures,'Position',[curLoc(1:2) handles.advancedSize]);
  set(handles.togglebuttonMode,'String','Basic <');
else
  handles.mode = 'basic';
  set(handles.figure_SelectFeatures,'Position',[curLoc(1:2) handles.basicSize]);
  set(handles.togglebuttonMode,'String','Advanced >');
end
return

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

prcEdges = [5 15 30 50 70 85 95];

fv=handles.featureVocabulary;
histWFTypeNdx = find(strcmp('hist',fv.wfTypes));
histExtraParamName = fv.wfExtraParamNames{histWFTypeNdx};  %#ok

h = waitbar(0,'Computing hist bins');
for pfIndex = 1:numel(fv.subdialectPFNames)
  pfName = fv.subdialectPFNames{pfIndex};
  waitbar(pfIndex/numel(fv.subdialectPFNames),h);

  if ~fv.pfIsInVocabulary(pfIndex) || ~fv.wfTypeIsInVocabulary(pfIndex,'hist')
    continue;
  end

  allData = [];
  for expi = 1:handles.jld.nexps,

    % load per-frame data for this experiment
    perframeDirName = handles.jld.GetFile('perframedir',expi);
    file = fullfile(perframeDirName,[pfName,'.mat']);
    if ~exist(file,'file'),
      warning('Per-frame data file %s does not exist',file);
      continue;
    end

    perframedata = load(file);

    for fly = 1:handles.jld.nflies_per_exp(expi),

      x = perframedata.data{fly};
      allData = [allData ; x(:)];  %#ok
    end
  end
  bins = prctile(allData,prcEdges);
  minD = min(allData);
  maxD = max(allData);
  binMin = minD - (maxD-minD);
  binMax = maxD + (maxD-minD);
  bins = [binMin bins binMax];  %#ok
  %handles.data{ndx}.hist.values.(histExtraName) = bins;
  fv.setWFParam(pfName,'hist',histExtraParamName,bins)
end
delete(h);
guidata(hObject,handles);
updateWindowTableAndEnablement(handles);
updateWinParamsAndEnablement(handles);
% if ~isempty(handles.pfNdx)
%   updateWindowTable(handles);
%   enableWindowTable(handles);
% end
return

% -------------------------------------------------------------------------
function figure_SelectFeatures_CloseRequestFcn(hObject,eventdata,handles)  %#ok
%fprintf('In CloseRequestFcn()\n');
push_cancel_Callback(hObject,eventdata,handles);
return

% % -------------------------------------------------------------------------
% % --- Executes on button press in pushbutton_done.
% function pushbutton_ok_Callback(hObject, eventdata, handles)
% % hObject    handle to pushbutton_done (see GCBO)
% % eventdata  reserved - to be defined in a future version of MATLAB
% % handles    structure with handles and user data (see GUIDATA)
%
% % configfile = handles.jld.configfilename;
% % [~,~,ext ] = fileparts(configfile);
% % if strcmpi(ext,'.xml'),
% %   configparams = ReadXMLParams(configfile);
% % elseif strcmpi(ext,'.mat'),
% %   configparams = load(configfile);
% % else
% %   errordlg('Project file %s is invalid. Cannot save the window features',configfile);
% % end
% % if ~isfield(configparams.file,'featureparamfilename') || isempty(configparams.file.featureparamfilename)
% %   behaviorname = configparams.behaviors.names;
% %   if iscell(behaviorname),
% %     defaultname = sprintf('WindowFeatures_%s.xml',behaviorname{1});
% %   else
% %     defaultname = sprintf('WindowFeatures_%s.xml',behaviorname);
% %   end
% %   [fname,fpath]= uiputfile(fullfile('params','*.xml'),'Enter a name for feature config file',defaultname);
% %   if isempty(fname),return, end
% %   featureconfigfile = fullfile(fpath,fname);
% %   configparams.file.featureparamfilename = featureconfigfile;
% %   docNode = com.mathworks.xml.XMLUtils.createDocument('params');
% %   toc = docNode.getDocumentElement;
% %   fnames = fieldnames(configparams);
% %   for ndx = 1:numel(fnames)
% %     toc.appendChild(createXMLNode(docNode,fnames{ndx},configparams.(fnames{ndx})));
% %   end
% %   xmlwrite(configfile,docNode);
% % end
% %
% % featureconfigfile = configparams.file.featureparamfilename;
% % params = convertData(handles);
% % basicData = get(handles.basicTable,'Data');
% % featureWindowSize = round(str2double(get(handles.editSize,'String')));
% % docNode = createParamsXML(params,basicData,featureWindowSize);
% % xmlwrite(featureconfigfile,docNode);
%
% pushbutton_done_Callback(hObject,eventdata,handles);
% push_cancel_Callback(hObject,eventdata,handles);
% return

author: kristinbranson

repo: JAABA


text:
function obj = fromSimpleNN(net, varargin)
% FROMSIMPLENN  Initialize a DagNN object from a SimpleNN network
%   FROMSIMPLENN(NET) initializes the DagNN object from the
%   specified CNN using the SimpleNN format.
%
%   SimpleNN objects are linear chains of computational layers. These
%   layers exchange information through variables and parameters that
%   are not explicitly named. Hence, FROMSIMPLENN() uses a number of
%   rules to assign such names automatically:
%
%   * From the input to the output of the CNN, variables are called
%     `x0` (input of the first layer), `x1`, `x2`, .... In this
%     manner `xi` is the output of the i-th layer.
%
%   * Any loss layer requires two inputs, the second being a label.
%     These are called `label` (for the first such layers), and then
%     `label2`, `label3`,... for any other similar layer.
%
%   Additionally, given the option `CanonicalNames` the function can
%   change the names of some variables to make them more convenient to
%   use. With this option turned on:
%
%   * The network input is called `input` instead of `x0`.
%
%   * The output of each SoftMax layer is called `prob` (or `prob2`,
%     ...).
%
%   * The output of each Loss layer is called `objective` (or `
%     objective2`, ...).
%
%   * The input of each SoftMax or Loss layer of type *softmax log
%     loss* is called `prediction` (or `prediction2`, ...). If a Loss
%     layer immediately follows a SoftMax layer, then the rule above
%     takes precendence and the input name is not changed.
%
%   FROMSIMPLENN(___, 'OPT', VAL, ...) accepts the following options:
%
%   `CanonicalNames`:: false
%      If `true` use the rules above to assign more meaningful
%      names to some of the variables.

% Copyright (C) 2015 Karel Lenc and Andrea Vedaldi.
% All rights reserved.
%
% This file is part of the VLFeat library and is made available under
% the terms of the BSD license (see the COPYING file).

opts.canonicalNames = false ;
opts = vl_argparse(opts, varargin) ;

import dagnn.*

obj = DagNN() ;
net = vl_simplenn_move(net, 'cpu') ;
net = vl_simplenn_tidy(net) ;

% copy meta-information as is
obj.meta = net.meta ;

for l = 1:numel(net.layers)
  inputs = {sprintf('x%d',l-1)} ;
  outputs = {sprintf('x%d',l)} ;

  params = struct(...
        'name', {}, ...
        'value', {}, ...
        'learningRate', [], ...
        'weightDecay', []) ;
  if isfield(net.layers{l}, 'name')
    name = net.layers{l}.name ;
  else
    name = sprintf('layer%d',l) ;
  end

  switch net.layers{l}.type
    case {'conv', 'convt'}
      sz = size(net.layers{l}.weights{1}) ;
      hasBias = ~isempty(net.layers{l}.weights{2}) ;
      params(1).name = sprintf('%sf',name) ;
      params(1).value = net.layers{l}.weights{1} ;
      if hasBias
        params(2).name = sprintf('%sb',name) ;
        params(2).value = net.layers{l}.weights{2} ;
      end
      if isfield(net.layers{l},'learningRate')
        params(1).learningRate = net.layers{l}.learningRate(1) ;
        if hasBias
          params(2).learningRate = net.layers{l}.learningRate(2) ;
        end
      end
      if isfield(net.layers{l},'weightDecay')
        params(1).weightDecay = net.layers{l}.weightDecay(1) ;
        if hasBias
          params(2).weightDecay = net.layers{l}.weightDecay(2) ;
        end
      end
      switch net.layers{l}.type
        case 'conv'
          block = Conv() ;
          block.size = sz ;
          block.pad = net.layers{l}.pad ;
          block.stride = net.layers{l}.stride ;
          block.dilate = net.layers{l}.dilate ;
        case 'convt'
          block = ConvTranspose() ;
          block.size = sz ;
          block.upsample = net.layers{l}.upsample ;
          block.crop = net.layers{l}.crop ;
          block.numGroups = net.layers{l}.numGroups ;
      end
      block.hasBias = hasBias ;
      block.opts = net.layers{l}.opts ;

    case 'pool'
      block = Pooling() ;
      block.method = net.layers{l}.method ;
      block.poolSize = net.layers{l}.pool ;
      block.pad = net.layers{l}.pad ;
      block.stride = net.layers{l}.stride ;
      block.opts = net.layers{l}.opts ;

    case {'normalize', 'lrn'}
      block = LRN() ;
      block.param = net.layers{l}.param ;

    case {'dropout'}
      block = DropOut() ;
      block.rate = net.layers{l}.rate ;

    case {'relu'}
      block = ReLU() ;
      block.leak = net.layers{l}.leak ;

    case {'sigmoid'}
      block = Sigmoid() ;

    case {'softmax'}
      block = SoftMax() ;

    case {'softmaxloss'}
      block = Loss('loss', 'softmaxlog') ;
      % The loss has two inputs
      inputs{2} = getNewVarName(obj, 'label') ;

    case {'bnorm'}
      block = BatchNorm() ;
      params(1).name = sprintf('%sm',name) ;
      params(1).value = net.layers{l}.weights{1} ;
      params(2).name = sprintf('%sb',name) ;
      params(2).value = net.layers{l}.weights{2} ;
      params(3).name = sprintf('%sx',name) ;
      params(3).value = net.layers{l}.weights{3} ;
      if isfield(net.layers{l},'learningRate')
        params(1).learningRate = net.layers{l}.learningRate(1) ;
        params(2).learningRate = net.layers{l}.learningRate(2) ;
        params(3).learningRate = net.layers{l}.learningRate(3) ;
      end
      if isfield(net.layers{l},'weightDecay')
        params(1).weightDecay = net.layers{l}.weightDecay(1) ;
        params(2).weightDecay = net.layers{l}.weightDecay(2) ;
        params(3).weightDecay = 0 ;
      end

    otherwise
      error([net.layers{l}.type ' is unsupported']) ;
  end

  obj.addLayer(...
    name, ...
    block, ...
    inputs, ...
    outputs, ...
    {params.name}) ;

  for p = 1:numel(params)
    pindex = obj.getParamIndex(params(p).name) ;
    if ~isempty(params(p).value)
      obj.params(pindex).value = params(p).value ;
    end
    if ~isempty(params(p).learningRate)
      obj.params(pindex).learningRate = params(p).learningRate ;
    end
    if ~isempty(params(p).weightDecay)
      obj.params(pindex).weightDecay = params(p).weightDecay ;
    end
  end
end

% --------------------------------------------------------------------
% Rename variables to canonical names
% --------------------------------------------------------------------

if opts.canonicalNames
  for l = 1:numel(obj.layers)
    if l == 1
      obj.renameVar(obj.layers(l).inputs{1}, 'input') ;
    end
    if isa(obj.layers(l).block, 'dagnn.SoftMax')
      obj.renameVar(obj.layers(l).outputs{1}, getNewVarName(obj, 'prob')) ;
      obj.renameVar(obj.layers(l).inputs{1}, getNewVarName(obj, 'prediction')) ;
    end
    if isa(obj.layers(l).block, 'dagnn.Loss')
      obj.renameVar(obj.layers(l).outputs{1}, 'objective') ;
      if isempty(regexp(obj.layers(l).inputs{1}, '^prob.*'))
        obj.renameVar(obj.layers(l).inputs{1}, ...
                      getNewVarName(obj, 'prediction')) ;
      end
    end
  end
end

if isfield(obj.meta, 'inputs')
  obj.meta.inputs(1).name = obj.layers(1).inputs{1} ;
end

% --------------------------------------------------------------------
function name = getNewVarName(obj, prefix)
% --------------------------------------------------------------------
t = 0 ;
name = prefix ;
while any(strcmp(name, {obj.vars.name}))
  t = t + 1 ;
  name = sprintf('%s%d', prefix, t) ;
end

author: guosheng

repo: refinenet

save_path: github-repos/MATLAB/guosheng-refinenet


text:
function [x, fx, exitFlag] = bisection(f,lb,ub,target,options)%#codegen
    % BISECTION Fast and robust root-finding method that handles n-dim arrays.
    %
    %   [x,fVal,ExitFlag] = BISECTION(f,LB,UB,target,options) finds x +/- TolX
    %   (LB < x < UB) such that f(x) = target +/- TolFun.
    %
    %   x = BISECTION(f,LB,UB) finds the root(s) of function f on the interval
    %   [LB, UB], i.e. finds x such that f(x) = 0 where LB <= x <= UB. f will
    %   never be evaluated outside of the interval specified by LB and UB. f
    %   should have only one root and f(UB) and f(LB) must bound it. Elements
    %   of x are NaN for instances where a solution could not be found.
    %
    %   x = BISECTION(f,LB,UB,target) finds x such that f(x) = target.
    %
    %   x = BISECTION(f,LB,UB,target,TolX) will terminate the search when the
    %   search interval is smaller than TolX (TolX must be positive).
    %
    %   x = BISECTION(f,LB,UB,target,options) solves with the default
    %   parameters replaced by values in the structure OPTIONS, an argument
    %   created with the OPTIMSET function. Used options are TolX and TolFun.
    %   Note that OPTIMSET will not allow arrays for tolerances, so set the
    %   fields of the options structure manually for non-scalar TolX or TolFun.
    %
    %   [x,fVal] = BISECTION(f,...) returns the value of f evaluated at x.
    %
    %   [x,fVal,ExitFlag] = BISECTION(...) returns an ExitFlag that describes
    %   the exit condition of BISECTION. Possible values of elements of
    %   ExitFlag and the corresponding exit conditions are
    %
    %       1   Search interval smaller than TolX.
    %       2   Function value within TolFun of target.
    %       3   Search interval smaller than TolX AND function value within
    %           TolFun of target.
    %      -1   No solution found.
    %
    %   Any or all of f(scalar), f(array), LB, UB, target, TolX, or TolFun may
    %   be scalar or n-dim arrays. All non-scalar arrays must be the same size.
    %   All outputs will be this size.
    %
    %   Default values are target = 0, TolX = 1e-6, and TolFun = 0.
    %
    %   There is no iteration limit. This is because BISECTION (with a TolX
    %   that won't introduce numerical issues) is guaranteed to converge if f
    %   is a continuous function on the interval [UB, LB] and f(x)-target
    %   changes sign on the interval.
    %
    %   The bisection method is very robust root-finding method. The absolute
    %   error is halved at each step so the method converges linearly. However,
    %   Brent's method (such as implemented in FZERO) can converge
    %   superlinearly and is as robust. FZERO also has more features and input
    %   checking, so use BISECTION in cases where either the optimization
    %   toolbox is unavailable or if FZERO would have to be implemented in a
    %   loop to solve multiple cases, in which case BISECTION will be much
    %   faster because of vectorization.
    %
    %   Define LB, UB, target, TolX, and TolFun for each specific application
    %   using great care for the following reasons:
    %     - There is no iteration limit, so given an unsolvable task, such as
    %       TolX = TolFun = 0, BISECTION remains in an unending loop.
    %     - Spacing between very large floating point numbers is likely to be
    %       greater than TolX.
    %     - There is no initial check to make sure that f(x) - target changes
    %       sign between LB and UB.
    %     - Very large or very small numbers can introduce numerical issues.
    %
    %   Example 1: Find cube root of array 'target' without using NTHROOT and
    %   compare speed to using FZERO.
    %       options = optimset('TolX', 1e-9);
    %       target = [(-100:.1:100)' (-1000:1:1000)'];
    %
    %       tic;
    %       xfz = zeros(size(target));
    %       for ii = 1:numel(target)
    %           xfz(ii) = fzero(@(x) x.^3-target(ii), [-20 20], options);
    %       end
    %       fzero_time = toc
    %
    %       tic;
    %       xbis = bisection(@(x) x.^3, -20, 20, target, options);
    %       bisection_time = toc
    %
    %       fprintf('FZERO took %0.0f times longer than BISECTION.\n',...
    %                   fzero_time/bisection_time)
    %
    %   Example 2: Find roots by varying the function coefficients.
    %       [A, B] = meshgrid(linspace(1,2,6), linspace(4,12,10));
    %       f = @(x) A.*x.^0.2 + B.*x.^0.87 - 15;
    %       xstar = bisection(f,0,5);
    %
    %   See also FZERO, FMINBND, OPTIMSET, FUNCTION_HANDLE.
    %
    %   [x,fVal,ExitFlag] = BISECTION(f,LB,UB,target,options)

    %   Copyright 2010-2013 Sky Sartorius
    %   Author  - Sky Sartorius
    %   Contact - www.mathworks.com/matlabcentral/fileexchange/authors/101715

    % --- Process inputs. ---
    % Set default values
    tolX    = 1e-6;
    tolFun  = 0;
    if nargin == 5
        if isstruct(options)
            if isfield(options,'TolX') && ~isempty(options.TolX)
                tolX = options.TolX;
            end
            if isfield(options,'TolFun') && ~isempty(options.TolFun)
                tolFun = options.TolFun;
            end
        else
            tolX = options;
        end
    end
    if nargin<4 || isempty(target); target=0; end

    ub_in = ub; lb_in = lb;
    f = @(x) f(x) - target;

    % --- Flip UB and LB if necessary. ---
    isFlipped = lb>ub;
    if any(isFlipped(:))
        ub(isFlipped) = lb_in(isFlipped);
        lb(isFlipped) = ub_in(isFlipped);
        ub_in = ub; lb_in = lb;
    end

    % --- Make sure everything is the same size for a non-scalar problem. ---
    if isscalar(lb) && isscalar(ub)
        % Test if f returns multiple outputs for scalar input.
        if ~isscalar(target)
            ub = ub + zeros(size(target));
        else
            jnk = f(ub);
            if ~isscalar(jnk)
                ub = ub + zeros(size(jnk));
            end
        end
    end

    % Check if lb and/or ub need to be made into arrays.
    if isscalar(lb) && ~isscalar(ub)
        lb = lb + zeros(size(ub));
    elseif ~isscalar(lb) && isscalar(ub)
        ub = ub + zeros(size(lb));
    end

    x = zeros(size(lb));
    [x, fx, outsideTolFun, outsideTolX, stillNotDone] = testconvergence(f, ub, lb, tolFun, tolX);
    % --- Iterate ---
    iterations = 0;
    while any(stillNotDone(:))
        bigger  = fx.*f(ub) > 0;
        ub(bigger)= x(bigger);
        lb(~bigger)= x(~bigger);

        [x, fx, outsideTolFun, outsideTolX, stillNotDone] = testconvergence(f, ub, lb, tolFun, tolX);
        iterations = iterations + 1;

        if(iterations > 10000)
            %         error('Too many iterations in bisection!');
            break;
        end
    end

    % --- Check that f(x+tolX) and f(x-tolX) have opposite sign. ---
    fu = f(min(x+tolX,ub_in));
    fl = f(max(x-tolX,lb_in));
    unboundedRoot = (fu.*fl) > 0;

    % Throw out unbounded results if not meeting TolFun convergence criteria.

    x(unboundedRoot & outsideTolFun) = NaN;

    % --- Catch NaN elements of UB, LB, target, or other funky stuff. ---
    x(isnan(fx)) = NaN;

    % --- Characterize results. ---
    fx = fx + target;
    if nargout > 2
        exitFlag                                    = +~outsideTolX;
        exitFlag(~outsideTolFun)                    =  2;
        exitFlag(~outsideTolFun & ~outsideTolX)     =  3;
        exitFlag(isnan(x))                          = -1;
    end
end

function [x, fx, outsideTolFun, outsideTolX, stillNotDone] = testconvergence(f, ub, lb, tolFun, tolX)
    x=(ub+lb)/2;
    fx=f(x);
    outsideTolFun =  abs(fx)  > tolFun;
    outsideTolX =   (ub - lb) > tolX;
    stillNotDone = outsideTolX & outsideTolFun;
end

% V2: July     2010
% V3: December 2012
% don't remember when
%   typo line 39; added fn handle to see also; made array in example 2
%   smaller; changed wording in example 1
% 2013-08-23
%  -changed scalar*ones(...) calls to scalar+zeros(...) calls based on
%   http://undocumentedmatlab.com/blog/allocation-performance-take-2/
%  -rearranged help block and formatted a tiny bit

author: Arrowstar

repo: ksptot

save_path: github-repos/MATLAB/Arrowstar-ksptot


text:
function B=shiftmat(A,n,dim,pad)
%SHIFTMAT  Shift matrix along specified dimension.
%   SHIFTMAT(X), returns X.
%   SHIFTMAT(X,N), moves elements in matrix X with N steps. The trailing
%      elements becomes zeros. Shifting will be done row-wise.
%      Positive N will mean that elements are moved towards higher
%      row indicies. First row will be filled with zeros,
%      aso. Negative N will make the elements move upwards towards
%      lower row indicies. Last row will be filled with zeros,
%      aso. If N is zero or empty, no shifting will occur
%      and X will be returned.
%   SHIFTMAT(X,N,DIM), shifts matrix elements along dimension DIM.
%      If DIM is a singleton dimension, X will be returned.
%      Likewise if DIM < 1 or DIM > ndims(X), nothing will happen.
%      N must be scalar valued.
%   SHIFTMAT(X,N,DIM,PAD), uses PAD to pad the trailing elements with
%      another value rather than zeros.
%      PAD must be scalar valued.
%
%   Examples:
%      X=rand(3,3,3)          %X is 3x3x3.
%      shiftmat(X,1)          %shifts one step down.
%      shiftmat(X,-2)         %shifts two steps up.
%      shiftmat(X,1,2)        %shifts ones step right.
%      shiftmat(X,1,3)        %shifts one step "down" along 3:rd dimension.
%      shiftmat(X,-2,2,NaN)   %shifts two steps left with trailing NaNs.
%
%   See also DELMAT, INSMAT, ROTMAT, REPMAT, RESHAPE, FLIPDIM.

% Copyright (c) 2003-10-28, B. Rasmus Anthin.
% Revision 2003-10-29.
% GPL license, freeware.

error(nargchk(1,4,nargin))
if nargin<2, n=0;end                    %do nothing
if isempty(n), n=0;end
if prod(size(n))~=1, error('N must be a scalar.'),end
n=round(n);
if nargin<3, dim=1;end                  %rotate row vectors
if dim<1, dim=ndims(A)+1;end            %if less than one, do nothing
if nargin<4, pad=0;end                  %trailing elements are zeros as default
if prod(size(pad))~=1, error('PAD must be a scalar.'),end
dims=[dim:max(ndims(A),dim) 1:dim-1];
if dims(1)<=ndims(A) & n
   A=permute(A,dims);                             %move dimension to front
   sizA=size(A);                                  %get dimension sizes
   A=reshape(A,[sizA(1) prod(sizA(2:end))]);      %reshape to a 2-D matrix
   idx=1:sizA(1);                                 %the row indices
   if n<0
      idx=idx(1-n:end);                           %remove low valued indices
      B=A(idx,:);                                 %truncate matrix
      B=[B;pad*ones(min(-n,sizA(1)),prod(sizA(2:end)))];    %pad with zeros (or PAD)
   elseif n>0
      idx=idx(1:end-n);                           %remove high valued indices
      B=A(idx,:);                                 %truncate matrix
      B=[pad*ones(min(n,sizA(1)),prod(sizA(2:end)));B];     %pad with zeros (or PAD)
   end
   B=reshape(B,[size(B,1) sizA(2:end)]);          %back to previous shape minus removed vectors
   B=ipermute(B,dims);                            %replace dimensions to initial location
else
   B=A;
end

author: Sable

repo: mcbench-benchmarks


text:
function [c, xc] = covW(obj, x, w)
sw = sum(w);
mx = (w' * x) ./ sw;

xc = x-mx;

N = size(x, 1);
% Direct method uses way too much memory
tmp = sqrt(w) .* xc;
c = (tmp' * tmp) ./ ((N-1) * sw / N);
end

author: Bobholamovic

repo: ChangeDetectionToolbox