[Master Index] [Index for Toolbox]

# simulator

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

### Function Synopsis

    varargout = simulator(varargin)

### Help Text

    SIMULATOR - Application M-file for simulator.fig
     function varargout = simulator(varargin)
        FIG = SIMULATOR launch simulator GUI.
        SIMULATOR('callback_name', ...) invoke the named callback.

### Cross-Reference Information

This function calls

    blk_diag                           C:\BrainStorm_2001\Toolbox\blk_diag.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
    get_user_directory                 C:\BrainStorm_2001\Toolbox\get_user_directory.m
    os_meg                             C:\BrainStorm_2001\Toolbox\os_meg.m
    save_fieldnames                    C:\BrainStorm_2001\Toolbox\save_fieldnames.m
    sensor_axial                       C:\BrainStorm_2001\Toolbox\sensor_axial.m
    sensor_planar                      C:\BrainStorm_2001\Toolbox\sensor_planar.m
    sensor_spacing                     C:\BrainStorm_2001\Toolbox\sensor_spacing.m
    str_repeater                       C:\BrainStorm_2001\Toolbox\str_repeater.m
    vec                                C:\BrainStorm_2001\Toolbox\vec.m

This function is called by

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

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

    function varargout = simulator(varargin)
    %SIMULATOR - Application M-file for simulator.fig
    % function varargout = simulator(varargin)
    %    FIG = SIMULATOR launch simulator GUI.
    %    SIMULATOR('callback_name', ...) invoke the named callback.

    %<autobegin> ---------------------- 26-May-2004 11:34:24 -----------------------
    % --------- Automatically Generated Comments Block Using AUTO_COMMENTS ---------
    %
    % CATEGORY: GUI and Related
    %
    % Alphabetical list of external functions (non-Matlab):
    %   toolbox\blk_diag.m
    %   toolbox\bst_color_scheme.m
    %   toolbox\bst_layout.m
    %   toolbox\bst_message_window.m
    %   toolbox\engstr.m
    %   toolbox\get_user_directory.m
    %   toolbox\os_meg.m
    %   toolbox\save_fieldnames.m
    %   toolbox\sensor_axial.m
    %   toolbox\sensor_planar.m
    %   toolbox\sensor_spacing.m
    %   toolbox\str_repeater.m
    %   toolbox\vec.m
    %
    % Subfunctions in this file, in order of occurrence in file:
    %   set_listbox_entry(h,newstr);
    %   link_listbox_vals(h, eventdata, handles);
    %   initialize_gui(h, eventdata, handles);
    %   varargout = pushbutton_load_results_Callback(h, eventdata, handles, varargin)
    %   varargout = edit_number_sources_Callback(h, eventdata, handles, varargin)
    %   varargout = listbox_source_model_Callback(h, eventdata, handles, varargin)
    %   varargout = listbox_source_location_Callback(h, eventdata, handles, varargin)
    %   varargout = listbox_source_orientation_Callback(h, eventdata, handles, varargin)
    %   varargout = listbox_source_amplitude_Callback(h, eventdata, handles, varargin)
    %   varargout = listbox_source_delay_Callback(h, eventdata, handles, varargin)
    %   varargout = listbox_source_waveform_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_source_model_dipole_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_source_model_multipole_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_waveform_hamming_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_waveform_hann_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_waveform_boxcar_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_waveform_triangle_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_waveform_sinusoid_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_waveform_custom_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_edit_location_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_random_location_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_edit_orientation_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_random_orientation_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_ForceTangential_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_edit_amplitude_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_edit_delay_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_help_location_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_help_amplitude_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_help_delay_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_help_waveform_Callback(h, eventdata, handles, varargin)
    %   varargout = uimenu_help_model_Callback(h, eventdata, handles, varargin)
    %   varargout = help_orientation_context_menu_Callback(h, eventdata, handles, varargin)
    %   varargout = edit_data_root_name_Callback(h, eventdata, handles, varargin)
    %   varargout = edit_STUDIES_Callback(h, eventdata, handles, varargin)
    %   varargout = edit_data_folder_name_Callback(h, eventdata, handles, varargin)
    %   varargout = edit_brain_radius_Callback(h, eventdata, handles, varargin)
    %   varargout = edit_scalp_radius_Callback(h, eventdata, handles, varargin)
    %   varargout = edit_sensor_radius_Callback(h, eventdata, handles, varargin)
    %   varargout = edit_head_center_Callback(h, eventdata, handles, varargin)
    %   varargout = edit_sensor_spacing_Callback(h, eventdata, handles, varargin)
    %   varargout = popup_sensor_coverage_Callback(h, eventdata, handles, varargin)
    %   varargout = popup_sensor_type_Callback(h, eventdata, handles, varargin)
    %   varargout = edit_sensor_baseline_Callback(h, eventdata, handles, varargin)
    %   varargout = popup_data_modality_Callback(h, eventdata, handles, varargin)
    %   varargout = edit_number_samples_Callback(h, eventdata, handles, varargin)
    %   varargout = popup_noise_generator_Callback(h, eventdata, handles, varargin)
    %   varargout = edit_noise_variance_Callback(h, eventdata, handles, varargin)
    %   varargout = Quit_Callback(h, eventdata, handles, varargin)
    %   varargout = pushbutton_generate_Callback(h, eventdata, handles, varargin)
    %
    % Application data and their calls in this file:
    %   'Center'
    %   'SourceLoc'
    %   'SourceOrientation'
    %   'TileType'
    %   'TimeSeries'
    %
    %   setappdata(fig,'Center',Center);
    %   setappdata(fig,'Center',UserFile.Center);
    %   setappdata(fig,'SourceLoc',UserFile.SourceLoc);
    %   setappdata(fig,'SourceOrientation',UserFile.SourceOrientation);
    %   setappdata(fig,'TileType','T');
    %   setappdata(fig,'TimeSeries',TimeSeries);
    %   setappdata(fig,'TimeSeries',UserFile.TimeSeries);
    %
    %   Center = getappdata(fig,'Center');
    %   SourceLoc = getappdata(fig,'SourceLoc');
    %   SourceOrientation = getappdata(fig,'SourceOrientation');
    %   TimeSeries = getappdata(fig,'TimeSeries');
    %
    % Figure Files opened by this function:
    %   mfilename
    %
    %   Format of strings below: Type:Style:Tag, "String", CallBack Type and Call
    %   <automatic> callback is <Tag>_Callback by Matlab default
    %
    % Callbacks by figure simulator.fig
    %   uicontrol:edit:edit_brain_radius "Brain Radius" uses Callback for <automatic>
    %   uicontrol:edit:edit_data_folder_name "Simulation Folder Name" uses Callback for <automatic>
    %   uicontrol:edit:edit_data_root_name "Root File Name" uses Callback for <automatic>
    %   uicontrol:edit:edit_head_center "Head Center" uses Callback for <automatic>
    %   uicontrol:edit:edit_noise_variance "Noise %" uses Callback for <automatic>
    %   uicontrol:edit:edit_number_samples "Number Samps" uses Callback for <automatic>
    %   uicontrol:edit:edit_number_sources "Num Sources" uses Callback for <automatic>
    %   uicontrol:edit:edit_scalp_radius "Scalp Radius" uses Callback for <automatic>
    %   uicontrol:edit:edit_sensor_baseline "Baseline Sep" uses Callback for <automatic>
    %   uicontrol:edit:edit_sensor_radius "Meg Sensor Radius" uses Callback for <automatic>
    %   uicontrol:edit:edit_sensor_spacing "Sensor Spacing" uses Callback for <automatic>
    %   uicontrol:edit:edit_STUDIES "Studies Folder" uses Callback for <automatic>
    %   uicontrol:listbox:listbox_source_amplitude "Amp" uses Callback for <automatic>
    %   uicontrol:listbox:listbox_source_delay "Delay Samps" uses Callback for <automatic>
    %   uicontrol:listbox:listbox_source_location "Location 1" uses Callback for <automatic>
    %   uicontrol:listbox:listbox_source_model "None" uses Callback for <automatic>
    %   uicontrol:listbox:listbox_source_orientation "Orientation" uses Callback for <automatic>
    %   uicontrol:listbox:listbox_source_waveform "Hamming" uses Callback for <automatic>
    %   uicontrol:popupmenu:popup_data_modality "MEG" uses Callback for <automatic>
    %   uicontrol:popupmenu:popup_noise_generator "Noiseless" uses Callback for <automatic>
    %   uicontrol:popupmenu:popup_sensor_coverage "Upper Hemisphere" uses Callback for <automatic>
    %   uicontrol:popupmenu:popup_sensor_type "Magnetometer" uses Callback for <automatic>
    %   uicontrol:pushbutton:pushbutton_generate "Generate" uses Callback for <automatic>
    %   uicontrol:pushbutton:pushbutton_load_results "Previous Results" uses Callback for <automatic>
    %   uimenu::help_orientation_context_menu "" uses Callback for <automatic>
    %   uimenu::uimenu_edit_amplitude "" uses Callback for <automatic>
    %   uimenu::uimenu_edit_delay "" uses Callback for <automatic>
    %   uimenu::uimenu_edit_location "" uses Callback for <automatic>
    %   uimenu::uimenu_edit_orientation "" uses Callback for <automatic>
    %   uimenu::uimenu_ForceTangential "" uses Callback for <automatic>
    %   uimenu::uimenu_help_amplitude "" uses Callback for <automatic>
    %   uimenu::uimenu_help_delay "" uses Callback for <automatic>
    %   uimenu::uimenu_help_location "" uses Callback for <automatic>
    %   uimenu::uimenu_help_model "" uses Callback for <automatic>
    %   uimenu::uimenu_help_waveform "" uses Callback for <automatic>
    %   uimenu::uimenu_random_location "" uses Callback for <automatic>
    %   uimenu::uimenu_random_orientation "" uses Callback for <automatic>
    %   uimenu::uimenu_source_model_dipole "" uses Callback for <automatic>
    %   uimenu::uimenu_source_model_multipole "" uses Callback for <automatic>
    %   uimenu::uimenu_waveform_boxcar "" uses Callback for <automatic>
    %   uimenu::uimenu_waveform_custom "" uses Callback for <automatic>
    %   uimenu::uimenu_waveform_hamming "" uses Callback for <automatic>
    %   uimenu::uimenu_waveform_hann "" uses Callback for <automatic>
    %   uimenu::uimenu_waveform_sinusoid "" uses Callback for <automatic>
    %   uimenu::uimenu_waveform_triangle "" uses Callback for <automatic>
    %
    % At Check-in: $Author: Mosher $  $Revision: 16 $  $Date: 5/26/04 10:02a $
    %
    % This software is part of BrainStorm Toolbox Version 2.0 (Alpha) 24-May-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> ------------------------ 26-May-2004 11:34:24 -----------------------

    % Last Modified by GUIDE v2.0 19-Jun-2002 08:58:59

    if nargin == 0  % LAUNCH GUI

        fig = openfig(mfilename,'reuse');

        % Use system color scheme for figure:
        set(fig,'Color',get(0,'defaultUicontrolBackgroundColor'));

        % 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

       bst_color_scheme(fig);
       setappdata(fig,'TileType','T');
       bst_layout('align',fig,2,1,1);
       initialize_gui(fig,[],handles);
       set(fig,'visible','on');

    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 ------------------------
    function set_listbox_entry(h,newstr);
    % set the current entry in the listbox to the new string
    % used by the uimenus

    str = get(h,'str');
    if(~iscellstr(str)),
       str = cellstr(str);
    end
    val = get(h,'val');
    str{val} = newstr;
    set(h,'string',str); % put it back

    % --------------------------------------------------------------------
    function link_listbox_vals(h, eventdata, handles);
    % set all listboxes to the same value

    val = get(h,'val'); % the setting of the current listbox
    links = {'model','location','orientation','amplitude','delay','waveform'};

    for i =1:length(links),
       eval(sprintf('set(handles.listbox_source_%s,''val'',val);',links{i}));
    end

    % --------------------------------------------------------------------
    function initialize_gui(h, eventdata, handles);

    fig = handles.figure_simulator; % handy shorthand
    User = get_user_directory;

    % Set location boxes
    % display current studies folder
    set(handles.edit_STUDIES,'string',User.STUDIES);

    % folder
    set(handles.edit_data_folder_name,'string','simulated');

    % data
    set(handles.edit_data_root_name,'string','sphere_');

    % sphere parameters
    set(handles.edit_brain_radius,'string','80');
    set(handles.edit_scalp_radius,'string','100');
    % head center set below

    % sensor parameters
    set(handles.edit_sensor_radius,'string','120');
    set(handles.edit_sensor_spacing,'string','25');
    set(handles.edit_sensor_baseline,'string','50');

    % Noise parameters
    set(handles.popup_noise_generator,'val',2); % gaussian is 2
    set(handles.edit_noise_variance,'string','1'); % good snr

    % Data Parameters
    % set the number of sources desired on initialization
    set(handles.edit_number_sources,'string','3');

    % now retrieve it
    NumSources = str2num(get(handles.edit_number_sources,'string'));

    % set the listbox strings
    links = {'model','location','orientation','amplitude','delay','waveform'};
    inits = {'Dipole','[0.0 0.0 80.0] mm','[1.00 0.00 0.00]','10 nA-m','10','Hamming'};

    % is there application data defined? use it instead as the defaults

    if(isappdata(fig,'SourceLoc'))
       % assume it is all there
       SourceLoc = getappdata(fig,'SourceLoc');
       SourceOrientation = getappdata(fig,'SourceOrientation');
       TimeSeries = getappdata(fig,'TimeSeries');
       % now convert to matrices
       SourceLoc = [SourceLoc{:}]; % make a matrix
       SourceOrientation = [SourceOrientation{:}];
    else
       SourceLoc = repmat([0;0;80]/1000,1,NumSources); % source locations
       SourceOrientation = repmat([1.00;0.00;0.00],1,NumSources); % orients
       TimeSeries = []; % empty
    end

    % NOTE: Will crash if load is for synchronized sources. TimeSeries not same as
    %  number of sources in that case. CBB.

    NumSources = size(SourceLoc,2); % number of sources

    % are there time series? Initialize the number of samples
    if(~isempty(TimeSeries)),
       inits{4} = '1 nA-m'; % unity scaling
       inits{5} = '0'; % no delay
       inits{6} = 'Custom'; % custom waveform
       set(handles.edit_number_samples,'String',int2str(size(TimeSeries,1)));
    else
       set(handles.edit_number_samples,'String','100');
    end

    % now initialize listboxes
    for i = 1:length(links),
       eval(sprintf(...
          'set(handles.listbox_source_%s,''val'',1,''string'',cellstr(repmat(''%s'',%.0f,1)));',...
          links{i},inits{i},NumSources));
    end

    % now overwrite just the custom initialization
    cLoc = cell(NumSources,1); % cell array of locations
    cOrient = cell(NumSources,1); % orientions

    set(handles.edit_number_sources,'String',int2str(NumSources));
    for i = 1:NumSources,
       cLoc{i} = ['[' str_repeater('%.1f',' ',SourceLoc(:,i)*1000) '] mm']; % pretty print
       cOrient{i} = ['[' str_repeater('%.2f',' ',SourceOrientation(:,i)) ']'];
    end

    set(handles.listbox_source_location,'String',cLoc);
    set(handles.listbox_source_orientation,'String',cOrient);

    % How about a center?
    if(isappdata(fig,'Center')),
       Center = getappdata(fig,'Center');
       set(handles.edit_head_center,'string',sprintf('[%.1f %.1f %.1f]',...
          Center*1000));
    else
       set(handles.edit_head_center,'string','[0 0 0]');
    end

    % activate the callback for sources
    edit_number_sources_Callback(handles.edit_number_sources,eventdata,handles);

    % --------------- UICONTROL CALLBACKS --------------------

    % ------------ LOAD PREVIOUS RESULTS FOR SIMULATION -------------------
    function varargout = pushbutton_load_results_Callback(h, eventdata, handles, varargin)

    fig = handles.figure_simulator; % handy shorthand

    % load a set of starting points from a file, presumably a results file
    % All that really matters is that the file contain SourceLoc, a
    %  cell array of three-dimensional locations
    User = get_user_directory; % the default locations of files
    cd(User.STUDIES); % set to the studies tree
    [Filename,Pathname]= uigetfile('*results*.mat',...
       'Select a File to Load in a Set of Starting Points');
    if(Filename == 0),
       % user selected nothing, do nothing
       return
    end

    UserFile = load(fullfile(Pathname,Filename));
    if(~isfield(UserFile,'SourceLoc')),
       errordlg('The file you selected does not have SourceLoc',...
          'Simulator Load Error');
       return
    end

    % assume the other parameters are there, in addition to SourceLoc
    setappdata(fig,'SourceLoc',UserFile.SourceLoc);
    setappdata(fig,'SourceOrientation',UserFile.SourceOrientation);
    setappdata(fig,'TimeSeries',UserFile.TimeSeries);

    if(isfield(UserFile,'IndepTopo')),
       % proper units, not contributions
       TimeSeries = pinv(UserFile.IndepTopo)*UserFile.Fsynth;
       TimeSeries = TimeSeries';
       setappdata(fig,'TimeSeries',TimeSeries);
    end

    % Is there a headcenter
    if(isappdata(fig,'Center')),
       rmappdata(fig,'Center'); % initialize as nonexistant
    end

    if(isfield(UserFile,'StudySubject')), % the file has a StudySubject structure
       if(isfield(UserFile.StudySubject,'HeadModel')), % with a headmodel field
          if(exist(UserFile.StudySubject.HeadModel,'file')),
             % and the file exists
             HeadModel = load(fullfile(User.STUDIES,UserFile.StudySubject.HeadModel));
             Center = mean([HeadModel.Param.Center],2);  % average over all centers
             setappdata(fig,'Center',Center);
          end
       end
    end % if the studysubject exists

    % simulated data may conveniently have the Center defined in the file
    if(isfield(UserFile,'Center')),
       % overrides the HeadModel, if there was one
       setappdata(fig,'Center',UserFile.Center);
    end

    initialize_gui(fig, eventdata, handles);

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

    NumSources = round(str2num(get(h,'string')));
    set(h,'string',NumSources) % properly displayed

    % how many sources were there originally
    Cstr = get(handles.listbox_source_model,'string');
    OldNum = length(Cstr); % old number of sources

    % set the listbox strings
    links = {'model','location','orientation','amplitude','delay','waveform'};
    inits = {'Dipole','[0.0 0.0 80.0] mm','[1.00 0.00 0.00]','10 nA-m','10','Hamming'};

    if(OldNum < NumSources),
       % we need to initialize some new sources
       NewNum = NumSources - OldNum;

       for i = 1:length(links),
          hlist = eval(sprintf('handles.listbox_source_%s',links{i}));
          OldCstr = get(hlist,'String'); % old string array
          NewCstr = cellstr(repmat(inits{i},NewNum,1));
          set(hlist,'val',1,'string',[OldCstr;NewCstr]);
       end

    elseif(OldNum > NumSources)
       % shorter, just trim
       for i = 1:length(links),
          hlist = eval(sprintf('handles.listbox_source_%s',links{i}));
          OldCstr = get(hlist,'String'); % old string array
          set(hlist,'val',1,'string',OldCstr(1:NumSources));
       end

    end

    % --------------- START OF LINKED LISTBOXES --------------------------

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

    link_listbox_vals(h, eventdata, handles);

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

    link_listbox_vals(h, eventdata, handles);

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

    link_listbox_vals(h, eventdata, handles);

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

    link_listbox_vals(h, eventdata, handles);

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

    link_listbox_vals(h, eventdata, handles);

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

    link_listbox_vals(h, eventdata, handles);

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

    set_listbox_entry(handles.listbox_source_model,'Dipole');

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

    disp('Not implemented')
    set_listbox_entry(handles.listbox_source_model,'Dipole');

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

    set_listbox_entry(handles.listbox_source_waveform,'Hamming');

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

    set_listbox_entry(handles.listbox_source_waveform,'Hann');

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

    set_listbox_entry(handles.listbox_source_waveform,'Boxcar');

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

    set_listbox_entry(handles.listbox_source_waveform,'Triangle');

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

    set_listbox_entry(handles.listbox_source_waveform,'Sinusoid');

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

    set_listbox_entry(handles.listbox_source_waveform,'Custom');

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

    Cstr = get(handles.listbox_source_location,'string');
    val = get(handles.listbox_source_location,'val');
    str = Cstr{val}; % current entry in the listbox

    % strip out the brackets, if any
    str = strrep(str,'[','');
    str = strrep(str,']','');
    str = strrep(str,' mm',''); % strip the units in the display

    % expand the orientation display
    prompt={'Location in the x, y, z coordinates'};
    def = {str};
    dlgTitle = 'Source Location';
    lineNo = 1;
    answer = inputdlg(prompt,dlgTitle,lineNo,def);

    if(~isempty(answer))
       % set the edit box
       location = str2num(answer{1}); % convert to array

       if(~isempty(location)),
          % valid read of the answer box
          % build string
          str = ['[',str_repeater('%.1f',' ',location),'] mm'];

          Cstr{val} = str; % replace in array

          % replace array
          set(handles.listbox_source_location,'string',Cstr);

       end

       % once the location is edited, update the orientation
       uimenu_edit_orientation_Callback(...
          handles.listbox_source_orientation, eventdata, handles, varargin)

    end % else do nothing

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

    Cstr = get(handles.listbox_source_location,'string');
    val = get(handles.listbox_source_location,'val');
    str = Cstr{val}; % current entry in the listbox

    location = [randn(1,2)*20 rand(1)*100];

    str = ['[',str_repeater('%.1f',' ',location),'] mm'];

    Cstr{val} = str; % replace in array

    % replace array
    set(handles.listbox_source_location,'string',Cstr);

    % now treat as new edited entry
    uimenu_edit_location_Callback(handles.listbox_source_location, eventdata, handles, varargin)

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

    Cstr = get(handles.listbox_source_orientation,'string');
    val = get(handles.listbox_source_orientation,'val');
    str = Cstr{val}; % current entry in the listbox

    % strip out the brackets, if any
    str = strrep(str,'[','');
    str = strrep(str,']','');

    % expand the orientation display
    prompt={'Orientation in the x, y, z directions'};
    def = {str};
    dlgTitle = 'Source Orientation, answer normalized automatically';
    lineNo = 1;
    answer = inputdlg(prompt,dlgTitle,lineNo,def);

    if(~isempty(answer))
       % set the edit box
       orient = str2num(answer{1}); % convert to array

       if(~isempty(orient)),
          % valid read of the answer box
          orient = orient(:);
          Tangential = get(handles.uimenu_ForceTangential,'checked');
          % is Tangential checked on?
          if(strcmp(Tangential,'on')),
             % need location, project tangential to it
             LCstr = get(handles.listbox_source_location,'string');
             Lval = get(handles.listbox_source_location,'val');
             Lstr = LCstr{Lval}; % current entry in the listbox

             Lstr = strrep(Lstr,'mm',''); % remove units

             Location = str2num(Lstr);
             CENTER = get(handles.edit_head_center,'string');
             CENTER = strrep(CENTER,'[','');
             CENTER = strrep(CENTER,']','');
             Center = str2num(CENTER); % center
             Location = Location - Center; % adjust to head center

             orient = orient - Location'*(Location*orient)/(Location*Location');
          end

          orient = orient/norm(orient); % the normalized orientation

          % build string
          str = ['[',str_repeater('%.2f',' ',orient),']'];

          Cstr{val} = str; % replace in array

          % replace array
          set(handles.listbox_source_orientation,'string',Cstr);

       end
    end % else do nothing

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

    Cstr = get(handles.listbox_source_orientation,'string');
    val = get(handles.listbox_source_orientation,'val');
    str = Cstr{val}; % current entry in the listbox

    orient = randn(1,3);
    orient = orient/norm(orient);

    str = ['[',str_repeater('%.2f',' ',orient),']'];

    Cstr{val} = str; % replace in array

    % replace array
    set(handles.listbox_source_orientation,'string',Cstr);

    uimenu_edit_orientation_Callback(handles.listbox_source_orientation, eventdata, handles, varargin)

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

    % whether or not to force all orientations to be tangential
    Tangential = get(h,'checked');
    switch Tangential
    case 'on'
       set(h,'checked','off');
    case 'off'
       set(h,'checked','on');
    end

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

    Cstr = get(handles.listbox_source_amplitude,'string');
    val = get(handles.listbox_source_amplitude,'val');
    str = Cstr{val}; % current entry in the listbox

    str = strrep(str,' nA-m',''); % remove units

    % expand the orientation display
    prompt={'Maximum amplitude in nA-m'};
    def = {str};
    dlgTitle = 'Source Amplitude';
    lineNo = 1;
    answer = inputdlg(prompt,dlgTitle,lineNo,def);

    if(~isempty(answer))
       % set the edit box
       amp = str2num(answer{1}); % convert to array

       if(~isempty(amp)),
          % valid read of the answer box
          % build string
          str = sprintf('%.0f nA-m',amp);

          Cstr{val} = str; % replace in array

          % replace array
          set(handles.listbox_source_amplitude,'string',Cstr);

       end
    end % else do nothing

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

    Cstr = get(handles.listbox_source_delay,'string');
    val = get(handles.listbox_source_delay,'val');
    str = Cstr{val}; % current entry in the listbox

    % expand the orientation display
    prompt={'Number of samples delay'};
    def = {str};
    dlgTitle = 'Source Delay';
    lineNo = 1;
    answer = inputdlg(prompt,dlgTitle,lineNo,def);

    if(~isempty(answer))
       % set the edit box
       delay = str2num(answer{1}); % convert to array
       delay = round(delay);

       if(~isempty(delay)),
          % valid read of the answer box
          % build string
          str = sprintf('%.0f',delay);

          Cstr{val} = str; % replace in array

          % replace array
          set(handles.listbox_source_delay,'string',Cstr);

       end
    end % else do nothing

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

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

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

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

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

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

    bst_message_window('wrap','DRAFT: Help for setting the simulation orientation');

    % --------------- END OF LINKED LISTBOXES ----------------------------

    % --------------------------------------------------------------------
    function varargout = edit_data_root_name_Callback(h, eventdata, handles, varargin)
    % The file prefix name

    % --------------------------------------------------------------------
    function varargout = edit_STUDIES_Callback(h, eventdata, handles, varargin)
    % Inactive, for display purposes only. Use datamanager to change

    % --------------------------------------------------------------------
    function varargout = edit_data_folder_name_Callback(h, eventdata, handles, varargin)
    % Folder inside of studies to store

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

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

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

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

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

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

    % strings relate loosely to half and full coverage

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

    % strings relate loosely to magnetometer, axial gradi, planar grad

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

    % numeric in mm

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

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

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

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

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

    delete(gcbf)

    % -------------------- MAKE THE SIMULATED DATA -------------------------------
    function varargout = pushbutton_generate_Callback(h, eventdata, handles, varargin)

    fig = handles.figure_simulator; % handy shorthand

    % Global variables
    User = get_user_directory; % where are we?

    % GUI Variables
    % the folder name and prefix to the data names
    STUDIES = User.STUDIES; % root folder
    FOLDER = get(handles.edit_data_folder_name,'String'); % desired simulation folder
    PREFIX = get(handles.edit_data_root_name,'String'); % desired prefix name

    % which sensor modality was selected
    tempstr = get(handles.popup_data_modality,'String');
    MODALITY = tempstr{get(handles.popup_data_modality,'Val')};

    % spacing of sensors in mm -> m
    SENSOR_SPACING = str2num(get(handles.edit_sensor_spacing,'string'))/1000;

    % Sensor coverage
    SENSOR_COVERAGE = {'half','full'};
    SENSOR_COVERAGE = SENSOR_COVERAGE{get(handles.popup_sensor_coverage,'value')};

    % Sensor type, important if MEG
    SENSOR_TYPE = {'magnetometer','axial','planar'};
    SENSOR_TYPE = SENSOR_TYPE{get(handles.popup_sensor_type,'value')};

    % Sensor baseline in mm -> m
    BASELINE = str2num(get(handles.edit_sensor_baseline,'string'))/1000;

    MODEL = get(handles.listbox_source_model,'string');
    LOCATION = get(handles.listbox_source_location,'string');
    ORIENTATION = get(handles.listbox_source_orientation,'string');
    AMPLITUDE = get(handles.listbox_source_amplitude,'string');
    DELAY = get(handles.listbox_source_delay,'string');
    WAVEFORM = get(handles.listbox_source_waveform,'string');

    % strip units
    LOCATION = strrep(LOCATION,' mm','');
    AMPLITUDE = strrep(AMPLITUDE,' nA-m','');

    CENTER = vec(str2num(get(handles.edit_head_center,'string')))/1000;

    NUM_SAMPLES = str2num(get(handles.edit_number_samples,'string'));

    TimeSeries = getappdata(fig,'TimeSeries');

    % ----------------------- STUDY STRUCTURE --------------------------
    % The Study Structure
    % Build and load a brainstormstudy.mat

    % Information about the Study
    Study = struct('Name',[],'Session',[],'DateOfStudy',[],...
       'DateOfModification',[],'BrainStormSubject',[],'Subject',[]);
    Study.Name = 'Simulated Data';
    Study.Session = 'Simulated Session';
    Study.DateOfStudy = '01-Jan-1998';
    Study.DateOfModification = date;
    Study.BrainStormSubject = []; % the filename of the subject, handled below.
    Study.Subject = 'Simulated Subject';

    % what is the modality and therefore the SENSOR radius:
    switch MODALITY
    case 'MEG'
       SENSOR = str2num(get(handles.edit_sensor_radius,'string'))/1000;
    case 'EEG'
       SENSOR = str2num(get(handles.edit_scalp_radius,'string'));
    otherwise
       disp('unknown modality');
    end

    % --------------------- CHANNEL GENERATION ----------------------------
    % The Channel information

    % pre-allocate space
    [Channel(1:1000)] = deal(struct('Loc',[],'Orient',[],'Weight',[],'Type',[],...
       'Comment',[],'Name',[],'System',[]));

    % Initial sensor arrangement
    tempLoc = sensor_spacing(SENSOR,SENSOR_SPACING,SENSOR_COVERAGE);

    switch MODALITY
    case 'MEG'

       switch SENSOR_TYPE
       case 'magnetometer'
          % simple, keep the existing location
          NUM_CHANNELS = size(tempLoc,1);
          for i = 1:NUM_CHANNELS,
             Channel(i).Loc = tempLoc(i,:)';
             Channel(i).Orient = Channel(i).Loc/norm(Channel(i).Loc);
             Channel(i).Weight = [1];
             Channel(i).Type = 'MEG';
             Channel(i).Comment = sprintf('Simulated magnetometer #%03.0f',i);
             Channel(i).Name = sprintf('MEG %03.0f',i);
             Channel(i).System = 'ctf';
          end

       case 'axial'
          % create second sensor in radial direction
          [tempLoc,tempOrient] = sensor_axial(tempLoc,BASELINE);
          NUM_CHANNELS = size(tempLoc,1);
          for i = 1:NUM_CHANNELS,
             Channel(i).Loc = reshape(tempLoc(i,:),3,2);
             Channel(i).Orient = reshape(tempOrient(i,:),3,2);
             Channel(i).Weight = [1; -1];
             Channel(i).Type = 'MEG';
             Channel(i).Comment = sprintf('Simulated axial gradiometer #%03.0f',i);
             Channel(i).Name = sprintf('MEG %03.0f',i);
             Channel(i).System = 'ctf';
          end

       case 'planar'
          % create two planar sensors per location
          [tempLoc,tempOrient] = sensor_planar(tempLoc,BASELINE);
          NUM_CHANNELS = size(tempLoc,1);
          for i = 1:NUM_CHANNELS,
             Channel(i).Loc = reshape(tempLoc(i,:),3,2);
             Channel(i).Orient = reshape(tempOrient(i,:),3,2);
             Channel(i).Weight = [1; -1];
             Channel(i).Type = 'MEG';
             Channel(i).Comment = sprintf('Simulated planar gradiometer #%03.0f',i);
             Channel(i).Name = sprintf('MEG %03.0f',i);
             Channel(i).System = 'ctf';
          end

       case 'triaxial'
          [tempLocp,tempOrient] = sensor_planar(tempLoc,BASELINE);
          NUM_MAG = size(tempLoc,1);
          NUM_PLANE = size(tempLocp,1);

          NUM_CHANNELS = NUM_MAG + NUM_PLANE;

          % first the magnetometers
          for i = 1:NUM_MAG,
             Channel(i).Loc = tempLoc(i,:)';
             Channel(i).Orient = Channel(i).Loc/norm(Channel(i).Loc);
             Channel(i).Weight = [1];
             Channel(i).Type = 'MEG';
             Channel(i).Comment = sprintf('Simulated magnetometer #%03.0f',i);
             Channel(i).Name = sprintf('MEG %03.0f',i);
             Channel(i).System = 'ctf';
          end

          % then the gradiometers
          for i = 1:NUM_PLANE,
             Channel(i + NUM_MAG).Loc = reshape(tempLocp(i,:),3,2);
             Channel(i + NUM_MAG).Orient = reshape(tempOrient(i,:),3,2);
             Channel(i + NUM_MAG).Weight = [1; -1];
             Channel(i + NUM_MAG).Type = 'MEG';
             Channel(i + NUM_MAG).Comment = sprintf('Simulated planar gradiometer #%03.0f',i);
             Channel(i + NUM_MAG).Name = sprintf('MEG %03.0f',i);
             Channel(i + NUM_MAG).System = 'ctf';
          end

       end

    case 'EEG'
       % not yet

    end

    Channel = Channel(1:NUM_CHANNELS); % trim allocation

    % Move all channels to be spherical about the head center
    for i = 1:NUM_CHANNELS,
       % Move the channel from sphere to PCS
       Channel(i).Loc = Channel(i).Loc + repmat(CENTER,1,size(Channel(i).Loc,2));
    end

    [Param(1:NUM_CHANNELS)] = struct('Center',CENTER);

    % ----------------------- DATA GENERATION ------------------------

    Data = struct('F',[],'Time',[],'ChannelFlag',[],'NoiseCov',[],'SourceCov',[],...
       'Projector',[],'Comment',[]);

    Location = str2num(char({'[', LOCATION{:} ']'}))'/1000; % per column
    % Location is already in the PCs

    Orientation = str2num(char({'[', ORIENTATION{:} ']'}))'; % per column

    G = os_meg(Location,Channel,Param,-1);
    A = G*blk_diag(Orientation,1); % each source gets a column
    S = zeros(NUM_SAMPLES,size(A,2)); % one time series per source

    for i = 1:size(S,2), % for each source
       amp = str2num(AMPLITUDE{i});
       delay = str2num(DELAY{i});
       wavlen = NUM_SAMPLES-delay; % number of samples to generate

       switch WAVEFORM{i}
       case 'Hamming'
          waveform = hamming(wavlen);
       case 'Hann'
          waveform = hann(wavlen);
       case 'Boxcar'
          waveform = ones(wavlen,1);
       case 'Triangle'
          waveform = triang(wavlen);
       case 'Sinusoid'
          % start and return to zero
          waveform = sin(2*pi*[0:(wavlen-1)]'/(wavlen-1));
       case 'Custom'
          waveform = TimeSeries(:,i)*1e9; % nA-m units
       otherwise
          error(sprintf('Problem waveform type: %s',WAVEFORM{i}));
       end

       waveform = waveform*amp;
       S(:,i) = [zeros(delay,1);waveform];

    end

    Data.F = A*S';
    % Data.F = Data.F * (1e-9 * 1e15); % to convert nA-m to A-m, then units to fT.
    Data.F = Data.F * (1e-9); % to convert nA-m to A-m, leave  units in T.

    % -------------------- NOISE GENERATION ----------------------------
    % now add the noise

    NoiseVal = get(handles.popup_noise_generator,'val');
    NoisePCT = str2num(get(handles.edit_noise_variance,'string'))/100;
    if(isempty(NoisePCT)),
       disp('Noise value string corrupted, edit');
       bst_message_window('append','Noise value string corrupted, edit');
       NoisePCT = 0;
    end
    VarSig = sum(Data.F(:).^2); % variance of the data

    switch NoiseVal
    case 1
       % noiseless, do nothing
       FNoise = zeros(size(Data.F));
    case 2
       % gaussian
       FNoise = randn(size(Data.F));
    case 3
       % uniform
       FNoise = rand(size(Data.F));
    otherwise
       % unknown
       error('unknown noise val added to popup, edit m-file');
    end

    VarNoise = sum(FNoise(:).^2);
    if(VarNoise), % non-zero case
       FNoise = FNoise*sqrt(VarSig/VarNoise*NoisePCT/(1-NoisePCT));
    end
    % Noise is now NoisePCT Variance not explained

    ChannelStd = std(FNoise'); % standard dev per channel
    disp(sprintf('Std. Dev per channel: %s',engstr(mean(ChannelStd))));
    Data.F = Data.F + FNoise;

    % ------------------- FINAL CLEANUP AND WRITING -----------------

    Data.Time = ([1:size(S,1)]-6) * 2/1000; % 2 ms sampling, fake pre-stim

    disp('True Locations (mm):')
    disp(Location*1000)
    disp('True Orientations: ')
    disp(Orientation)

    Data.ChannelFlag = ones(1,length(Channel)); % all channels good
    Data.NoiseCov = []; % unused for now
    Data.SourceCov = []; % unused for now
    Data.Projector = []; % unused for now
    Data.Comment = 'Simulated Data';
    Data.Device = 'Ctf_Axial';  % simulated

    % So now all structures are complete and residing in ram. Need to write out
    %  to the appropriate files.
    % Recall that PREFIX and PREFIX_STUDY were defined above.

    Users = get_user_directory; % where is the base storage area

    % now the study data
    cd(STUDIES);
    if(~exist(FOLDER,'dir')),
       % CBB handle status errors
       [status, message] = mkdir(FOLDER);
    end
    cd(FOLDER);

    % Need a unique name
    % Remote possibility of creating a duplicate name, which would overwrite old data
    clk = clock;
    SUF = sprintf('%02.0f%04.0f',clk(5),round(clk(6)*100)); % suffix of minutes, seconds, hundreds
    DataFileName = [PREFIX 'data_' SUF];
    % DataSimResults = [DataFileName '_sim_results'];
    % New convention, replace data with results in filename
    DataSimResults = [PREFIX 'results_' SUF];

    if(~exist([PREFIX 'brainstormstudy.mat'],'file')),
       save_fieldnames(Study,[PREFIX 'brainstormstudy']);
    end

    % because we kept Channel a single array, requires special handling
    save([PREFIX 'channel'],'Channel');
    % load as two-step, Channel = load('channel.mat'); Channel = Channel.Channel;

    save_fieldnames(Data,DataFileName); % the first of several possible data sets.

    bst_message_window('append',sprintf('Current directory: %s',pwd));
    bst_message_window('append',sprintf('Wrote %s',DataFileName));

    % now write out the answers to a simulated results file

    SourceLoc = cell(1,size(Location,2));
    SourceOrientation = cell(size(SourceLoc));
    IndepTopo = A;
    TimeSeries = S;
    Fsynth = Data.F;
    Time = Data.Time;
    Comment = 'Simulated data';
    Center = CENTER;

    for i= 1:size(Location,2),
       SourceLoc{i} = Location(:,i);
       SourceOrientation{i} = Orientation(:,i);
    end

    save(DataSimResults,'SourceLoc','SourceOrientation','Center',...
       'IndepTopo','TimeSeries','Fsynth','Time','Comment');

    bst_message_window('append',sprintf('Wrote %s',DataSimResults));

    bst_message_window('Done');

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