[Master Index] [Index for Toolbox]

# parametric_estimation

## (Toolbox/parametric_estimation.m in BrainStorm 2.0 (Alpha))

### Function Synopsis

    varargout = parametric_estimation(varargin)

### Help Text

    PARAMETRIC_ESTIMATION - GUI for selecting data segments and subspaces prior to estimation
     function varargout = parametric_estimation(varargin)
        FIG = PARAMETRIC_ESTIMATION launch parametric_estimation GUI.
        PARAMETRIC_ESTIMATION('callback_name', ...) invoke the named callback.

     Application Data in this GUI, handles.ParametricEstimation
      StudySubject, standard structure
      Data, standard structure as loaded from the disk
      DataFile, fully qualified filename
      USV, decomposition of selected data segment
      hplot, handle to the vertical line the SVD plot

### Cross-Reference Information

This function calls

    aic_mdl                            C:\BrainStorm_2001\Toolbox\aic_mdl.m
    bst_color_scheme                   C:\BrainStorm_2001\Toolbox\bst_color_scheme.m
    bst_layout                         C:\BrainStorm_2001\Toolbox\bst_layout.m
    bst_message_window                 C:\BrainStorm_2001\Toolbox\bst_message_window.m
    bst_static_taskbar                 C:\BrainStorm_2001\Toolbox\bst_static_taskbar.m
    data_manager                       C:\BrainStorm_2001\Toolbox\data_manager.m
    data_selector_cb                   C:\BrainStorm_2001\Toolbox\data_selector_cb.m
    dataplot_cb                        C:\BrainStorm_2001\Toolbox\dataplot_cb.m
    find_brainstorm_structure          C:\BrainStorm_2001\Toolbox\find_brainstorm_structure.m
    get_user_directory                 C:\BrainStorm_2001\Toolbox\get_user_directory.m
    good_channel                       C:\BrainStorm_2001\Toolbox\good_channel.m
    least_squares_parameters_cb        C:\BrainStorm_2001\Toolbox\least_squares_parameters_cb.m
    load_brainstorm_file               C:\BrainStorm_2001\Toolbox\load_brainstorm_file.m
    offset                             C:\BrainStorm_2001\Toolbox\offset.m
    rap_music_parameters               C:\BrainStorm_2001\Toolbox\rap_music_parameters.m
    save_fieldnames                    C:\BrainStorm_2001\Toolbox\save_fieldnames.m
    svd0                               C:\BrainStorm_2001\Toolbox\svd0.m

This function is called by

    bst_static_taskbar                 C:\BrainStorm_2001\Toolbox\bst_static_taskbar.m
    dataplot_cb                        C:\BrainStorm_2001\Toolbox\dataplot_cb.m

### Listing of function C:\BrainStorm_2001\Toolbox\parametric_estimation.m

    function varargout = parametric_estimation(varargin)
    %PARAMETRIC_ESTIMATION - GUI for selecting data segments and subspaces prior to estimation
    % function varargout = parametric_estimation(varargin)
    %    FIG = PARAMETRIC_ESTIMATION launch parametric_estimation GUI.
    %    PARAMETRIC_ESTIMATION('callback_name', ...) invoke the named callback.
    %
    % Application Data in this GUI, handles.ParametricEstimation
    %  StudySubject, standard structure
    %  Data, standard structure as loaded from the disk
    %  DataFile, fully qualified filename
    %  USV, decomposition of selected data segment
    %  hplot, handle to the vertical line the SVD plot

    %<autobegin> ---------------------- 16-Jun-2004 16:50:24 -----------------------
    % --------- Automatically Generated Comments Block Using AUTO_COMMENTS ---------
    %
    % CATEGORY: Inverse Modeling
    %
    % Alphabetical list of external functions (non-Matlab):
    %   toolbox\aic_mdl.m
    %   toolbox\bst_color_scheme.m
    %   toolbox\bst_layout.m
    %   toolbox\bst_message_window.m
    %   toolbox\bst_static_taskbar.m
    %   toolbox\data_manager.m
    %   toolbox\dataplot_cb.m
    %   toolbox\find_brainstorm_structure.m
    %   toolbox\get_user_directory.m
    %   toolbox\good_channel.m
    %   toolbox\least_squares_parameters_cb.m
    %   toolbox\load_brainstorm_file.m
    %   toolbox\rap_music_parameters.m
    %   toolbox\save_fieldnames.m
    %   toolbox\svd0.m
    %
    % Subfunctions in this file, in order of occurrence in file:
    %   reset_gui(h, eventdata, handles, varargin);
    %   load_gui(h,eventdata,handles,varargin);
    %   V = zoom_axis(h, eventdata, handles, varargin);
    %   set_axis(h,eventdata,handles,varargin,V);
    %   update_stats(h, eventdata, handles, varargin);
    %   decompose(h,eventdata,handles,varargin);
    %   plot_signalnoise(h,eventdata,handles,varargin);
    %   GUI = start_gui_structure(h,eventdata,handles,varargin);
    %   varargout = PopupSVD_Callback(h, eventdata, handles, varargin)
    %   varargout = EditRank_Callback(h, eventdata, handles, varargin)
    %   varargout = SliderRank_Callback(h, eventdata, handles, varargin)
    %   varargout = EditMinTime_Callback(h, eventdata, handles, varargin)
    %   varargout = EditMaxTime_Callback(h, eventdata, handles, varargin)
    %   varargout = Data_Stats_Callback(h, eventdata, handles, varargin)
    %   varargout = AxisStudy_ButtonDownFcn(h, eventdata, handles, varargin)
    %   varargout = AxisSignalSubspace_ButtonDownFcn(h, eventdata, handles, varargin)
    %   varargout = AxisNoiseSubspace_ButtonDownFcn(h, eventdata, handles, varargin)
    %   varargout = AxisSVD_ButtonDownFcn(h, eventdata, handles, varargin)
    %   varargout = Pushbutton_decompose_Callback(h, eventdata, handles, varargin)
    %   varargout = DatabaseManager_Callback(h, eventdata, handles, varargin)
    %   varargout = pushbutton_reload_data_Callback(h, eventdata, handles, varargin)
    %   varargout = pushbutton_help_Callback(h, eventdata, handles, varargin)
    %   varargout = button_grid_Callback(h, eventdata, handles, varargin)
    %   varargout = Quit_Callback(h, eventdata, handles, varargin)
    %   varargout = radiobutton_eeg_Callback(h, eventdata, handles, varargin)
    %   varargout = radiobutton_meg_Callback(h, eventdata, handles, varargin)
    %   varargout = EstimationTechnique_Callback(h, eventdata, handles, varargin)
    %   varargout = togglebutton_zoom_Callback(h, eventdata, handles, varargin)
    %   varargout = togglebutton_zoom_ButtonDownFcn(h, eventdata, handles, varargin)
    %   varargout = popupmenu_domain_Callback(h, eventdata, handles, varargin)
    %   varargout = uicontextmenu_selection_action_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_data_exclude_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_clear_data_exclusion_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_subspace_reject_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_clear_projector_Callback(h, eventdata, handles, varargin)
    %   varargout = togglebutton_projector_detect_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_help_selection_action_Callback(h, eventdata, handles, varargin)
    %
    % Application data and their calls in this file:
    %   'Data'
    %   'DataFile'
    %   'StudySubject'
    %   'TileType'
    %   'USV'
    %   'hplot'
    %   'hvertical_lines'
    %   'rbbox_points'
    %
    %   setappdata(fig,'Data',Data);
    %   setappdata(fig,'DataFile',DataFile);
    %   setappdata(fig,'StudySubject',StudySubject);
    %   setappdata(fig,'TileType','T');
    %   setappdata(fig,'USV',struct('U',U,'S',S,'V',V,'vSeS',[vS eS],...
    %   setappdata(fig,'hplot',hplot);
    %   setappdata(fig,'hvertical_lines',hvertical_lines);
    %   setappdata(fig,'rbbox_points',[]);
    %   setappdata(fig,'rbbox_points',[p1;p2]);
    %
    %   Data = getappdata(fig,'Data');
    %   DataFile = getappdata(fig,'DataFile');
    %   StudySubject = getappdata(fig,'StudySubject');
    %   USV = getappdata(fig,'USV');
    %   data.Measures.NoiseModelParam.StudySubject = getappdata(fig,'StudySubject');
    %   filename = getappdata(fig,'DataFile');
    %   hplot = getappdata(fig,'hplot');
    %   hvertical_lines = getappdata(fig,'hvertical_lines');
    %   points = getappdata(fig,'rbbox_points');
    %
    % Figure Files opened by this function:
    %   'dataplot.fig'
    %   mfilename
    %
    %   Format of strings below: Type:Style:Tag, "String", CallBack Type and Call
    %   <automatic> callback is <Tag>_Callback by Matlab default
    %
    % Callbacks by figure dataplot.fig
    %   figure::DATAPLOT "" uses DeleteFcn for clear global data
    %   uicontrol:edit:current_time "0" uses Callback for dataplot_cb set_current_time
    %   uicontrol:edit:step "''" uses Callback for dataplot_cb set_time_step
    %   uicontrol:edit:time_max "" uses Callback for dataplot_cb set_time_max
    %   uicontrol:edit:time_min "" uses Callback for dataplot_cb set_time_min
    %   uicontrol:popupmenu:ChangeUnits "MKS" uses Callback for
    %     dataplot_cb('ChangeUnits','reset'),dataplot_cb ChangeUnits
    %   uicontrol:popupmenu:DataViewingDataType "Original Data" uses Callback for
    %     dataplot_cb DataViewingDataType
    %   uicontrol:popupmenu:DataViewingSpatialDisplay "<No Scalp Topography>" uses Callback for
    %     dataplot_cb('DataViewingSpatialDisplay', 'reset'), dataplot_cb DataViewingSpatialDisplay
    %   uicontrol:popupmenu:DataViewingTimeDisplay "<No Time Display>" uses Callback for
    %     dataplot_cb DataViewingTimeDisplay
    %   uicontrol:popupmenu:SourceEstimationMethod "-------- IMAGING " uses Callback for
    %     dataplot_cb SourceImaging
    %   uicontrol:popupmenu:SourceViewingSpatialDisplay "<No Spatial Topography>" uses Callback for
    %     dataplot_cb SourceViewingSpatialDisplay
    %   uicontrol:popupmenu:SourceViewingTimeDisplay "<No Time Display>" uses Callback for
    %     dataplot_cb SourceViewingTimeDisplay
    %   uicontrol:pushbutton:HPlot "Plot" uses Callback for dataplot_cb('Plot','Measures')
    %   uicontrol:pushbutton:HPlotTimeSeries "Plot" uses Callback for dataplot_cb('Plot','RESULTS')
    %   uicontrol:pushbutton:HSetDataViewing "Set" uses Callback for dataplot_cb SetDataViewing
    %   uicontrol:pushbutton:HSetSourceViewing "Set" uses Callback for dataplot_cb SetSourceViewing
    %   uicontrol:pushbutton:MSIndexSwitch "ms/index" uses Callback for dataplot_cb MSIndexSwitch
    %   uicontrol:pushbutton:NoiseModel "Noise Model" uses Callback for dataplot_cb CallDataSelector
    %   uicontrol:pushbutton:pushbutton6 "Save" uses Callback for dataplot_cb saveas
    %   uicontrol:pushbutton:SourceModel "Source Model" uses Callback for
    %     dummy_dynamic_viewer('pushbutton11_Callback',gcbo,[],guidata(gcbo))
    %   uicontrol:slider:TimeSlider "" uses Callback for dataplot_cb mapping_slider
    %
    % Callbacks by figure parametric_estimation.fig
    %   axes::AxisNoiseSubspace "" uses ButtonDownFcn for <automatic>
    %   axes::AxisSignalSubspace "" uses ButtonDownFcn for <automatic>
    %   axes::AxisSVD "" uses ButtonDownFcn for <automatic>
    %   uicontextmenu::uicontextmenu_selection_action "" uses Callback for <automatic>
    %   uicontrol:checkbox:button_grid "Gridding" uses Callback for <automatic>
    %   uicontrol:checkbox:PopupSVD "Log Y-Axis" uses Callback for <automatic>
    %   uicontrol:edit:EditMaxTime "Max" uses Callback for <automatic>
    %   uicontrol:edit:EditMinTime "Min" uses Callback for <automatic>
    %   uicontrol:edit:EditRank "Rank" uses Callback for <automatic>
    %   uicontrol:listbox:Data_Stats "Time Index:" uses Callback for <automatic>
    %   uicontrol:popupmenu:EstimationTechnique "Select Method . . ." uses Callback for <automatic>
    %   uicontrol:popupmenu:popupmenu_domain "Time" uses Callback for <automatic>
    %   uicontrol:pushbutton:DatabaseManager "Data Manager" uses Callback for <automatic>
    %   uicontrol:pushbutton:Pushbutton_decompose "Decompose" uses Callback for <automatic>
    %   uicontrol:pushbutton:pushbutton_help "Help" uses Callback for <automatic>
    %   uicontrol:pushbutton:pushbutton_reload_data "Reload Data" uses Callback for <automatic>
    %   uicontrol:pushbutton:Quit "Done" uses Callback for <automatic>
    %   uicontrol:radiobutton:radiobutton_eeg "EEG Data" uses Callback for <automatic>
    %   uicontrol:radiobutton:radiobutton_meg "MEG Data" uses Callback for <automatic>
    %   uicontrol:slider:SliderRank "" uses Callback for <automatic>
    %   uicontrol:togglebutton:togglebutton_projector_detect "No Projector Detected" uses Callback for <automatic>
    %   uicontrol:togglebutton:togglebutton_zoom "Zoom Mode" uses ButtonDownFcn for <automatic>
    %   uicontrol:togglebutton:togglebutton_zoom "Zoom Mode" uses Callback for <automatic>
    %   uimenu::uimenu_clear_data_exclusion "" uses Callback for <automatic>
    %   uimenu::uimenu_clear_projector "" uses Callback for <automatic>
    %   uimenu::uimenu_data_exclude "" uses Callback for <automatic>
    %   uimenu::uimenu_help_selection_action "" uses Callback for <automatic>
    %   uimenu::uimenu_subspace_reject "" uses Callback for <automatic>
    %
    % At Check-in: $Author: Mosher $  $Revision: 49 $  $Date: 6/16/04 3:16p $
    %
    % This software is part of BrainStorm Toolbox Version 2.0 (Alpha) 16-Jun-2004
    %
    % Principal Investigators and Developers:
    % ** Richard M. Leahy, PhD, Signal & Image Processing Institute,
    %    University of Southern California, Los Angeles, CA
    % ** John C. Mosher, PhD, Biophysics Group,
    %    Los Alamos National Laboratory, Los Alamos, NM
    % ** Sylvain Baillet, PhD, Cognitive Neuroscience & Brain Imaging Laboratory,
    %    CNRS, Hopital de la Salpetriere, Paris, France
    %
    % See BrainStorm website at http://neuroimage.usc.edu for further information.
    %
    % Copyright (c) 2004 BrainStorm by the University of Southern California
    % This software distributed  under the terms of the GNU General Public License
    % as published by the Free Software Foundation. Further details on the GPL
    % license can be found at http://www.gnu.org/copyleft/gpl.html .
    %
    % FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
    % UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
    % WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
    % MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
    % LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
    %<autoend> ------------------------ 16-Jun-2004 16:50:24 -----------------------

    % Last Modified by GUIDE v2.0 10-Jul-2003 17:28:47

    % ----------------------------------------------
    % JCM spring 2002  development
    % JCM 02-Jul-2002  detect if projector has the right number of rows, ignore if different
    % JCM 31-Oct-2002  Comments editing, alteration of Estimation activation button
    % SB  20-Nov-2002  Minor display enhancements
    %                  Fixed issues related to data sets with both EEG and MEG data
    % SB  11-Jul-2003  Made the link with the Viewer
    % ----------------------------------------------

    if nargin == 0  % LAUNCH GUI

        fig = openfig(mfilename,'reuse'); % SB | Just open it once

        % Generate a structure of handles to pass to callbacks, and store it.
        handles = guihandles(fig);
        guidata(fig, handles);

        if nargout > 0
            varargout{1} = fig;
        end

       % custom routines
       bst_color_scheme(fig);
       set(handles.Data_Stats,'fontname','default'); % prettier than fixedwidth
       setappdata(fig,'TileType','T'); % a tile
       bst_layout('align',fig,1,1,1); % one big tile
       set(fig,'Visible','on')

       % now initialize
       reset_gui(fig,[],handles,[]); % setup all uicontrols
       load_gui(fig,[],handles,[]); % load the current datamanager trial

    elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK

        try
            if (nargout)
                [varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard
            else
                feval(varargin{:}); % FEVAL switchyard
            end
        catch
            disp(lasterr);
        end

    end

    % ------------------- local functions ------------------------------
    % ----------------------------- RESET GUI -------------------------------
    function reset_gui(h, eventdata, handles, varargin);
    % reset all of the uicontrols
    % Reset all of the buttons to initial values, refresh the studies list
    % Objects:  AxisStudy, AxisSignal, AxisNoise, AxisSVD
    %  EditMinTime, EditMaxTime, EditRank, SliderRank, SliderCorr,
    %  PopupSVD

    fig = handles.ParametricEstimation; % handy shortcut

    % set zoom default on
    set(handles.togglebutton_zoom,'Val',1);
    % set the color correctly
    togglebutton_zoom_Callback(handles.togglebutton_zoom, eventdata, handles, varargin)

    % clear the strings, enable
    TAGS ={'EditMinTime', 'EditMaxTime', 'EditRank'};
    for i = 1:length(TAGS),
       ht = getfield(handles,TAGS{i});
       set(ht,'Enable','On','String',' ');
    end

    % set the initial value to zero on the sliders, enable
    TAGS = {'SliderRank'};
    for i = 1:length(TAGS),
       ht = getfield(handles,TAGS{i});
       set(ht,'Enable','On','Min',0,'Max',1,'Value',0);
    end
    TAGS = {'EditRank'};
    for i = 1:length(TAGS),
       ht = getfield(handles,TAGS{i});
       set(ht,'Enable','On','String',0);
    end

    % set the initial value of popups to one, enable
    TAGS = {'PopupSVD'};
    for i = 1:length(TAGS),
       ht = getfield(handles,TAGS{i});
       set(ht,'Enable','On','Value',1);
    end

    % clear all of the axes
    TAGS = {'AxisSignalSubspace', 'AxisNoiseSubspace', 'AxisSVD'};
    for i = 1:length(TAGS),
       ht = getfield(handles,TAGS{i});
       set(fig,'CurrentAxes',ht);
       cla % do not use cla reset
       axis tight
       zoom off % don't want competition with our own zoom function
    end

    if(isappdata(fig,'Data')),
       rmappdata(fig,'Data'); % the current data set
    end
    if(isappdata(fig,'USV')),
       rmappdata(fig,'USV'); % it's decomposition
    end
    if(isappdata(fig,'SubjectStudy')),
       rmappdata(fig,'SubjectStudy'); % and the file information
    end
    if(isappdata(fig,'hplot')),
       rmappdata(fig,'hplot'); % the handle to the SVD vertical line
    end

    % the rubber band points for selecting a data region
    if(~isappdata(fig,'rbbox_points'))
       setappdata(fig,'rbbox_points',[]); % initialize as empty
    end

    % can't do until decomposed:
    set(handles.radiobutton_meg,'Enable','off');
    set(handles.radiobutton_eeg,'Enable','off');
    set(handles.SliderRank,'Enable','off');
    set(handles.EditRank,'Enable','off');
    set(handles.EstimationTechnique,'Enable','off');

    % these uimenus are not yet ready for use:
    set(handles.uimenu_data_exclude,'Enable','Off');
    set(handles.uimenu_clear_data_exclusion,'Enable','Off');

    % reset title of the main data graph
    % set(handles.text_stdata,'string','Spatio-temporal Data');

    if(0)
       % now set up custom actions for each important object.
       % Should have been saved with the .fig,
       %  but caca pasa
       ht = findobj(hf,'Tag','AxisStudy');
       set(ht,'ButtonDownFcn','data_selector_cb(''set time'')');

       ht = findobj(hf,'Tag','SliderRank');
       set(ht,'Value',0,'Min',0,'Max',1,'callback','data_selector_cb(''set sliderrank'')');
       ht = findobj(hf,'Tag','EditRank');
       set(ht,'String','0','callback','data_selector_cb(''set textrank'')');

       ht = findobj(hf,'Tag','EditMinTime');
       set(ht,'Callback','data_selector_cb(''set mintime'')');
       ht = findobj(hf,'Tag','EditMaxTime');
       set(ht,'Callback','data_selector_cb(''set maxtime'')');

       ht = findobj(hf,'Tag','Source Estimation');
       set(ht,'Enable','off'); % can't do estimation without data
       % end of reset
    end

    % -----------------------LOAD GUI WITH DATA FROM DATAMANAGER ---------------
    function load_gui(h,eventdata,handles,varargin);

    fig = handles.ParametricEstimation; % shortcut

    % Get the current data and load into the axis
    User = get_user_directory;
    if 0 %~isfield(User,'CurrentData') | ~isfield(User.CurrentData,'DataFile')
        bst_message_window({'','Use Data Manager to select trial first'});
        data_manager
        return
    end

    % Filename = fullfile(User.STUDIES,User.CurrentData.StudyFile);
    StudySubject = find_brainstorm_structure(User.CurrentData.StudyFile);

    % two methods of acquiring the data, either from the files or from the
    %  global variable
    METHOD_FILE = 1;
    METHOD_GLOBAL = 2;
    METHOD = METHOD_GLOBAL;%METHOD_FILE; % hardwire

    switch METHOD
    case METHOD_FILE

       [PathStr,Name,Ext,Versn] = fileparts(User.CurrentData.StudyFile);
       DataFile = bst_static_taskbar('GET','DATA');
       DataFile = DataFile{1};
       Data = load_brainstorm_file(DataFile); % only the first one
       Channel = load_brainstorm_file(StudySubject.Channel);
       Channel = Channel.Channel;

       % what time samples are desired
       try
          [ignore,timeNdx] = dataplot_cb('GET','TIME');
       catch
          % dataplot_cb may not have been open
          timeNdx = [1:size(Data.F,2)]; % assume all of the data
       end

       Data.F = Data.F(:,timeNdx);
       Data.Time = Data.Time(timeNdx);

       % [val,enable,h] = bst_static_taskbar('GET','MEG');
       % MEG = ~isempty(data.SelectedChannels{1}) & val ;
       % [val,enable,h] = bst_static_taskbar('GET','EEG');
       % EEG = ~isempty(data.SelectedChannels{2}) & val;
       % [val,enable,h] = bst_static_taskbar('GET','OTHER');
       % Other= ~isempty(data.SelectedChannels{3}) & val;
       % Test = [MEG,EEG,Other];
       % Label = {'MEG','EEG','OTHER'};
       %data.imod = find(Test);
       % if length(data.imod) > 1 % More than one modality selected
       %     errordlg('Please select only either MEG or EEG for noise modelling.')
       %     return
       % end
       % Sanity checks ----------DONE----------

       % Use Mosher Data structure: initialize and fill all fields

    case METHOD_GLOBAL

       global data % Get data from the Viewer's strcuture
       if isempty(data)
          disp('No global data selected.')
          return
       end

       % reassign the data variables
       DataFile = data.Measures.Filename{1}; % consider only the first filename
       % Get current time window defined in Viewer
       Data.Time =  linspace(data.Display.Time(1), data.Display.Time(end),data.Display.NumberOfSamples);
       Data.F = data.Measures.F{1}; % and only the first data cell element
       Channel = data.Measures.Channel;
       Data.ChannelFlag = data.Measures.ChannelFlag;
       cd(User.STUDIES)

       % what time samples are desired
       try
          [ignore,timeNdx] = dataplot_cb('GET','TIME');
       catch
          % dataplot_cb may not have been open
          timeNdx = [1:size(Data.F,2)]; % assume all of the data
       end

       if 0, % deprecated code | SB 14-06-04 | Data.F and .Time now are trimmed to what is seen in Viewer
           Data.F = Data.F(:,timeNdx);
           Data.Time = Data.Time(timeNdx);
       end

    end % which data loading method

    % load the projector
    Users = get_user_directory;
    cd(Users.STUDIES)
    tmp = load(DataFile,'Projector');
    Data.Projector = tmp.Projector;
    clear tmp

    % load the Noise Covariance (actually, square root)
    tmp = load(DataFile,'NoiseCov'); % load the noise covariance sqrt
    Data.NoiseCov = tmp.NoiseCov;
    clear tmp

    GoodChannelEEG = good_channel(Channel,Data.ChannelFlag,'EEG');
    GoodChannelMEG = good_channel(Channel,Data.ChannelFlag,'MEG');
    % CHEAT: What about the reference channels?

    if(isempty(GoodChannelMEG) & isempty(GoodChannelEEG)),
       % both were empty!
       bst_message_window({'','No valid EEG or MEG data!'});
       return
    else
        bst_message_window('wrap',...
            {...
                ' ',...
                'Current analysis consists of:',...
                sprintf('%d good EEG channels',length(GoodChannelEEG))...
                sprintf('%d good MEG channels',length(GoodChannelMEG)),...
            })
    end

    if 0, % deprecated code (was problematic when file contains both EEG and MEG). Read what user wants to look at from bst_static_taskbar
        % activate radio buttons as available
        if(~isempty(GoodChannelMEG)),
            % meg data, enable and check the button on
            set(handles.radiobutton_meg,'enable','on');
        else
            % no MEG data, be sure the EEG the EEG button is on
            set(handles.radiobutton_meg,'val',0); % no meg
            set(handles.radiobutton_eeg,'val',1); % must be eeg
        end

        if(~isempty(GoodChannelEEG)),
            % eeg data, enable and check the button on
            set(handles.radiobutton_eeg,'enable','on');
        else
            % no EEG data, be sure the MEG button is on
            set(handles.radiobutton_meg,'val',1); % must be meg data
            set(handles.radiobutton_eeg,'val',0); % no eeg data

        end
    end

    % What does the user want to look at MEG? EEG? Both ? etc.
    % Get this information from checkboxes in Static Taskbar
    [ValMEG,enable,hMEG] = bst_static_taskbar('GET','MEG');
    [ValEEG,enable,hEEG] = bst_static_taskbar('GET','EEG');
    [valOTHER,enable,hOTHER] = bst_static_taskbar('GET','OTHER');

    if ValEEG & ValMEG
        valEEG = 0; % when both are available look at MEG only by default
    end

    set(handles.radiobutton_meg,'val',ValMEG);
    set(handles.radiobutton_eeg,'val',ValEEG);

    % % what is the status of the data radio buttons
    % ValEEG = get(handles.radiobutton_eeg,'val');
    % ValMEG = get(handles.radiobutton_meg,'val');

    % by the nature of those buttons, one of them has to be set.
    GoodChannel = [];
    if(ValEEG),
        imod = 2;
        GoodChannel = [GoodChannel GoodChannelEEG];
    end
    if(ValMEG),
        imod = 1;
        GoodChannel = [GoodChannel GoodChannelMEG];
    end

    if isempty(GoodChannel)
        errordlg('Please select either MEG, EEG or OTHER from static taskbar','Empty channel selection');
        return
    end

    Data.Selected_Channel = GoodChannel; %[GoodChannelMEG;GoodChannelEEG]; % SB 20-Nov-2002 : Fixing issues related to data sets with both EEG and MEG data

    % is there a projector in the data?
    Colors = bst_color_scheme;
    if(~isempty(Data.Projector)),
       if(size(Data.Projector,1) ~= length(Data.Selected_Channel)),
          % invalid projector for channels selected
          bst_message_window('wrap',['Projector has a different number of rows than the ' ...
                'the channels selected. Projector ignored.']);
          Data.Projector = [];
       end
    end

    % Apply the whitener, if any
    if ~isempty(Data.NoiseCov),
       W = Data.NoiseCov(Data.Selected_Channel,:); % the portion of the data
       if any(isnan(W(:))),
          bst_message_window('NaNs in the noise covariance, re-estimate.')
       else
          Data.F(Data.Selected_Channel,:) = pinv(W)*Data.F(Data.Selected_Channel,:);
       end
    end

    % Apply the projector, if any
    if ~isempty(Data.Projector),
       Data.F(Data.Selected_Channel,:) = Data.F(Data.Selected_Channel,:) - ...
          Data.Projector*(Data.Projector'*Data.F(Data.Selected_Channel,:));
       set(handles.togglebutton_projector_detect,'value',1,'BackgroundColor',...
          Colors.ToggleOn,'ForegroundColor',[.5 .5 .5],'String',...
          'Projector Applied');
    else
       % no projector data detected
       set(handles.togglebutton_projector_detect,'value',0,'BackgroundColor',...
          Colors.ToggleOff,'ForegroundColor',Colors.ButtonText,'String',...
          'No Projector Detected');
    end

    setappdata(fig,'StudySubject',StudySubject);
    setappdata(fig,'Data',Data);
    setappdata(fig,'DataFile',DataFile);

    % now display in the AxisStudy

    set(0,'CurrentFigure',fig);
    set(fig,'CurrentAxes',handles.AxisSignalSubspace);
    cla
    hl=line(Data.Time*1000,Data.F(Data.Selected_Channel,:));
    set(hl,'hittest','off'); % nothing happens when clicking on line
    axis tight
    xlabel('Time (ms)');
    ylabel('Amplitude');

    set(handles.AxisNoiseSubspace,'Xlim',xlim);

    V = axis;
    set(handles.EditMinTime,'String',sprintf('%.1f ms',V(1)));
    set(handles.EditMaxTime,'String',sprintf('%.1f ms',V(2)));

    update_stats(h,eventdata,handles,varargin);

    % -------------------- CUSTOM ZOOMING FUNCTION --------------------------
    function V = zoom_axis(h, eventdata, handles, varargin);
    % Zoom the axis given by h if left click, reset zoom if right click
    % Use only in buttondown functions for each of the axes
    % Return the new axis settings

    % Zoom control only works if the Zoom toggle button is selected
    % If Zooming is off, then only gather the rubberband information
    %  and store in the application data.
    % Exception is if we are clicking on the SVD axis, for which zoom is always on
    %

    fig = handles.ParametricEstimation; % shorthand

    ZoomVal = get(handles.togglebutton_zoom,'Val');

    if(h==handles.AxisSVD),
       ZoomVal = 1; % effectively zoom is always on for the SVD display
    end

    Type = get(fig,'selectiontype'); %what kind of click

    % make the gcbo the current axes
    set(fig,'CurrentAxes',h);

    V = axis; % current settings

    switch Type
    case 'normal' % left click
       point1 = get(h,'CurrentPoint');   % button down detected
       finalRect = rbbox;               % return figure units
       point2 = get(h,'CurrentPoint');    % button up detected
       % more useful is to use the starting and ending points of the button clicks:
       point1 = point1(1,1:2);             % extract x and y (z meaningless here)
       point2 = point2(1,1:2);
       p1 = min(point1,point2);   % calculate locations
       p2 = max(point1,point2);   % p1 is lower left, p2 is upper right of box

       if(ZoomVal), % zooming is on
          offset = abs(point1-point2);        % and dimensions
          V = axis; % current settings
          % if user only drew a box less than 5% (1/20th) in both directions,
          %  then ignore
          if(offset(1) > (V(2)-V(1))/20 | offset(2) > (V(4)-V(3))/20)
             % box greater than 5% in one direction, zoom to it
             V = [p1(1) p2(1) p1(2) p2(2)]; % return new settings
             axis(V)
          else
             % box too small in both dimensions, do nothing
          end

       else
          % zooming is off, store rubberband information only
          setappdata(fig,'rbbox_points',[p1;p2]);

          % draw vertical lines, possibly deleting older ones
          if(isappdata(fig,'hvertical_lines')),
             hvertical_lines = getappdata(fig,'hvertical_lines');
             if(ishandle(hvertical_lines)),
                % could be older handles that no longer exist
                delete(hvertical_lines)
             end
          end

          hvertical_lines = line([p1(1) p2(1);p1(1) p2(1)],[V(3);V(4)]);
          set(hvertical_lines,'linewidth',4,'color','k');

          setappdata(fig,'hvertical_lines',hvertical_lines);
       end

    otherwise
       % not a single left click
       if(ZoomVal),
          % zooming is on, so zoom out
          axis tight % "zoom out" to the full coordinates of the data
          V = axis; % return new settings
       else
          % zooming is off, do nothing. AxisStudy has a uicontextmenu that
          %  will popup in this case
       end
    end

    % ---------------------- MAKE ALL AXES HAVE SAME RANGE -------------------
    function set_axis(h,eventdata,handles,varargin,V);
    fig = handles.ParametricEstimation; % shorthand

    % set(fig,'CurrentAxes',handles.AxisStudy);
    % axis(V);
    set(fig,'CurrentAxes',handles.AxisSignalSubspace);
    axis(V);
    set(fig,'CurrentAxes',handles.AxisNoiseSubspace);
    axis(V);

    set(handles.EditMinTime,'String',sprintf('%.1f ms',V(1)));
    set(handles.EditMaxTime,'String',sprintf('%.1f ms',V(2)));

    % ---------------------UPDATE STATISTICS IN LISTBOX --------------------
    function update_stats(h, eventdata, handles, varargin);
    fig = handles.ParametricEstimation; % shorthand

    % update the Data_Stats listbox with information
    % Is the SVD axis active?
    Val = str2num(get(handles.EditRank,'string'));
    if(Val), % non-zero, active
       Data = getappdata(fig,'Data');
       USV = getappdata(fig,'USV'); % decomposition
       S2 = full(diag(USV.S)).^2; % singular values squared
       E2 = USV.vSeS(:,2).^2; % estimated floor

       TotalVar = sum(S2);
       SignalVar = sum(S2(1:Val));
       NoiseVar = sum(S2((Val+1):end));
       ENoiseVar = sum(E2);
       msg_str = {...
             sprintf('%20s: %.0f of %.0f','Rank',Val,length(S2)),...
             sprintf('%20s: %5.1f%%','Signal Subspace',SignalVar/TotalVar*100),...
             sprintf('%20s: %5.1f%%','Noise Subspace',NoiseVar/TotalVar*100),...
             sprintf('%20s: %5.1f%%','Approximated Noise',ENoiseVar/TotalVar*100),...
             '',...
             sprintf('Time selected: %.1f ms, %.0f samples',...
             diff(USV.Time([1 end]))*1000,length(USV.Segment)),...
             sprintf('Interval selected: %.1f  to  %.1f ms',...
             USV.Time([1 end])*1000),...
             sprintf('Indices selected: %.0f to %.0f',USV.Segment([1 end])),...
             sprintf('Available: %.1f ms from %.1f to %.1f ms',...
             diff(Data.Time([1 end]))*1000,Data.Time([1 end])*1000),...
             sprintf('  %.0f samples at %.1f samples/sec',length(Data.Time),...
             length(Data.Time)/diff(Data.Time([1 end]))),...
             sprintf('Channels selected: %.0f of %.0f',...
             length(Data.Selected_Channel),length(Data.ChannelFlag)),...
             ''};
    else
       msg_str = {'"Decompose" for Stats',''};
    end

    StudySubject = getappdata(fig,'StudySubject');
    User = get_user_directory;

    %sprintf('Subject Name: %s',User.CurrentData.SubjectName),... % SB- 10-Oct-2003 removed display of subject name because it's not
    % straightfully available from User structure
    User.CurrentData.DataFile = bst_static_taskbar('GET','DATA');
    User.CurrentData.DataFile = User.CurrentData.DataFile{1};
    msg_str = [msg_str, {...
             sprintf('Database: %s',User.Comment),...
             sprintf('Data File: %s',User.CurrentData.DataFile),...
             sprintf(''),...
             sprintf('Subject: %s',StudySubject.Subject),...
             sprintf('Study: %s',StudySubject.Study),...
             sprintf('Channel: %s',StudySubject.Channel),...
             sprintf('HeadModel: %s',StudySubject.HeadModel)}];

    set(handles.Data_Stats,'string',msg_str);

    % update the title of the main graph
    % what radio buttons are selected
    ValE = get(handles.radiobutton_eeg,'val');
    ValM = get(handles.radiobutton_meg,'val');

    if(ValE & ~ValM),
       SUFFIX = 'EEG Data';
    elseif(~ValE & ValM),
       SUFFIX = 'MEG Data';
    elseif(ValE & ValM),
       SUFFIX = 'E/MEG Fusion';
    else
       SUFFIX = 'Bogus Case';
    end

    %set(handles.text_stdata,'string',[User.CurrentData.DataFile ' ' SUFFIX]); SB

    % ----------------- SVD THE DATA DISPLAYED IN THE TOP  DATA WINDOW ---------
    function decompose(h,eventdata,handles,varargin);
    % decompose the data and display
    fig = handles.ParametricEstimation; % figure handle

    set(handles.PopupSVD,'Value',1); % force a log state
    % retrieve the state
    iLogLin = get(handles.PopupSVD,'Value'); % 1 is log, 0 is linear

    % generate and save decomposed data
    Data = getappdata(fig,'Data'); %the current data

    % what has the user selected
    set(0,'CurrentFigure',fig);
    %set(fig,'CurrentAxes',handles.AxisStudy); SB
    set(fig,'CurrentAxes',handles.AxisSignalSubspace);
    V = axis; % current limits

    Time = Data.Time;
    mni = min(find(Time*1000 >= V(1))); % time index is in ms, set in display_data
    mxi = max(find(Time*1000 <= V(2)));
    F = Data.F(Data.Selected_Channel,[mni:mxi]); % what user has selected % was mni:mxi | SB
    Time = Data.Time([mni:mxi]);

    % is this a really big data set?
    BIG = prod(size(F)) > 1e5;
    if(BIG),
       bst_message_window('Decomposing large set of selected data . . .');
    end
    set(fig,'pointer','watch'); % wait symbol

    [U,S,V] = svd0(F); % economy SVD
    S = sparse(S); % make sparse

    % build noise estimate
    nS = min(size(S)); % how many values
    if(nS > 1),
       vS = full(diag(S)); % vector form of S
    else
       vS = full(S);
    end

    % vS is a vector of singular values.
    % Because of log plotting, don't want truly zero values
    % Adjust to be at noise floor
    vndx = find(vS < (eps*vS(1))); % less than epsilon
    vS(vndx) = eps*vS(1); % set to noise floor

    switch 2 % which method for estimating the noise floor
    case 1
       % old method of fitting linear line to smaller singular value
       midS = [1:round(nS/3)]'; % third the data
       midS = midS + round(nS/2); % centered on the half
       if(length(midS) >= 2), % need two points to define a line
          eS = polyval(polyfit(midS,vS(midS),1),[1:nS]'); % first order fit
       else
          % degenerate case, may be single time slice fitting
          eS = vS(end)+zeros(nS,1); % set to last value
       end
       ndx = find(eS <= 0); % negative values
       if(~isempty(ndx)), % some values
          eS(ndx) = eS(ndx(1)-1); % set to smallest positive value
       end

    case 2
       % new method November 2003 using MDL
       vndx = find(vS < .005*vS(1)); % less than this, don't believe
       if ~isempty(vndx)
          % now synthesize new noise with vndx(1) as the noise level
          vSadjust = svd(F + (vS(vndx(1))*randn(size(F))) );
       else
          vSadjust = vS; % keep as is
       end
       dim = aic_mdl(vSadjust.^2, size(F,2));
       RANK = dim(2); % the MDL method
       eS = zeros(size(vS)) + sqrt(mean(vSadjust((RANK+1):end).^2)); % average of the noise
    end
    % result of above switch case is vector eS of estimated singular values
    % [vS eS] is singular values and estimated noise values

    % setappdata(fig,'USV',struct('U',U,'S',S,'V',V,'vSeS',[vS eS],...
    %    'Time',Time(mni:mxi),'Segment',[mni:mxi]));
    % Indices of the time samples in original data time window
    % SB 18-Nov-2003 : get proper subset of time samples from original data
    [tmp,TimeSegment] = dataplot_cb('GET','time');

    setappdata(fig,'USV',struct('U',U,'S',S,'V',V,'vSeS',[vS eS],...
       'Time',Time,'Segment',TimeSegment));

    % Now set an initial RANK for the data matrix
    switch 3
    case 1
       % set the initial rank display to be 10%
       RANK = max(floor(length(vS)/10),1); % at least unity
    case 2
       % set the rank based on estimated noise floor
       cS2 = cumsum(vS.^2); % cumulative squared singular values
       eS2 = sum(eS.^2)/cS2(end); % total estimated noise power as fraction
       cS2 = cS2/cS2(end); % scale of 0 to 1 for power
       cN2 = 1-cS2; % relative power in noise-only subspace
       RANK = max(find(cN2 >= eS2))+1;
       if(isempty(RANK)),
          RANK = 1; % minimum
       end
       RANK = min(RANK,length(vS)); % don't exceed limit
    case 3
       % was set above by the MDL method, do nothing
    end

    % setup the slider
    set(handles.EditRank,'String',int2str(RANK)); % set the rank field
    MaxSlider = max(2,length(vS)); % need a minimum of two
    set(handles.SliderRank,'Min',1,'Max',MaxSlider,'Value',RANK,'Enable','On',...
       'SliderStep',[1/MaxSlider max(.1,2/MaxSlider)]); % want unity steps

    % now plot
    set(0,'CurrentFigure',fig);
    set(fig,'CurrentAxes',handles.AxisSVD);
    cla
    h = line([1:length(S)]',[vS eS]);
    set(h,'marker','*');

    switch iLogLin % which plot
    case 0 % linear
       set(handles.AxisSVD,'yscale','linear');
    case 1 % log
       set(handles.AxisSVD,'yscale','log')
    otherwise
       % what otherwise?
       msgbox(sprintf('Error in plotting SVD','Error','modal'))
       return
    end

    axis tight
    V = axis(handles.AxisSVD);
    % % But don't be ridiculous about tight
    % V(3) = max(V(3),V(4)/1e3);
    % axis(V);
    V = axis;

    vline_height = diff(V(3:4)); % height of line
    % extend upward by 5% for better visual effect
    vline_height = vline_height * 1.05;

    % plot the vertical bar between signal and noise subspace
    hplot = line([RANK;RANK]'+.5,[V(3); V(3)+vline_height]);
    set(hplot,'linewidth',2,'color','b','erasemode','xor');
    setappdata(fig,'hplot',hplot); % the handle to this line

    % now recursively call to plot the signal and noise data
    plot_signalnoise(fig,eventdata,handles,varargin);

    % set scales to the displayed data
    % set(fig,'CurrentAxes',handles.AxisStudy); SB
    set(fig,'CurrentAxes',handles.AxisSignalSubspace);
    V = axis;
    set_axis(h, eventdata, handles, varargin, V);

    % set(handles.EstimationTechnique,'Enable','on'); % now can estimate

    set(fig,'pointer','arrow'); % wait symbol done
    if(BIG), % update message window
       bst_message_window('overwrite','Done Decomposing');
    end

    figure(fig) % bring to front

    % can now do:
    set(handles.SliderRank,'Enable','on');
    set(handles.EditRank,'Enable','on');
    % set(handles.EstimationTechnique,'Enable','on');

    % ------------------- UPDATE THE SIGNAL AND NOISE SUBSPACE PLOTS ---------
    function plot_signalnoise(h,eventdata,handles,varargin);

    fig = handles.ParametricEstimation;
    set(0,'CurrentFigure',fig);

    RANK = get(handles.SliderRank,'Value'); % what is the rank

    if(~isappdata(fig,'USV')), % no decomposition available
       decompose(fig,eventdata,handles,varargin);
       % which will recursively call this routine again
    else
       USV = getappdata(fig,'USV'); % get the decomposition information

       set(fig,'CurrentAxes',handles.AxisSignalSubspace);
       cla
       hs = line(USV.Time*1000,USV.U(:,1:RANK)*(USV.S(1:RANK,1:RANK)*USV.V(:,1:RANK)'));
       set(hs,'hittest','off'); % easier zooming
       ylabel('Signal Subspace')

       set(fig,'CurrentAxes',handles.AxisNoiseSubspace);
       cla
       hn = line(USV.Time*1000,...
          USV.U(:,(RANK+1):end)*(USV.S((RANK+1):end,(RANK+1):end)*USV.V(:,(RANK+1):end)'));
       set(hn,'hittest','off');
       ylabel('Noise Subspace')

       update_stats(h, eventdata, handles, varargin);

    end

    % --------------- PREPARE THE GUI STRUCTURE FOR EXECUTION --------------
    function GUI = start_gui_structure(h,eventdata,handles,varargin);
    % begin the basic GUI parameter structure from this figure's appdata
    fig = handles.ParametricEstimation;

    DataFile = getappdata(fig,'DataFile'); % name
    Data = getappdata(fig,'Data'); % data
    USV = getappdata(fig,'USV'); % decomposition
    User = get_user_directory; % database
    RANK = get(handles.SliderRank,'val'); % selected rank
    ChannelFlag = -ones(size(Data.ChannelFlag)); %zeros(size(Data.ChannelFlag)); % initialize
    ChannelFlag(Data.Selected_Channel) = 1; % set desired flags on

    %Data.ChannelFlag is the status of all channels
    %GUI.ChannelFlag indicates which channels to process this run

    GUI = struct('DataName',DataFile,'Segment',USV.Segment,'Rank',RANK,...
       'ChannelFlag',ChannelFlag);

    % ----------------- The Uicontrol Callbacks -----------------

    % ----------------------SWITCH BETWEEN LOG AND LINEAR ---------------
    function varargout = PopupSVD_Callback(h, eventdata, handles, varargin)
    % Switch between log and linear scaling on the SVD plot
    switch get(h,'Val')
    case 1
       set(handles.AxisSVD,'Yscale','log');
    case 0
       set(handles.AxisSVD,'Yscale','linear');
    end

    % ------------------ TEXT ENTER RANK NUMBER ------------------------------
    function varargout = EditRank_Callback(h, eventdata, handles, varargin)
    % Convert string to new rank, integrity check, update subspace plots
    fig = handles.ParametricEstimation;

    RANK = str2num(get(h,'String'));
    if(isempty(RANK)),
       % did not understand user's string input
       RANK = round(get(handles.SliderRank,'Val')); % what is slider set to
       set(handles.EditRank,'string',sprintf('%.0f',RANK)); % reset edit box
    else
       % good number, check integrity
       RANK = max(1,round(RANK)); % must be a minimum of one
       RANK = min(RANK,get(handles.SliderRank,'Max')); % must be a max of dimension

       set(handles.EditRank,'string',sprintf('%.0f',RANK)); % feedback to edit box

       set(handles.SliderRank,'Val',RANK); % update the slider

       plot_signalnoise(h,eventdata,handles,varargin); % update the plots

       hplot = getappdata(fig,'hplot'); % the vertical line
       set(hplot,'Xdata',[1 1]*(RANK+.5)); % shift plot line to lie between integers
    end

    % --------------------------- USE SLIDER FOR RANK -------------------
    function varargout = SliderRank_Callback(h, eventdata, handles, varargin)
    fig = handles.ParametricEstimation;

    RANK = get(h,'Value');
    RANK = round(RANK);
    RANK = max(1,RANK); % minimum
    RANK = min(RANK,get(h,'Max')); % maximum

    set(h,'Value',RANK); % set to integer

    set(handles.EditRank,'String',sprintf('%.0f',RANK));
    plot_signalnoise(h,eventdata,handles,varargin);

    hplot = getappdata(fig,'hplot'); % the vertical line
    set(hplot,'Xdata',[1 1]*(RANK+.5)); % shift plot line to lie between two integers

    % --------------------- TEXT ENTER OF STARTING TIME OF DATA ----------------
    function varargout = EditMinTime_Callback(h, eventdata, handles, varargin)
    % user can use rubber band box, or enter time manually
    fig = handles.ParametricEstimation;

    str = get(h,'string'); % time that user entered
    set(0,'CurrentFigure',fig); %this figure
    set(fig,'CurrentAxes',handles.AxisSignalSubspace); % the data
    V = axis; % limits of existing plot
    newmin = sscanf(str,'%g',1); % user might have entered '4.5 ms'
    set_axis(h, eventdata, handles, varargin,[newmin V(2:end)]);

    % Update data Viewer window
    dataViewerfig = findobj(0,'Tag','DATAPLOT','type','figure');
    if isempty(dataViewerfig)
        errordlg('Please leave DataViewer open when running RAP-MUSIC estimation')
        return
    end

    % Update time window values
    viewHandles = guihandles(dataViewerfig);
    set(viewHandles.time_min,'String', newmin)
    dataplot_cb('set_time_min')

    decompose(h,eventdata,handles,varargin);

    % --------------------- TEXT ENTER OF ENDING TIME -------------------------
    function varargout = EditMaxTime_Callback(h, eventdata, handles, varargin)
    fig = handles.ParametricEstimation;

    str = get(h,'string'); % time that user entered
    set(0,'CurrentFigure',fig); %this figure
    set(fig,'CurrentAxes',handles.AxisSignalSubspace); % the data
    V = axis; % limits of existing plot
    newmax = sscanf(str,'%g',1); % user might have entered '4.5 ms'
    set_axis(h, eventdata, handles, varargin,[V(1) newmax V(3:end)]); %was [V(1) newmax V(3:end)] but bugged | SB

    % Update data Viewer window
    dataViewerfig = findobj(0,'Tag','DATAPLOT','type','figure');
    if isempty(dataViewerfig)
        errordlg('Please leave DataViewer open when running RAP-MUSIC estimation')
        return
    end

    % Update time window values
    viewHandles = guihandles(dataViewerfig);
    set(viewHandles.time_max,'String', newmax)
    dataplot_cb('set_time_max')

    decompose(h,eventdata,handles,varargin);

    % ------------------- LISTBOX CALLBACK -----------------------------------
    function varargout = Data_Stats_Callback(h, eventdata, handles, varargin)
    % the listbox of information, no action

    % ------------------ BUTTONDOWN ON DATA TO ZOOM --------------------------
    function varargout = AxisStudy_ButtonDownFcn(h, eventdata, handles, varargin)

    V = zoom_axis(h,eventdata, handles, varargin);
    % Make the other two plots have the same axis
    set_axis(h,eventdata, handles, varargin,V);

    % ------------------- BUTTONDOWN ON SUBSPACE TO ZOOM---------------------
    function varargout = AxisSignalSubspace_ButtonDownFcn(h, eventdata, handles, varargin)

    V = zoom_axis(h,eventdata, handles, varargin);
    % Make the other two plots have the same axis
    set_axis(h,eventdata, handles, varargin,V);

    % ------------------- BUTTONDOWN ON NOISE SPACE TO ZOOM---------------------
    function varargout = AxisNoiseSubspace_ButtonDownFcn(h, eventdata, handles, varargin)

    V = zoom_axis(h,eventdata, handles, varargin);
    % Make the other two plots have the same axis
    set_axis(h,eventdata, handles, varargin,V);

    % ------------------ BUTTONDOWN ON SVD PLOT TO ZOOM --------------------------
    function varargout = AxisSVD_ButtonDownFcn(h, eventdata, handles, varargin)

    V = zoom_axis(h,eventdata, handles, varargin);

    % ------------------- DECOMPOSE THE SELECTED DATA ---------------------------
    function varargout = Pushbutton_decompose_Callback(h, eventdata, handles, varargin)

    decompose(h,eventdata,handles,varargin);

    % ------------------- CALL THE DATABASE MANAGER ----------------------
    function varargout = DatabaseManager_Callback(h, eventdata, handles, varargin)

    figman = data_manager; % call the manager
    uiwait(figman); % wait for him to be done

    % now reload the data
    pushbutton_reload_data_Callback(handles.pushbutton_reload_data,[],handles);

    % ------------------- RELOAD THE CURRENT DATA IN THE DATAMANAGER -------------
    function varargout = pushbutton_reload_data_Callback(h, eventdata, handles, varargin)
    fig = handles.ParametricEstimation;

    reset_gui(fig,[],handles,[]); % setup all uicontrols
    load_gui(fig,[],handles,[]); % load the current datamanager trial

    % ------------------- SEND HELP TO THE MESSAGE WINDOW -----------------------
    function varargout = pushbutton_help_Callback(h, eventdata, handles, varargin)

    % multiple paragraphs:
    msg_str1 = ['Left click, drag, and release in any axis to zoom. ',...
          'Double-click or right-click in any axis to zoom out to "tight." ',...
          'Other windows will adjust to same axis.'];

    msg_str2 = ['Zoom top data window to desired region, or type in data range (in ms) ',...
          'in the edit windows of the top graph. Press Decompose to perform a ',...
          'Singular Value Decomposition (SVD) of the selected data. ',...
          'Right-click each spatio-temporal window to examine chosen data more ',...
          'closely. '];

    msg_str2b = ['Move Slider Rank or type in desired rank to change ',...
          'signal vs. noise-only subspaces. The green line in the SVD window ',...
          'is a crude guess as to the noise floor and is used to guess the ',...
          'percentage of noise in the data. Statistics window updates the percentage of ',...
          'variance in the signal and noise subspaces. Look for a rank that is either ',...
          'at a distinct drop in the singular values, or approximates the levels of ',...
          'noise.'];

    msg_str3 = ['Select estimation method to provide ',...
          'input for remaining necessary parameters.'];

    bst_message_window('wrap',{'Help for Parametric Estimation GUI','',...
          msg_str1,'',msg_str2,'',msg_str2b,'',msg_str3})

    % --------------------- SWITCH GRID ON AND OFF -------------------------
    function varargout = button_grid_Callback(h, eventdata, handles, varargin)

    ha = [handles.AxisSignalSubspace;...
          handles.AxisNoiseSubspace;handles.AxisSVD];
    switch get(h,'Val')
    case 0
       set(ha,'Xgrid','off','Ygrid','off');
    case 1
       set(ha,'Xgrid','on','Ygrid','on');
    end

    % ------------------- CLOSE THE WINDOW -------------------------------
    function varargout = Quit_Callback(h, eventdata, handles, varargin)
    fig = handles.ParametricEstimation; % shorthand

    global data
    data.Measures.NoiseModelParam = start_gui_structure(h,eventdata,handles,varargin); % Get noise parameters and save them in Viewer's structure
    data.Measures.NoiseModelParam.StudySubject = getappdata(fig,'StudySubject');

    DATAPLOT = openfig('dataplot.fig','reuse');
    if isempty(DATAPLOT), return, end

    DPhandles = guihandles(DATAPLOT);
    set(DPhandles.NoiseModelTag,'string','set')

    close(fig)

    % ---------------- SELECT EEG OR MEG DATA -------------------------------
    function varargout = radiobutton_eeg_Callback(h, eventdata, handles, varargin)
    % Which data set to display, or both
    %  radiobutton_meg calls this routine as well

    Vale = get(handles.radiobutton_eeg,'Val'); % the eeg button
    Valm = get(handles.radiobutton_meg,'Val'); % the meg button

    % handles to all the radio buttons in this group
    hall = [handles.radiobutton_eeg; handles.radiobutton_meg];
    ndx = find(hall ~= h); % which buttons were not called

    RESET = 1; % default, we need to reset the gui, with an exception below

    % we can't have both buttons off
    if(~Valm & ~Vale), % if both radio buttons are off
       % User has just turned off button h. See if the other button is enabled
       % what is the enable status of the other button
       switch lower(get(hall(ndx(1)),'Enable'))
       case 'on'
          % the other button is available
          set(hall(ndx(1)),'Val',1); % then turn back on the other button not pressed
       otherwise
          set(h,'Val',1); % other button not enabled, force this button to stay on
          % in this case, there is only one data set. No need to reset the GUI
          RESET = 0;
       end
    end
    % otherwise, the other set is enabled and selected,
    %  let the user automatically toggle this button on or off

    if(RESET), % is a reset of the GUI necessary?
       % Once the user has toggled the desired data, let him play with these
       %  buttons until he gets the combination he wants, b
       % But require him to manually reload the data
       % First, what is the current state of these two buttons
       EState = get(hall,'enable'); % enabled state of these buttons
       VState = get(hall,'Val'); % and their current values

       % reset the GUI.
       reset_gui(h, eventdata, handles, varargin);

       % put the data buttons back to their original state
       for i = 1:length(EState),
          set(hall(i),'Enable',EState{i},'Val',VState{i});
       end

       % user will need to reload the data
    end

    % ------------------- SELECT MEG BUTTON ----------------------------
    function varargout = radiobutton_meg_Callback(h, eventdata, handles, varargin)
    % works in cooperation with the eeg button
    radiobutton_eeg_Callback(h, eventdata, handles, varargin);

    % --------------------- SELECT ESTIMATION TECHNIQUE ---------------------
    function varargout = EstimationTechnique_Callback(h, eventdata, handles, varargin)
    % OBSOLETE: No longer used October 2003

    fig = handles.ParametricEstimation; % shorthand
    % Activate additional GUIs for particular parameters
    Val = get(handles.EstimationTechnique,'Val'); % what is the popup at?

    switch Val
    case 1 % Do Nothing "Estimate . . ." teaser

    case 2 % RAP-MUSIC
       % get the GUI parameters
       GUI = start_gui_structure(h,eventdata,handles,varargin);
       StudySubject = getappdata(fig,'StudySubject');

       hf = rap_music_parameters; % setup
       rap_music_parameters('load_parameters',hf,StudySubject,GUI);

    case 3 % Least-squares
       % get the GUI parameters
       GUI = start_gui_structure(h,eventdata,handles,varargin);
       StudySubject = getappdata(fig,'StudySubject');
       hf = least_squares_parameters_cb; % setup

       least_squares_parameters_cb(StudySubject,GUI,hf); %set up the popup

    otherwise
       bst_message_window(sprintf('Unknown estimation case'));
    end

    % now set the popup back to position 1, "Estimate . . ." teaser
    % set(handles.EstimationTechnique,'Val',1);

    % ---------------- ZOOM CONTROL ------------------------------------
    function varargout = togglebutton_zoom_Callback(h, eventdata, handles, varargin)
    % if on, then rubberband and right click control zooming.
    % if off, then rubberband selects regions only and right click is uicontextmenu

    Val = get(h,'Val');
    Colors = bst_color_scheme; % current scheme

    switch Val
    case 0
       % it's off
       set(h,'BackGroundColor',Colors.ToggleOff,'ForegroundColor',Colors.ButtonText);
    case 1
       % it's on
       set(h,'BackGroundColor',Colors.ToggleOn,'ForegroundColor',[.5 .5 .5]);
    end

    % --------------------------------------------------------------------
    function varargout = togglebutton_zoom_ButtonDownFcn(h, eventdata, handles, varargin)

    str1 = ['Toggle zoom off, then left click and pull on spatio-temporal data to select ',...
          'regions of the data. Then ',...
          'right click on spatio-temporal data to select noise projectors.'];

    bst_message_window('wrap',str1)

    % ---------------- DOMAIN SELECTION ------------------------------------
    function varargout = popupmenu_domain_Callback(h, eventdata, handles, varargin)
    % future version will allow primary window to display time, frequency, or spectrogram

    % --------------------------------------------------------------------
    function varargout = uicontextmenu_selection_action_Callback(h, eventdata, handles, varargin)

    hc = get(h,'children');

    % what is the status of the toggle button for zooming?
    Val = get(handles.togglebutton_zoom,'Val');

    switch Val
    case 0
       % user is NOT zooming, so show the uimenus
       for i = 1:length(hc),
          set(hc(i),'visible','on');
       end
    case 1
       % user IS ZOOMING, so DO NOT show the uimenus
       for i = 1:length(hc),
          set(hc(i),'visible','off');
       end
    end

    % --------------------------------------------------------------------
    function varargout = uimenu_data_exclude_Callback(h, eventdata, handles, varargin)

    % --------------------------------------------------------------------
    function varargout = uimenu_clear_data_exclusion_Callback(h, eventdata, handles, varargin)

    % --------------------------------------------------------------------
    function varargout = uimenu_subspace_reject_Callback(h, eventdata, handles, varargin)
    % if varargin is set to 'clear', do so, otherwise set projector based on region
    %  user selected with rubberband

    User = get_user_directory;

    fig = handles.ParametricEstimation; % shorthand

    if(~exist('varargin')),
       varargin{1} = [];
    end

    if(isempty(varargin))
       MODE = 'set';
    else
       MODE = varargin{1};
    end

    switch MODE
    case 'clear'
       Projector = [];
    case 'set'
       Data = getappdata(fig,'Data'); % the current data

       points = getappdata(fig,'rbbox_points'); % the region selected

       Left = points(1,1); % left most x-axis
       Right = points(2,1); % right most x-axis, don't care about y
       % units are in ms, convert Data.Time
       iLeft = min(find(Data.Time*1000 >= Left)); % left most index
       iRight = max(find(Data.Time*1000 <= Right));

       Region = Data.F(Data.Selected_Channel,iLeft:iRight);

       [U,S,V] = svd(Region,0);

       % now display the singular values in the SVD plot
       if(length(S) > 1),
          S = diag(S); % make a vector
       end

       set(0,'CurrentFigure',fig);
       set(fig,'CurrentAxes',handles.AxisSVD);
       cla
       hl = line([1:length(S)]',S);

       set(hl,'hittest','off'); % nothing happens when clicking on line

       set(hl,'marker','*');

       iLogLin = get(handles.PopupSVD,'Value'); % 1 is log, 0 is linear
       switch iLogLin % which plot
       case 0 % linear
          set(handles.AxisSVD,'yscale','linear');
       case 1 % log
          set(handles.AxisSVD,'yscale','log')
       otherwise
          % what otherwise?
          msgbox(sprintf('Error in plotting SVD','Error','modal'))
          return
       end

       axis tight
       V = axis;
       V(2) = min(V(2),20); % don't want too many for display purposes
       V(3) = max(V(4)/100,V(3))
       axis(V);

       prompt={'Enter the rank of the subspace (see graph)'};
       def={'1'};
       dlgTitle='Input for Subspace Projector';
       lineNo=1;
       answer=inputdlg(prompt,dlgTitle,lineNo,def);

       if(isempty(answer)),
          % cancelled out
          r = 0;
       else
          r = round(str2num(answer{1}));
          r = max(r,1); % quality control
          r = min(r,size(U,2)); % quality control
       end

       Projector = U(:,1:r);
    end

    % need to save this data in the data file itself
    filename = getappdata(fig,'DataFile'); % referential name

    cd(User.STUDIES);
    Data = load(filename);

    Data.Projector = Projector;

    save_fieldnames(Data,fullfile(User.STUDIES,filename)); % save back

    % and load the gui again
    reset_gui(fig,eventdata,handles,varargin);
    load_gui(fig,eventdata,handles,varargin);

    % --------------------------------------------------------------------
    function varargout = uimenu_clear_projector_Callback(h, eventdata, handles, varargin)

    uimenu_subspace_reject_Callback(handles.uimenu_subspace_reject, ...
       eventdata, handles, 'clear')

    % --------------------------------------------------------------------
    function varargout = togglebutton_projector_detect_Callback(h, eventdata, handles, varargin)
    % only used as a flag

    % --------------------------------------------------------------------
    function varargout = uimenu_help_selection_action_Callback(h, eventdata, handles, varargin)

    str0 = ['Selection Action Help'];
    str1 = ['Exclude Data: The region selected is removed from the data matrix and not ',...
          'processed.'];
    str2 = ['Exclude Subspace: The region selected is decomposed and the data are ',...
          'projected AWAY from the subspace selected.'];
    str3 = ['Clear Data Exclusion, Clear Projector: Removes the above exclusions and returns ',...
          'the data to its original state.'];

    bst_message_window('wrap',{'',str0,'',str1,'',str2,'',str3})

Produced by color_mat2html, a customized BrainStorm 2.0 (Alpha) version of mat2html on Tue Nov 2 16:17:59 2004
Cross-Directory links are: ON