Home > chronux_1_15 > spikesort > ssg > ssg_featureselect.m

ssg_featureselect

PURPOSE ^

SSG_FEATURESELECT M-file for ssg_featureselect.fig

SYNOPSIS ^

function varargout = ssg_featureselect(varargin)

DESCRIPTION ^

 SSG_FEATURESELECT M-file for ssg_featureselect.fig
      SSG_FEATURESELECT(axes_handle) creates a new SSG_FEATURESELECT.  Not
      a user GUI; intended for internal use by SS GUI applications.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function varargout = ssg_featureselect(varargin)
0002 % SSG_FEATURESELECT M-file for ssg_featureselect.fig
0003 %      SSG_FEATURESELECT(axes_handle) creates a new SSG_FEATURESELECT.  Not
0004 %      a user GUI; intended for internal use by SS GUI applications.
0005 
0006 %   Last Modified By: sbm on Tue Jul 19 21:32:10 2005
0007 
0008 % Last Modified by GUIDE v2.5 19-Aug-2004 16:32:46
0009 
0010 % Begin initialization code - DO NOT EDIT
0011 gui_Singleton = 0;
0012 gui_State = struct('gui_Name',       mfilename, ...
0013                    'gui_Singleton',  gui_Singleton, ...
0014                    'gui_OpeningFcn', @ssg_featureselect_OpeningFcn, ...
0015                    'gui_OutputFcn',  @ssg_featureselect_OutputFcn, ...
0016                    'gui_LayoutFcn',  [] , ...
0017                    'gui_Callback',   []);
0018 if nargin & isstr(varargin{1})
0019     gui_State.gui_Callback = str2func(varargin{1});
0020 end
0021 
0022 if nargout
0023     [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
0024 else
0025     gui_mainfcn(gui_State, varargin{:});
0026 end
0027 % End initialization code - DO NOT EDIT
0028 
0029 
0030 % --- Executes just before ssg_featureselect is made visible.
0031 function ssg_featureselect_OpeningFcn(hObject, eventdata, handles, varargin)
0032 handles.output = hObject;
0033 
0034 
0035 % Argument error checking
0036 if (length(varargin) < 2)
0037     error('SSG:invalid_init_arg', 'Incorrect initalization syntax.');
0038 end
0039 handles.axes_handle = varargin{1};
0040 handles.switchaxis = varargin{2};
0041 
0042 if (~ishandle(handles.axes_handle) || ~strcmp(get(handles.axes_handle, 'Type'), 'axes') || ...
0043     isempty(guidata(handles.axes_handle)))
0044     error('SSG:invalid_init_arg', 'First initialization argument must be an axis handle created by an SSG function.');
0045 end
0046 if (~ischar(handles.switchaxis) || ~any(strcmpi({'x', 'y', 'z'}, handles.switchaxis)))
0047     error('SSG:invalid_init_arg', 'Second initialization argument must be one of ''x'', ''y'', or ''z''.');
0048 end
0049 ssg = guidata(handles.axes_handle);
0050 
0051 choices = get(handles.popup_datatype, 'String');
0052 value = find(strcmpi(choices, ssg.([handles.switchaxis 'choice'])));
0053 if (isempty(value))
0054     error('SSG:invalid_default_choice', ['Invalid entry in initial ' handles.switchaxis 'choice.']);
0055 end
0056 
0057 % Fill in controls to reflect exisiting data choice.
0058 set(handles.popup_datatype, 'Value', value);
0059 set(handles.edit_param1, 'String', ssg.([handles.switchaxis 'param1']));
0060 handles.oldparam = ssg.([handles.switchaxis 'param1']);
0061 handles.maxparam = size(ssg.ss_object.waveforms, 2);
0062 set(handles.figure_ssg_featureselect, 'Name', [upper(handles.switchaxis) '-Axis Selection']);
0063 
0064 % Move this window to the current location of the corresponding label for convenience.
0065 set(handles.figure_ssg_featureselect, 'Units', 'Pixel');
0066 newpos = labelposition_screen_coords(handles);
0067 currpos = get(handles.figure_ssg_featureselect, 'Position');
0068 set(handles.figure_ssg_featureselect, 'Position', [(newpos-currpos(3:4)*0.75) currpos(3:4)]);
0069 set(handles.figure_ssg_featureselect, 'Color', get(handles.axes_handle, [handles.switchaxis 'Color']));
0070 
0071 % Update guidata structures
0072 ssg.([handles.switchaxis 'control']) = handles.figure_ssg_featureselect;
0073 guidata(handles.axes_handle, ssg);
0074 guidata(hObject, handles);
0075 
0076 
0077 % Outputs from this function are returned to the command line.
0078 function varargout = ssg_featureselect_OutputFcn(hObject, eventdata, handles)
0079 varargout{1} = handles.output;
0080 
0081 
0082 %%%%%%%%%%%%%%%%%%%%%%%  GUI INITIALIZATION %%%%%%%%%%%%%%%%%%%%%%%%%%
0083 % Executes during object creation, after setting all properties.
0084 %  Most of this is just for visual consistency.
0085 
0086 function edit_param1_CreateFcn(hObject, eventdata, handles)
0087 if ispc,  set(hObject,'BackgroundColor','white');
0088 else,     set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
0089 end
0090 
0091 function popup_datatype_CreateFcn(hObject, eventdata, handles)
0092 if ispc,  set(hObject,'BackgroundColor','white');
0093 else,     set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
0094 end
0095 
0096 function slider_aspect_CreateFcn(hObject, eventdata, handles)
0097 set(hObject,'BackgroundColor', [.9 .9 .9]);
0098 
0099 
0100 %%%%%%%%%%%%%%%%%%%%%%%%%%%% CALLBACKS  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0101 
0102 function popup_datatype_Callback(hObject, eventdata, handles)
0103 % Make GUI state consistent before calling for data update.
0104 choices = get(hObject, 'String');
0105 choice = choices{get(hObject, 'Value')};
0106 paramhandles = [handles.edit_param1, handles.button_next, handles.button_last];
0107 switch (choice),
0108     case {'Signal', 'PC'}
0109         set(paramhandles, 'Enable', 'on');
0110     case {'Event Time', 'Height', 'Width', 'ISI Preceding', 'Total Energy', 'Cluster #'}
0111         set(paramhandles, 'Enable', 'off');
0112 end
0113 alter_data(handles);
0114 
0115 
0116 function edit_param1_Callback(hObject, eventdata, handles)
0117 % Bounds checking on the parameter edit box.
0118 param1 = str2double(get(handles.edit_param1, 'String'));
0119 if (isnan(param1) || (param1 ~= round(param1)))
0120     set(handles.edit_param1, 'String', handles.oldparam);
0121     beep;
0122 else
0123     handles = param1_bounds_check(handles, param1);
0124     alter_data(handles);
0125 end
0126 
0127 
0128 % These next two functions just advance or review the param1 value
0129 % in integer steps; just finger-candy to make it easier to step
0130 % through a range of values.
0131 function button_next_Callback(hObject, eventdata, handles)
0132 param1 = str2double(get(handles.edit_param1, 'String'));
0133 handles = param1_bounds_check(handles, param1 + 1);
0134 alter_data(handles);
0135 
0136 function button_last_Callback(hObject, eventdata, handles)
0137 param1 = str2double(get(handles.edit_param1, 'String'));
0138 handles = param1_bounds_check(handles, param1 - 1);
0139 alter_data(handles);
0140 
0141 
0142 function figure_delete_Callback(hObject, eventdata, handles)
0143 % We need to let the parent axis know when this GUI is deleted.
0144 ssg = guidata(handles.axes_handle);
0145 ssg.([handles.switchaxis 'control']) = [];
0146 guidata(handles.axes_handle, ssg);
0147 
0148 %%%%%%%%%%%%%%%%%%%%%%%%% HELPER FUNCTIONS  %%%%%%%%%%%%%%%%%%%%%%%%%%%%
0149 
0150 function pos = labelposition_screen_coords(handles)
0151 % Returns [left, lower] pixel coordinates where the GUI can be placed
0152 % (in screen coordinates) so that it appears somewhere in the vicinity
0153 % of the axes (i tried to have them pop up on top of the axis labels, but
0154 % there's something wrong with the units of the label's 'Extent' property
0155 % in MatlabR13).
0156 axeshndl = handles.axes_handle;
0157 figurehndl = get(axeshndl, 'Parent');
0158 
0159 oldunits = get([figurehndl, axeshndl], 'Units');
0160 set([figurehndl, axeshndl], 'Units', 'Pixel');
0161 
0162 axes_relative = get(axeshndl, 'Position');
0163 figure_pos = get(figurehndl, 'Position');
0164 
0165 set(figurehndl, 'Units', oldunits{1});
0166 set(axeshndl, 'Units', oldunits{2});
0167 
0168 % Offsets to get near default axis orientation.  Won't do the right thing if the
0169 % axes have been rotated . . . its an imperfect world.
0170 offset = axes_relative(3:4);
0171 switch(handles.switchaxis),  
0172     case 'x',
0173         offset = offset .* [0.75 0];
0174     case 'y',
0175         offset = offset .* [-0.10 0.10];
0176     case 'z',
0177         offset = offset .* [0 0.75];
0178 end
0179 pos = figure_pos + axes_relative;
0180 pos = pos(1:2) + offset;
0181 
0182 
0183 function handles = param1_bounds_check(handles, param1)
0184 % Checks bounds on 'param1', clipping to [1,maxparam] if necessary, then
0185 % sets the param1 edit box to reflect the clipped value.
0186 % Note that this function also sets the 'handles.oldparam' to the newly
0187 % validated string but does NOT save the modified 'handles'.  Make sure to
0188 % accept 'handles' as an output and to save if you want to remember the
0189 % old value (useful for recovering from user typos).
0190 if (param1 < 1)
0191     param1 = '1';
0192 elseif (param1 > handles.maxparam)
0193     param1 = num2str(handles.maxparam);
0194 else
0195     param1 = num2str(param1);
0196 end
0197 set(handles.edit_param1, 'String', param1);
0198 handles.oldparam = param1;
0199 
0200     
0201 function alter_data(handles)
0202 %%% NEEDS COMMENTS!
0203 choices = get(handles.popup_datatype, 'String');
0204 choice = choices{get(handles.popup_datatype, 'Value')};
0205 param1 = str2double(get(handles.edit_param1, 'String'));
0206 ssg = guidata(handles.axes_handle);
0207 axname = handles.switchaxis;  % shorthand
0208 
0209 % First get the relevant data values ...
0210 switch (choice), 
0211     case 'Signal', 
0212         vector = ssg.ss_object.waveforms(:,param1);
0213       
0214     case 'PC', % (for principal components, we might need to compute the first time)
0215         if (~isfield(ssg.ss_object, 'pca'))
0216             parentfig = get(handles.axes_handle, 'Parent');  oldptr = get(parentfig, 'Pointer');
0217             set([handles.figure_ssg_featureselect, parentfig], 'Pointer', 'watch');
0218 
0219             [pca.scores,pca.u,pca.s,pca.v] = pcasvd(ssg.ss_object.waveforms);
0220             ssg.ss_object.pca = pca;
0221             
0222             set(handles.figure_ssg_featureselect, 'Pointer', 'arrow');
0223             set(parentfig, 'Pointer', oldptr);
0224         end
0225         vector = ssg.ss_object.pca.scores(:,param1);
0226         
0227     case 'Cluster #',
0228         vector = ssg.ss_assigns;
0229         
0230     case 'Event Time',
0231         vector = ssg.ss_object.spiketimes;
0232         
0233     case 'ISI Preceding',
0234         vector = [NaN; diff(ssg.ss_object.spiketimes)];
0235         
0236     case 'Total Energy',
0237         vector = sum(ssg.ss_object.waveforms.^2, 2);
0238         
0239     case {'Height', 'Width'},  % again, we might need to compute these the first time they're used
0240         if (~isfield(ssg.ss_object, 'heightwidth'))
0241             [hw.height, hw.width] = thresholded_peaks(ssg.ss_object);
0242             ssg.ss_object.heightwidth = hw;
0243         end
0244         vector = ssg.ss_object.heightwidth.(lower(choice));
0245         
0246 end 
0247 ssg.([axname 'choice']) = choice;
0248 ssg.([axname 'param1']) = num2str(param1);
0249 
0250 % ... then feed them to the appropriate group of data.
0251 for gp = 1:length(ssg.group_handles)
0252     set(ssg.group_handles(gp), [axname 'Data'], vector(ssg.group_indices{gp}));
0253 end
0254 
0255 % Reset the camera in case the axis scales have changed dramatically.
0256 haxes = handles.axes_handle;
0257 axis(haxes, 'tight');
0258 if ~isempty(get(ssg.group_handles(1), 'ZData'))
0259     campos(haxes,'auto'); camtarget(haxes,'auto');  view(haxes,3);
0260     camva(haxes,'auto');  camup(haxes,'auto');      camva(haxes,camva(haxes)); 
0261 end
0262 daspect(haxes,'auto');   daspect(haxes,daspect(haxes));
0263 
0264 % Change the axis labels to reflect the new reality.
0265 label = ssg.([axname 'choice']);
0266 if (strcmp(get(handles.edit_param1, 'Enable'), 'on'))
0267     label = [label ssg.([axname 'param1'])];
0268 end
0269 set(get(haxes, [axname 'Label']), 'String', label);
0270 
0271 % Store guidata's and raise this axis control to the top.
0272 guidata(handles.axes_handle, ssg);
0273 guidata(handles.figure_ssg_featureselect, handles);
0274 figure(handles.figure_ssg_featureselect);

Generated on Tue 15-Aug-2006 22:51:57 by m2html © 2003