├── batch_group_GALA_data_sources.m ├── batch_group_GALA_write.m ├── bf_copy.m ├── bf_data.m ├── bf_example_samgam_mv.m ├── bf_features.m ├── bf_features_contcov.m ├── bf_features_cov.m ├── bf_features_cov_bysamples.m ├── bf_features_csd.m ├── bf_features_identity.m ├── bf_features_regmulticov.m ├── bf_features_tdcov.m ├── bf_features_vbfa.m ├── bf_group.m ├── bf_group_GALA.m ├── bf_group_batch.m ├── bf_group_functionalROI.m ├── bf_inverse.m ├── bf_inverse_champagne.m ├── bf_inverse_deflect.m ├── bf_inverse_dics.m ├── bf_inverse_ebb.m ├── bf_inverse_eloreta.m ├── bf_inverse_lcmv.m ├── bf_inverse_lcmv_multicov.m ├── bf_inverse_minimumnorm.m ├── bf_inverse_nutmeg.m ├── bf_load.m ├── bf_output.m ├── bf_output_PLI.m ├── bf_output_image_cfGLM.m ├── bf_output_image_dics.m ├── bf_output_image_filtcorr.m ├── bf_output_image_gain.m ├── bf_output_image_kurtosis.m ├── bf_output_image_mv.m ├── bf_output_image_pac.m ├── bf_output_image_powcorr.m ├── bf_output_image_power.m ├── bf_output_image_sensitivity.m ├── bf_output_montage.m ├── bf_output_sourcedata_robust.m ├── bf_pipeline_Champagne.m ├── bf_pipeline_DICS_coherence.m ├── bf_pipeline_DICS_power.m ├── bf_pipeline_DeFlect.m ├── bf_pipeline_GALA.m ├── bf_pipeline_LCMV_all_mesh_sources.m ├── bf_pipeline_LCMV_imaging.m ├── bf_pipeline_LCMV_imaging_for_Neuromag.m ├── bf_pipeline_LCMV_source_extraction.m ├── bf_pipeline_MVAR_activation_vs_baseline.m ├── bf_pipeline_MVAR_two_conditions.m ├── bf_pipeline_Minimum_Norm.m ├── bf_pipeline_eLORETA.m ├── bf_regularise_mantrunc.m ├── bf_regularise_manual.m ├── bf_regularise_minkatrunc.m ├── bf_regularise_roi.m ├── bf_regularise_tichonov_rankdef.m ├── bf_save.m ├── bf_save_path.m ├── bf_slides.pdf ├── bf_sources.m ├── bf_sources_grid.m ├── bf_sources_grid_phantom.m ├── bf_sources_mesh.m ├── bf_sources_mni_coords.m ├── bf_sources_voi.m ├── bf_std_fields.m ├── bf_write.m ├── bf_write_gifti.m ├── bf_write_nifti.m ├── bf_write_spmeeg.m ├── private ├── DeFleCT.m ├── GALA_calculate_distance.m ├── GALA_clustering.m ├── GALA_find_localmin.m ├── GALA_invert.m ├── MNestimator.m ├── Tikhonov_rank_def.m ├── bf_fuse_lf.m ├── bf_reml_sc.m ├── champagne_aug2015.m ├── ft_inverse_beamformer_dics.m ├── gen_bf_ttest.m ├── get_components.m ├── get_data_features.m ├── mkfilt_eloreta_v2.m ├── nut_dSPM.m ├── nut_sLORETA.m ├── nut_swLORETA.m ├── output_image_mv_cva.m ├── pinv_plus.m ├── spm_pca_order.m └── vbfa_aug2015.m ├── spm_beamforming.m └── tbx_cfg_bf.m /batch_group_GALA_data_sources.m: -------------------------------------------------------------------------------- 1 | %----------------------------------------------------------------------- 2 | % Job saved on 11-Dec-2015 13:01:41 by cfg_util (rev $Rev: 6460 $) 3 | % spm SPM - SPM12 (12.1) 4 | % cfg_basicio BasicIO - Unknown 5 | %----------------------------------------------------------------------- 6 | matlabbatch{1}.spm.tools.beamforming.data.dir = ''; 7 | matlabbatch{1}.spm.tools.beamforming.data.D = ''; 8 | matlabbatch{1}.spm.tools.beamforming.data.val = 1; 9 | matlabbatch{1}.spm.tools.beamforming.data.gradsource = 'inv'; 10 | matlabbatch{1}.spm.tools.beamforming.data.space = 'MNI-aligned'; 11 | matlabbatch{1}.spm.tools.beamforming.data.overwrite = 1; 12 | matlabbatch{2}.spm.tools.beamforming.sources.BF(1) = cfg_dep('Prepare data: BF.mat file', substruct('.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 13 | matlabbatch{2}.spm.tools.beamforming.sources.reduce_rank = [2 3]; 14 | matlabbatch{2}.spm.tools.beamforming.sources.keep3d = 1; 15 | matlabbatch{2}.spm.tools.beamforming.sources.plugin.mesh.orient = 'original'; 16 | matlabbatch{2}.spm.tools.beamforming.sources.plugin.mesh.fdownsample = 1; 17 | matlabbatch{2}.spm.tools.beamforming.sources.plugin.mesh.symmetric = 'no'; 18 | matlabbatch{2}.spm.tools.beamforming.sources.plugin.mesh.flip = false; 19 | matlabbatch{2}.spm.tools.beamforming.sources.visualise = 1; 20 | -------------------------------------------------------------------------------- /batch_group_GALA_write.m: -------------------------------------------------------------------------------- 1 | %----------------------------------------------------------------------- 2 | % Job saved on 11-Dec-2015 14:59:04 by cfg_util (rev $Rev: 6460 $) 3 | % spm SPM - SPM12 (12.1) 4 | % cfg_basicio BasicIO - Unknown 5 | %----------------------------------------------------------------------- 6 | matlabbatch{1}.spm.tools.beamforming.write.BF = ''; 7 | matlabbatch{1}.spm.tools.beamforming.write.plugin.spmeeg.mode = 'write'; 8 | matlabbatch{1}.spm.tools.beamforming.write.plugin.spmeeg.modality = 'MEGPLANAR'; 9 | matlabbatch{1}.spm.tools.beamforming.write.plugin.spmeeg.addchannels.none = 0; 10 | matlabbatch{1}.spm.tools.beamforming.write.plugin.spmeeg.prefix = 'G'; 11 | -------------------------------------------------------------------------------- /bf_copy.m: -------------------------------------------------------------------------------- 1 | function out = bf_copy 2 | % Sets up a new analysis by copying an existing one 3 | % Copyright (C) 2012 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | % dir Directory 9 | % --------------------------------------------------------------------- 10 | 11 | BF = cfg_files; 12 | BF.tag = 'BF'; 13 | BF.name = 'BF.mat file'; 14 | BF.filter = '^BF.mat$'; 15 | BF.num = [1 1]; 16 | BF.help = {'Select BF.mat file.'}; 17 | 18 | dir = cfg_files; 19 | dir.tag = 'dir'; 20 | dir.name = 'Output directory'; 21 | dir.help = {'Select a directory where the copied BF.mat file will be written.'}; 22 | dir.filter = 'dir'; 23 | dir.ufilter = '.*'; 24 | dir.num = [1 1]; 25 | 26 | steps = cfg_menu; 27 | steps.tag = 'steps'; 28 | steps.name = 'Steps to copy'; 29 | steps.help = {'Select ''all'' or the last step to copy'}; 30 | steps.labels = ['all'; bf_std_fields]; 31 | steps.values = ['all'; bf_std_fields]; 32 | steps.val = {'all'}; 33 | 34 | out = cfg_exbranch; 35 | out.tag = 'copy'; 36 | out.name = 'Copy analysis'; 37 | out.val = {BF, dir, steps}; 38 | out.help = {'Make a copy of existing anallysis'}; 39 | out.prog = @bf_copy_run; 40 | out.vout = @bf_copy_vout; 41 | out.modality = {'EEG'}; 42 | end 43 | 44 | function out = bf_copy_run(job) 45 | 46 | BF = job.BF{1}; 47 | outdir = job.dir{1}; 48 | 49 | cd(outdir); 50 | 51 | %-Ask about overwriting files from previous analyses 52 | %-------------------------------------------------------------------------- 53 | if exist(fullfile(pwd,'BF.mat'),'file') 54 | str = {'Current directory contains existing BF file:',... 55 | 'Continuing will overwrite existing file!'}; 56 | if spm_input(str,1,'bd','stop|continue',[1,0],1,mfilename); 57 | fprintf('%-40s: %30s\n\n',... 58 | 'Abort... (existing BF file)',spm('time')); 59 | out = []; return 60 | end 61 | end 62 | 63 | if isequal(job.steps, 'all') 64 | [r, msg] = copyfile(BF, ... 65 | fullfile(outdir, 'BF.mat'), 'f'); 66 | if ~r 67 | error(msg); 68 | end 69 | else 70 | fields = bf_std_fields; 71 | ind = strmatch(job.steps, fields); 72 | BF = bf_load(BF, fields(1:ind)); 73 | bf_save(BF, 1); 74 | end 75 | 76 | out.BF{1} = fullfile(outdir, 'BF.mat'); 77 | 78 | end 79 | 80 | function dep = bf_copy_vout(job) 81 | % Output is always in field "BF", no matter how job is structured 82 | dep = cfg_dep; 83 | dep.sname = 'BF.mat file'; 84 | % reference field "B" from output 85 | dep.src_output = substruct('.','BF'); 86 | % this can be entered into any evaluated input 87 | dep.tgt_spec = cfg_findspec({{'filter','mat','strtype','e'}}); 88 | end 89 | -------------------------------------------------------------------------------- /bf_data.m: -------------------------------------------------------------------------------- 1 | function out = bf_data 2 | % Prepares the data and initialises the beamforming pipeline 3 | % Copyright (C) 2012 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | % dir Directory 9 | % --------------------------------------------------------------------- 10 | dir = cfg_files; 11 | dir.tag = 'dir'; 12 | dir.name = 'Directory'; 13 | dir.help = {'Select a directory where the B.mat file containing the beamforming data will be written.'}; 14 | dir.filter = 'dir'; 15 | dir.ufilter = '.*'; 16 | dir.num = [1 1]; 17 | 18 | D = cfg_files; 19 | D.tag = 'D'; 20 | D.name = 'M/EEG dataset'; 21 | D.filter = 'mat'; 22 | D.num = [1 1]; 23 | D.help = {'Select the M/EEG mat file.'}; 24 | 25 | val = cfg_entry; 26 | val.tag = 'val'; 27 | val.name = 'Inversion index'; 28 | val.strtype = 'n'; 29 | val.help = {'Index of the cell in D.inv where the forward model is stored.'}; 30 | val.val = {1}; 31 | 32 | gradsource = cfg_menu; 33 | gradsource.tag = 'gradsource'; 34 | gradsource.name = 'Where to get MEG sensors'; 35 | gradsource.help = {'Taking sensors from D.sensors makes it possible to',... 36 | 'use the same head model and coregistration with multiple datasets.',... 37 | 'This relies on the assumption that the sensors are in head coordinates',... 38 | 'and the fiducals are at the same locations'}; 39 | gradsource.labels = {'D.inv', 'D.sensors'}; 40 | gradsource.values = {'inv', 'sensors'}; 41 | gradsource.val = {'inv'}; 42 | 43 | space = cfg_menu; 44 | space.tag = 'space'; 45 | space.name = 'Coordinate system to work in'; 46 | space.help = {'Select the coordinate system for the forward model'}; 47 | space.labels = {'MNI-aligned', 'Head', 'Native'}; 48 | space.values = {'MNI-aligned', 'Head', 'Native'}; 49 | space.val = {'MNI-aligned'}; 50 | 51 | overwrite = cfg_menu; 52 | overwrite.tag = 'overwrite'; 53 | overwrite.name = 'Overwrite BF.mat if exists'; 54 | overwrite.help = {'Choose whether to overwrite the existing BF.mat file'}; 55 | overwrite.labels = {'Yes', 'No'}; 56 | overwrite.values = {1, 0}; 57 | overwrite.val = {0}; 58 | 59 | out = cfg_exbranch; 60 | out.tag = 'data'; 61 | out.name = 'Prepare data'; 62 | out.val = {dir, D, val, gradsource, space, overwrite}; 63 | out.help = {'Prepare the input for beamforming'}; 64 | out.prog = @bf_data_run; 65 | out.vout = @bf_data_vout; 66 | out.modality = {'EEG'}; 67 | end 68 | 69 | function out = bf_data_run(job) 70 | 71 | outdir = job.dir{1}; 72 | val = job.val; 73 | space = job.space; 74 | gradsource = job.gradsource; 75 | D = spm_eeg_load(job.D{1}); 76 | 77 | if ~isfield(D, 'inv') 78 | error('Please run head model specification.'); 79 | end 80 | 81 | if numel(D.inv) < val 82 | error('Invalid inversion index'); 83 | end 84 | 85 | % cd(outdir); 86 | 87 | %-Ask about overwriting files from previous analyses 88 | %-------------------------------------------------------------------------- 89 | if exist(fullfile(outdir, 'BF.mat'),'file') && ~job.overwrite 90 | str = {'Output directory contains existing BF file:',... 91 | 'Continuing will overwrite existing file!'}; 92 | if spm_input(str,1,'bd','stop|continue',[1,0],1,mfilename); 93 | fprintf('%-40s: %30s\n\n',... 94 | 'Abort... (existing BF file)',spm('time')); 95 | out = []; return 96 | end 97 | end 98 | 99 | BF = []; 100 | 101 | BF.data = spm_eeg_inv_get_vol_sens(D, val, space, gradsource); 102 | 103 | BF.data.D = D; 104 | BF.data.mesh = D.inv{val}.mesh; 105 | 106 | try 107 | delete(fullfile(outdir, 'BF.mat')); 108 | end 109 | 110 | bf_save_path(BF,fullfile(outdir, 'BF.mat')); 111 | 112 | out.BF{1} = fullfile(outdir, 'BF.mat'); 113 | 114 | end 115 | 116 | function dep = bf_data_vout(job) 117 | % Output is always in field "BF", no matter how job is structured 118 | dep = cfg_dep; 119 | dep.sname = 'BF.mat file'; 120 | % reference field "B" from output 121 | dep.src_output = substruct('.','BF'); 122 | % this can be entered into any evaluated input 123 | dep.tgt_spec = cfg_findspec({{'filter','mat','strtype','e'}}); 124 | end 125 | -------------------------------------------------------------------------------- /bf_example_samgam_mv.m: -------------------------------------------------------------------------------- 1 | %----------------------------------------------------------------------- 2 | % Job configuration created by cfg_util (rev $Rev$) 3 | %----------------------------------------------------------------------- 4 | matlabbatch{1}.spm.meeg.source.headmodel.D = {'C:\Users\gbarnes\Documents\simdata_peakomatic\simdata_1dip_5mm_0pcamp2_amp10\simdata.mat'}; 5 | matlabbatch{1}.spm.meeg.source.headmodel.val = 1; 6 | matlabbatch{1}.spm.meeg.source.headmodel.comment = ''; 7 | matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshes.template = 1; 8 | matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshres = 2; 9 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).fidname = 'nas'; 10 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).specification.select = 'nas'; 11 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).fidname = 'lpa'; 12 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).specification.select = 'FIL_CTF_L'; 13 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).fidname = 'rpa'; 14 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).specification.select = 'FIL_CTF_R'; 15 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.useheadshape = 0; 16 | matlabbatch{1}.spm.meeg.source.headmodel.forward.eeg = 'EEG BEM'; 17 | matlabbatch{1}.spm.meeg.source.headmodel.forward.meg = 'Single Shell'; 18 | matlabbatch{2}.spm.tools.beamforming.data.dir = {'C:\Users\gbarnes\Documents\batchtest\'}; 19 | matlabbatch{2}.spm.tools.beamforming.data.D(1) = cfg_dep('M/EEG head model specification: M/EEG dataset(s) with a forward model', substruct('.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','D')); 20 | matlabbatch{2}.spm.tools.beamforming.data.val = 1; 21 | matlabbatch{2}.spm.tools.beamforming.data.space = 'MNI-aligned'; 22 | matlabbatch{3}.spm.tools.beamforming.sources.BF(1) = cfg_dep('Prepare data: BF.mat file', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 23 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.grid.resolution = 5; 24 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.grid.space = 'MNI template'; 25 | matlabbatch{4}.spm.tools.beamforming.features.BF(1) = cfg_dep('Define sources: BF.mat file', substruct('.','val', '{}',{3}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 26 | matlabbatch{4}.spm.tools.beamforming.features.whatconditions.all = 1; 27 | matlabbatch{4}.spm.tools.beamforming.features.woi = [-Inf Inf]; 28 | matlabbatch{4}.spm.tools.beamforming.features.foi = [0 0]; 29 | matlabbatch{4}.spm.tools.beamforming.features.plugin.regcov.lambda = 0; 30 | matlabbatch{5}.spm.tools.beamforming.inverse.BF(1) = cfg_dep('Covariance features: BF.mat file', substruct('.','val', '{}',{4}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 31 | matlabbatch{5}.spm.tools.beamforming.inverse.plugin.lcmv = struct([]); 32 | matlabbatch{6}.spm.tools.beamforming.output.BF(1) = cfg_dep('Inverse solution: BF.mat file', substruct('.','val', '{}',{5}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 33 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.whatconditions.all = 1; 34 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.woi = [-Inf Inf]; 35 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.contrast = 1; 36 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.result = 'singleimage'; 37 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.modality = 'MEG'; 38 | matlabbatch{7}.spm.tools.beamforming.write.BF(1) = cfg_dep('Output: BF.mat file', substruct('.','val', '{}',{6}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 39 | matlabbatch{7}.spm.tools.beamforming.write.plugin.nifti.normalise = 'separate'; 40 | matlabbatch{7}.spm.tools.beamforming.write.plugin.nifti.space = 'mni'; 41 | -------------------------------------------------------------------------------- /bf_features_contcov.m: -------------------------------------------------------------------------------- 1 | function res = bf_features_contcov(BF, S) 2 | % Robust covariance for continuous data 3 | % Copyright (C) 2013 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0 10 | contcov = cfg_branch; 11 | contcov.tag = 'contcov'; 12 | contcov.name = 'Robust covariance'; 13 | contcov.val = {}; 14 | contcov.help = {'Robust covariance for continuous data'}; 15 | 16 | res = contcov; 17 | 18 | return 19 | elseif nargin < 2 20 | error('Two input arguments are required'); 21 | end 22 | 23 | D = BF.data.D; 24 | 25 | nchans = length(S.channels); 26 | 27 | samples = S.samples{1}; 28 | 29 | bad = badsamples(D, S.channels, samples, 1); 30 | 31 | % Combine fixed 1 sec segments with change points of bad channel number 32 | % and prune to avoid too many short segments 33 | fixedseg = 1:round(D.fsample):D.nsamples; 34 | 35 | chngpnt = [1 find(any(diff(bad, [], 2)))+1]; 36 | 37 | prunetable = abs(repmat(fixedseg, length(chngpnt), 1)-repmat(chngpnt', 1, length(fixedseg))); 38 | fixedseg(any(prunetable 100, Ibar = floor(linspace(1, nsegments,100)); 47 | else Ibar = 1:nsegments; end 48 | 49 | YY = zeros(nchans); 50 | 51 | N = YY; 52 | 53 | id = zeros(1, nsegments); 54 | 55 | for i = 1:nsegments 56 | if i1 68 | Y = detrend(Y', 'constant')'; 69 | end 70 | 71 | YY(goodind, goodind) = YY(goodind, goodind)+(Y*Y'); 72 | N(goodind, goodind) = N(goodind, goodind)+size(Y, 2); 73 | 74 | id(i) = spm_data_id(S.channels(goodind)); 75 | if ismember(i, Ibar) 76 | spm_progress_bar('Set', i); drawnow; 77 | end 78 | end 79 | 80 | spm_progress_bar('Clear'); 81 | 82 | C = YY./N; 83 | 84 | features.C = C; 85 | features.N = N; 86 | 87 | res = features; -------------------------------------------------------------------------------- /bf_features_cov.m: -------------------------------------------------------------------------------- 1 | function res = bf_features_cov(BF, S) 2 | % Simple band limited covariance computation 3 | % Copyright (C) 2012 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Gareth Barnes 6 | % $Id$ 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0 10 | foi = cfg_entry; 11 | foi.tag = 'foi'; 12 | foi.name = 'Frequency bands of interest'; 13 | foi.strtype = 'r'; 14 | foi.num = [Inf 2]; 15 | foi.val = {[0 Inf]}; 16 | foi.help = {'Frequency windows within which to compute covariance over (sec)'}; 17 | 18 | taper = cfg_menu; 19 | taper.tag = 'taper'; 20 | taper.name = 'Windowing'; 21 | taper.help = {'Select a window for pre-multiplying the data'}; 22 | taper.labels = {'Hanning', 'None'}; 23 | taper.values = {'hanning', 'none'}; 24 | taper.val = {'hanning'}; 25 | 26 | cov = cfg_branch; 27 | cov.tag = 'cov'; 28 | cov.name = 'Band limited covariance'; 29 | cov.val = {foi, taper}; 30 | 31 | res = cov; 32 | 33 | return 34 | elseif nargin < 2 35 | error('Two input arguments are required'); 36 | end 37 | 38 | D = BF.data.D; 39 | 40 | 41 | ntrials = length(S.trials); 42 | nchans = length(S.channels); 43 | %% now identify frequency bands of interest 44 | 45 | nbands = size(S.foi,1); 46 | 47 | if length(unique(cellfun(@length, S.samples)))~=1, 48 | error('all windows must be of equal length'); 49 | end; 50 | 51 | nwoi = numel(S.samples); 52 | nsamples = length(S.samples{1}); %% use length of first window to set up DCT (as all windows fixed at same length) 53 | windowduration = nsamples/D.fsample; 54 | dctfreq = (0:nsamples-1)/2/windowduration; % DCT frequencies (Hz) 55 | dctT = spm_dctmtx(nsamples,nsamples); 56 | 57 | allfreqind=[]; 58 | 59 | for fband = 1:nbands, %% allows one to break up spectrum and ignore some frequencies 60 | 61 | freqrange = S.foi(fband,:); 62 | 63 | j = find( (dctfreq >= freqrange(1)) & (dctfreq<=freqrange(2))); 64 | 65 | allfreqind = sort(unique([allfreqind j])); 66 | 67 | end; % for fband=1:Nbands 68 | 69 | % Hanning operator (if requested) 70 | %---------------------------------------------------------------------- 71 | 72 | switch lower(S.taper) 73 | case 'hanning', 74 | W = repmat(spm_hanning(nsamples)',nchans,1); 75 | case 'none' 76 | W = ones(nchans,nsamples); 77 | end 78 | 79 | spm('Pointer', 'Watch');drawnow; 80 | spm_progress_bar('Init', ntrials, 'Computing covariance'); drawnow; 81 | if ntrials > 100, Ibar = floor(linspace(1, ntrials,100)); 82 | else Ibar = 1:ntrials; end 83 | 84 | YY = 0; 85 | Tband = dctT(:,allfreqind); % filter to this band 86 | for i = 1:ntrials 87 | for j = 1:nwoi 88 | Y = squeeze(D(S.channels, S.samples{j}, S.trials(i))); 89 | 90 | Y = detrend(Y', 'constant')'; 91 | 92 | Y = Y.*W; 93 | 94 | dctY = Y*Tband; %% frequency representation 95 | 96 | YY = YY+(dctY*dctY'); 97 | end 98 | if ismember(i, Ibar) 99 | spm_progress_bar('Set', i); drawnow; 100 | end 101 | end 102 | 103 | spm_progress_bar('Clear'); 104 | 105 | N = ntrials*nsamples*nwoi; 106 | 107 | C = YY./N; 108 | 109 | features.C = C; 110 | features.N = N; 111 | 112 | res = features; -------------------------------------------------------------------------------- /bf_features_cov_bysamples.m: -------------------------------------------------------------------------------- 1 | function res = bf_features_cov_bysamples(BF, S) 2 | % Simple covariance computation to handle variable width WOIs, 3 | % Requires S.samples as a [1 x samples x ntrials] matrix of logical indices 4 | % indicating which data points should be used in the cov estimation 5 | % 6 | % Mark Woolrich 2014 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0, 10 | cov_bysamples = cfg_const; 11 | cov_bysamples.tag = 'cov_bysamples'; 12 | cov_bysamples.name = 'Cov estimation with variable width WOIs'; 13 | cov_bysamples.val = {0}; 14 | 15 | res = cov_bysamples; 16 | 17 | return 18 | elseif nargin < 2 19 | error('Two input arguments are required'); 20 | end 21 | 22 | D = BF.data.D; 23 | 24 | YY = 0; 25 | ns = 0; 26 | 27 | ntrials = length(S.trials); 28 | 29 | spm('Pointer', 'Watch');drawnow; 30 | spm_progress_bar('Init', ntrials, 'Computing covariance'); drawnow; 31 | if ntrials > 100, Ibar = floor(linspace(1, ntrials,100)); 32 | else Ibar = 1:ntrials; end 33 | 34 | num_of_invalid_covs=0; 35 | 36 | for i = 1:ntrials, 37 | nsamps=sum(S.samples(1,:,S.trials(i))>0); 38 | 39 | if(nsamps>1) 40 | Y = D(S.channels, find(S.samples(1,:,S.trials(i))), S.trials(i)); 41 | Y = detrend(Y', 'constant'); 42 | YY = YY+(Y'*Y); 43 | ns = ns + nsamps - 1; 44 | else 45 | num_of_invalid_covs=num_of_invalid_covs+1; 46 | end; 47 | 48 | if ismember(i, Ibar), 49 | spm_progress_bar('Set', i); drawnow; 50 | end 51 | end 52 | 53 | spm_progress_bar('Clear'); 54 | 55 | if(ntrials-num_of_invalid_covs < 10), 56 | warning(['Only ' num2str(ntrials-num_of_invalid_covs) ' valid trial covariances']); 57 | end; 58 | 59 | C = YY/ns; 60 | 61 | features.C = C; 62 | features.N = ns; 63 | 64 | res = features; -------------------------------------------------------------------------------- /bf_features_csd.m: -------------------------------------------------------------------------------- 1 | function res = bf_features_csd(BF, S) 2 | % Compute cross-spectral density matrix for DICS 3 | % Copyright (C) 2013 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0 10 | 11 | foi = cfg_entry; 12 | foi.tag = 'foi'; 13 | foi.name = 'Frequency band of interest'; 14 | foi.strtype = 'r'; 15 | foi.num = [1 2]; 16 | foi.help = {'Frequency window within which to compute CSD over (Hz)'}; 17 | 18 | taper = cfg_menu; 19 | taper.tag = 'taper'; 20 | taper.name = 'Taper'; 21 | taper.help = {'Save taper as well as power'}; 22 | taper.labels = {'Hanning', 'Rectangular', 'DPSS', 'Sine'}; 23 | taper.values = {'hanning', 'rectwin', 'dpss', 'sine'}; 24 | taper.val = {'dpss'}; 25 | 26 | keepreal = cfg_menu; 27 | keepreal.tag = 'keepreal'; 28 | keepreal.name = 'Keep real'; 29 | keepreal.labels = {'Yes', 'No'}; 30 | keepreal.val = {0}; 31 | keepreal.values = {1, 0}; 32 | keepreal.help = {'Keep only the real part of the CSD'}; 33 | 34 | han = cfg_menu; 35 | han.tag = 'hanning'; 36 | han.name = 'Pre-multiply with Hanning'; 37 | han.labels = {'yes', 'no'}; 38 | han.values = {1, 0}; 39 | han.val = {1}; 40 | 41 | csd = cfg_branch; 42 | csd.tag = 'csd'; 43 | csd.name = 'Cross-spectral density'; 44 | csd.val = {foi, taper, keepreal, han}; 45 | 46 | res = csd; 47 | 48 | return 49 | elseif nargin < 2 50 | error('Two input arguments are required'); 51 | end 52 | 53 | D = BF.data.D; 54 | 55 | ntrials = length(S.trials); 56 | centerfreq = mean(S.foi); 57 | tapsmofrq = 0.5*(abs(diff(S.foi))); 58 | nwoi = numel(S.samples); 59 | 60 | Cf = 0; 61 | N = 1; 62 | spm('Pointer', 'Watch');drawnow; 63 | spm_progress_bar('Init', ntrials, 'Computing CSD'); drawnow; 64 | if ntrials > 100, Ibar = floor(linspace(1, ntrials,100)); 65 | else Ibar = 1:ntrials; end 66 | 67 | for i = 1:ntrials 68 | for j = 1:nwoi 69 | Y = squeeze(D(S.channels, S.samples{j}, S.trials(i))); 70 | 71 | if j == 1 72 | if S.hanning 73 | han = repmat(spm_hanning(size(Y, 2))', [size(Y, 1), 1, size(Y, 3)]); 74 | else 75 | han = 1; 76 | end 77 | end 78 | 79 | Y = Y.*han; 80 | 81 | [fourier, ntap] = ft_specest_mtmfft(Y, D.time(S.samples{j}), 'freqoi', centerfreq, ... 82 | 'tapsmofrq', tapsmofrq, 'taper', S.taper, 'verbose', 0); 83 | 84 | 85 | dat = transpose(fourier); 86 | Cf = Cf + (dat * ctranspose(dat))./ntap; 87 | N = N + ntap; 88 | end 89 | if ismember(i, Ibar) 90 | spm_progress_bar('Set', i); drawnow; 91 | end 92 | end 93 | 94 | spm_progress_bar('Clear'); 95 | 96 | Cf = Cf/(ntrials*nwoi); 97 | 98 | if S.keepreal 99 | % the filter is computed using only the leadfield and the inverse covariance or CSD matrix 100 | % therefore using the real-valued part of the CSD matrix here ensures a real-valued filter 101 | Cf = real(Cf); 102 | end 103 | 104 | features=[]; 105 | 106 | features.C = Cf; 107 | features.N = N; 108 | 109 | res = features; -------------------------------------------------------------------------------- /bf_features_identity.m: -------------------------------------------------------------------------------- 1 | function res = bf_features_identity(BF, S) 2 | % Returns identity matrix for cases when covariance is not necessary 3 | % Copyright (C) 2016 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0 10 | identity = cfg_branch; 11 | identity.tag = 'identity'; 12 | identity.name = 'Identity matrix'; 13 | identity.val = {}; 14 | identity.help = {'Returns identity matrix for cases when covariance is not necessary'}; 15 | 16 | res = identity; 17 | 18 | return 19 | elseif nargin < 2 20 | error('Two input arguments are required'); 21 | end 22 | 23 | features.C = eye(length(S.channels)); 24 | features.N = 1; 25 | 26 | res = features; -------------------------------------------------------------------------------- /bf_features_regmulticov.m: -------------------------------------------------------------------------------- 1 | function res = bf_features_regmulticov(BF, S) 2 | % Simple covariance computation with regularization 3 | % 4 | % Mark Woolrich 5 | 6 | %-------------------------------------------------------------------------- 7 | if nargin == 0 8 | regmulticov = cfg_const; 9 | regmulticov.tag = 'regmulticov'; 10 | regmulticov.name = 'Regularized multiple covariance'; 11 | regmulticov.val = {0}; 12 | 13 | res = regmulticov; 14 | 15 | return 16 | elseif nargin < 2 17 | error('Two input arguments are required'); 18 | end 19 | 20 | D = BF.data.D; 21 | 22 | ntrials = length(S.trials); 23 | 24 | classchanind = find(strcmp(D.chanlabels,'Class')); %MWW 25 | 26 | if ~isempty(classchanind) 27 | NK = max(squash(D(classchanind,:,:))); 28 | else 29 | NK = 1; 30 | end 31 | 32 | for k = 1:NK 33 | 34 | YY = 0; 35 | ns = 0; 36 | 37 | spm('Pointer', 'Watch');drawnow; 38 | spm_progress_bar('Init', ntrials, 'Computing covariance'); drawnow; 39 | if ntrials > 100, Ibar = floor(linspace(1, ntrials,100)); 40 | else Ibar = 1:ntrials; end 41 | 42 | num_of_invalid_covs=0; 43 | 44 | for i = 1:ntrials, 45 | if ~isempty(classchanind) 46 | sampleind = S.samples(D(classchanind, S.samples, S.trials(i)) == k); 47 | else 48 | sampleind = S.samples; 49 | end 50 | 51 | nsamps = length(sampleind); 52 | 53 | if(nsamps>1) 54 | Y = D(S.channels, sampleind, S.trials(i)); 55 | Y = detrend(Y', 'constant'); 56 | YY = YY+(Y'*Y); 57 | ns = ns + nsamps - 1; 58 | else 59 | num_of_invalid_covs=num_of_invalid_covs+1; 60 | end; 61 | 62 | if ismember(i, Ibar), 63 | spm_progress_bar('Set', i); drawnow; 64 | end 65 | end 66 | 67 | spm_progress_bar('Clear'); 68 | 69 | if(ntrials-num_of_invalid_covs < 10), 70 | warning(['Only ' num2str(ntrials-num_of_invalid_covs) ' valid trial covariances for class ' num2str(k)]); 71 | end; 72 | 73 | C = YY/ns; 74 | 75 | features.C{k} = C; 76 | features.N{k} = ns; 77 | 78 | end 79 | 80 | res = features; -------------------------------------------------------------------------------- /bf_features_vbfa.m: -------------------------------------------------------------------------------- 1 | function res = bf_features_vbfa(BF, S) 2 | % Variational Bayes Factor Analysis for computing noise covariance 3 | % Code contributed by Sri Nagarajan 4 | % Copyright (C) 2015 Wellcome Trust Centre for Neuroimaging 5 | 6 | % Vladimir Litvak 7 | % $Id$ 8 | 9 | %-------------------------------------------------------------------------- 10 | if nargin == 0 11 | nl = cfg_entry; 12 | nl.tag = 'nl'; 13 | nl.name = 'Factor dimensionality'; 14 | nl.strtype = 'n'; 15 | nl.num = [1 1]; 16 | nl.val = {5}; 17 | 18 | nem = cfg_entry; 19 | nem.tag = 'nem'; 20 | nem.name = 'Number of EM iterations'; 21 | nem.strtype = 'n'; 22 | nem.num = [1 1]; 23 | nem.val = {50}; 24 | 25 | vbfa = cfg_branch; 26 | vbfa.tag = 'vbfa'; 27 | vbfa.name = 'VB Factor Analysis'; 28 | vbfa.val = {nl, nem}; 29 | vbfa.help = {'This method uses code contributed by Sri Nagarajan',... 30 | 'It should be used for computing noise covariance for Champagne'}; 31 | 32 | res = vbfa; 33 | 34 | return 35 | elseif nargin < 2 36 | error('Two input arguments are required'); 37 | end 38 | 39 | D = BF.data.D; 40 | 41 | ntrials = length(S.trials); 42 | 43 | nwoi = numel(S.samples); 44 | nsamples = length(S.samples{1}); 45 | 46 | if nwoi ~= 2 47 | error('Baseline and activation windows must be specified'); 48 | end 49 | 50 | spm('Pointer', 'Watch');drawnow; 51 | spm_progress_bar('Init', ntrials, 'Reading data'); drawnow; 52 | if ntrials > 100, Ibar = floor(linspace(1, ntrials,100)); 53 | else Ibar = 1:ntrials; end 54 | 55 | NN = []; 56 | YY = []; 57 | for i = 1:ntrials 58 | for j = 1:nwoi 59 | Y = squeeze(D(S.channels, S.samples{j}, S.trials(i))); 60 | 61 | Y = detrend(Y', 'constant')'; 62 | 63 | if j == 1 64 | NN = [NN, Y]; 65 | else 66 | YY = [YY Y]; 67 | end 68 | end 69 | if ismember(i, Ibar) 70 | spm_progress_bar('Set', i); drawnow; 71 | end 72 | end 73 | 74 | spm_progress_bar('Clear'); 75 | 76 | N = ntrials*nsamples*nwoi; 77 | 78 | % In the champagne header it is advised to convert data to pT. 79 | YY = 1e3*YY; 80 | NN = 1e3*NN; 81 | 82 | Fgraph = spm_figure('GetWin', 'VBFA'); figure(Fgraph); clf 83 | 84 | C = vbfa_aug2015(NN,S.nl,S.nem,Fgraph); 85 | 86 | features.C = C; 87 | features.N = N; 88 | features.Y = YY; 89 | 90 | res = features; -------------------------------------------------------------------------------- /bf_group.m: -------------------------------------------------------------------------------- 1 | function out = bf_group 2 | % A module for applying a processing step to a group of subjects 3 | % Copyright (C) 2015 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | %-------------------------------------------------------------------------- 9 | % BF 10 | %-------------------------------------------------------------------------- 11 | BF = cfg_files; 12 | BF.tag = 'BF'; 13 | BF.name = 'BF.mat or M/EEG files'; 14 | BF.filter = '.*.mat$'; 15 | BF.num = [1 Inf]; 16 | BF.help = {'Select BF.mat file.'}; 17 | 18 | 19 | %-------------------------------------------------------------------------- 20 | % prefix 21 | %-------------------------------------------------------------------------- 22 | prefix = cfg_entry; 23 | prefix.tag = 'prefix'; 24 | prefix.name = 'Directory prefix'; 25 | prefix.help = {'Specify the string to be prepended to the output directory name',... 26 | 'This is only used for batches starting with the Data module.'}; 27 | prefix.strtype = 's'; 28 | prefix.num = [0 Inf]; 29 | prefix.val = {''}; 30 | 31 | 32 | %-------------------------------------------------------------------------- 33 | % plugin 34 | %-------------------------------------------------------------------------- 35 | plugin = cfg_choice; 36 | plugin.tag = 'plugin'; 37 | plugin.name = 'Group analysis '; 38 | 39 | group_funs = spm_select('List', fileparts(mfilename('fullpath')), '^bf_group_.*\.m$'); 40 | group_funs = cellstr(group_funs ); 41 | for i = 1:numel(group_funs) 42 | plugin.values{i} = feval(spm_file(group_funs{i},'basename')); 43 | end 44 | 45 | out = cfg_exbranch; 46 | out.tag = 'group'; 47 | out.name = 'Group analysis'; 48 | out.val = {BF, prefix, plugin}; 49 | out.help = {'Set up group analyses'}; 50 | out.prog = @bf_group_run; 51 | out.vout = @bf_group_vout; 52 | out.modality = {'EEG'}; 53 | end 54 | 55 | function out = bf_group_run(job) 56 | 57 | 58 | plugin_name = cell2mat(fieldnames(job.plugin)); 59 | 60 | BF = job.BF; 61 | S = job.plugin.(plugin_name); 62 | S.prefix = job.prefix; 63 | 64 | BF = feval(['bf_group_' plugin_name], BF, S); 65 | 66 | if ~isa(BF, 'cell') 67 | BF = {BF}; 68 | end 69 | 70 | out.BF = BF(:); 71 | 72 | end 73 | 74 | function dep = bf_group_vout(job) 75 | % Output is always in field "BF", no matter how job is structured 76 | dep = cfg_dep; 77 | dep.sname = 'BF.mat files'; 78 | % reference field "B" from output 79 | dep.src_output = substruct('.','BF'); 80 | % this can be entered into any evaluated input 81 | dep.tgt_spec = cfg_findspec({{'filter','mat','strtype','e'}}); 82 | end 83 | -------------------------------------------------------------------------------- /bf_group_GALA.m: -------------------------------------------------------------------------------- 1 | function res = bf_group_GALA(BF, S) 2 | % Computes Minimum Norm projectors 3 | % Copyright (C) 2013 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak, using the code from Matti Stenroos and Olaf Hauk 6 | % http://imaging.mrc-cbu.cam.ac.uk/meg/AnalyzingData/DeFleCT_SpatialFiltering_Tools 7 | % 8 | % Please cite: 9 | % Hauk O, Stenroos M. 10 | % A framework for the design of flexible cross-talk functions for spatial filtering of EEG/MEG data: DeFleCT. 11 | % Human Brain Mapping 2013 12 | % $Id$ 13 | 14 | %-------------------------------------------------------------------------- 15 | if nargin == 0 16 | iter = cfg_entry; 17 | iter.tag = 'iter'; 18 | iter.name = 'Number of iteration'; 19 | iter.strtype = 'r'; 20 | iter.num = [1 1]; 21 | iter.val = {3}; 22 | iter.help = {'Number of iteration'}; 23 | 24 | 25 | GALA = cfg_branch; 26 | GALA.tag = 'GALA'; 27 | GALA.name = 'GALA'; 28 | GALA.val = {iter}; 29 | GALA.help = {'bla bla bla'}; 30 | res = GALA; 31 | 32 | return 33 | elseif nargin < 2 34 | error('Two input arguments are required'); 35 | end 36 | 37 | S.modality = 'MEGPLANAR'; % temp 38 | 39 | Nl = length(BF); 40 | S.Nl = Nl; 41 | 42 | [J, St] = GALA_invert(BF,S); 43 | 44 | Nd = length(J)/Nl; 45 | res = cell(1, numel(BF)); 46 | for p=1:Nl 47 | BFp = load(BF{p}); 48 | % extract sunbject's J 49 | Jp = J(1+(p-1)*Nd:Nd+(p-1)*Nd,:); 50 | BFp.inverse.(S.modality).J = Jp; 51 | BFp.inverse.(S.modality).S = St; 52 | BFp.inverse.(S.modality).channels = BFp.sources.channels.MEG; % temp 53 | 54 | outdir = spm_file(BF{p}, 'fpath'); 55 | bf_save_path(BFp,fullfile(outdir, 'BF.mat')); 56 | res(p) = {fullfile(outdir, 'BF.mat')}; 57 | end 58 | 59 | end 60 | 61 | 62 | -------------------------------------------------------------------------------- /bf_group_batch.m: -------------------------------------------------------------------------------- 1 | function res = bf_group_batch(BF, S) 2 | % Run a DAiSS batch on a group of subjects 3 | % Copyright (C) 2015 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0 10 | batchfile = cfg_files; 11 | batchfile.tag = 'batchfile'; 12 | batchfile.name = 'Batch .mat or .m file'; 13 | batchfile.filter = '(.*.mat$)|(.*.m$)'; 14 | batchfile.num = [1 Inf]; 15 | batchfile.help = {'Select batch specification file.'}; 16 | 17 | batch = cfg_branch; 18 | batch.tag = 'batch'; 19 | batch.name = 'Batch'; 20 | batch.val = {batchfile}; 21 | 22 | res = batch; 23 | 24 | return 25 | elseif nargin < 2 26 | error('Two input arguments are required'); 27 | end 28 | 29 | batchfile = char(S.batchfile); 30 | 31 | if isequal(spm_file(batchfile, 'ext'), 'm') 32 | cdir = pwd; 33 | if ~isempty(spm_file(batchfile, 'path')) 34 | try 35 | cd(spm_file(batchfile, 'path')); 36 | catch 37 | % This is to allow the use of pipelines saved with DAiSS 38 | % on different machines 39 | tbxdir = fileparts(mfilename('fullpath')); 40 | cd(tbxdir); 41 | end 42 | end 43 | vars = who; 44 | eval(spm_file(batchfile, 'basename')); 45 | cd(cdir); 46 | name = setdiff(who, [vars; {'vars'}]); 47 | if numel(name)~= 1 48 | error('Invalid batch specification'); 49 | end 50 | matlabbatch = eval(char(name)); 51 | if ~isa(matlabbatch, 'cell') 52 | error('Invalid batch specification'); 53 | end 54 | elseif isequal(spm_file(batchfile, 'ext'), 'mat') 55 | try 56 | tmp = load(batchfile); 57 | catch 58 | tbxdir = fileparts(mfilename('fullpath')); 59 | tmp = load(spm_file(batchfile, 'path', tbxdir)); 60 | end 61 | name = fieldnames(tmp); 62 | if numel(name)~= 1 63 | error('Invalid batch specification'); 64 | end 65 | matlabbatch = tmp.(char(name)); 66 | if ~isa(matlabbatch, 'cell') 67 | error('Invalid batch specification'); 68 | end 69 | else 70 | error('Invalid batch specification'); 71 | end 72 | 73 | try 74 | matlabbatch{1}.spm.tools.beamforming; 75 | [~, matlabbatch] = spm_jobman('harvest', matlabbatch); 76 | catch 77 | error('Invalid batch specification. DAiSS batch expected.'); 78 | end 79 | 80 | res = cell(1, numel(BF)); 81 | for i = 1:numel(BF) 82 | if isfield(matlabbatch{1}.spm.tools.beamforming, 'data'); 83 | D = spm_eeg_load(BF{i}); 84 | matlabbatch{1}.spm.tools.beamforming.data.D = {fullfile(D)}; 85 | dum = mkdir(D.path, [S.prefix 'BF']); 86 | matlabbatch{1}.spm.tools.beamforming.data.dir = {fullfile(D.path, [S.prefix 'BF'])}; 87 | else 88 | module = char(fieldnames(matlabbatch{1}.spm.tools.beamforming)); 89 | matlabbatch{1}.spm.tools.beamforming.(module).BF = BF(i); 90 | end 91 | out = spm_jobman('run', matlabbatch); 92 | res(i) = out{end}.BF; 93 | end 94 | -------------------------------------------------------------------------------- /bf_inverse.m: -------------------------------------------------------------------------------- 1 | function out = bf_inverse 2 | % Computes inverse projectors 3 | % Copyright (C) 2012 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | % dir Directory 9 | % --------------------------------------------------------------------- 10 | BF = cfg_files; 11 | BF.tag = 'BF'; 12 | BF.name = 'BF.mat file'; 13 | BF.filter = '^BF.mat$'; 14 | BF.num = [1 1]; 15 | BF.help = {'Select BF.mat file.'}; 16 | 17 | %-------------------------------------------------------------------------- 18 | % method 19 | %-------------------------------------------------------------------------- 20 | plugin = cfg_choice; 21 | plugin.tag = 'plugin'; 22 | plugin.name = 'Inverse method'; 23 | 24 | inverse_funs = spm_select('List', fileparts(mfilename('fullpath')), '^bf_inverse_.*\.m$'); 25 | inverse_funs = cellstr(inverse_funs ); 26 | for i = 1:numel(inverse_funs) 27 | plugin.values{i} = feval(spm_file(inverse_funs{i},'basename')); 28 | end 29 | 30 | 31 | out = cfg_exbranch; 32 | out.tag = 'inverse'; 33 | out.name = 'Inverse solution'; 34 | out.val = {BF, plugin}; 35 | out.help = {'Compute inverse projectors'}; 36 | out.prog = @bf_inverse_run; 37 | out.vout = @bf_inverse_vout; 38 | out.modality = {'EEG'}; 39 | end 40 | 41 | function out = bf_inverse_run(job) 42 | 43 | outdir = spm_file(job.BF{1}, 'fpath'); 44 | 45 | cd(outdir); 46 | 47 | BF = bf_load('BF.mat', {'data', 'sources', 'features'}); 48 | plugin_name = cell2mat(fieldnames(job.plugin)); 49 | S = job.plugin.(plugin_name); 50 | 51 | if ~isa(S, 'struct') 52 | S = []; 53 | end 54 | 55 | modalities = intersect(fieldnames(BF.features), {'MEG', 'MEGPLANAR', 'MEGMAG', 'EEG'}); 56 | 57 | for m = 1:numel(modalities) 58 | S(1).modality = modalities{m}; 59 | 60 | [S.L, channels] = bf_fuse_lf(BF, S.modality); 61 | 62 | BF.inverse.(modalities{m}) = feval(['bf_inverse_' plugin_name], BF, S); 63 | BF.inverse.(modalities{m}).channels = channels; 64 | if ~isfield(BF.inverse.(modalities{m}), 'L') 65 | BF.inverse.(modalities{m}).L = S.L; 66 | end 67 | end 68 | 69 | bf_save(BF); 70 | 71 | out.BF{1} = fullfile(outdir, 'BF.mat'); 72 | end 73 | 74 | 75 | function dep = bf_inverse_vout(job) 76 | % Output is always in field "D", no matter how job is structured 77 | dep = cfg_dep; 78 | dep.sname = 'BF.mat file'; 79 | % reference field "B" from output 80 | dep.src_output = substruct('.','BF'); 81 | % this can be entered into any evaluated input 82 | dep.tgt_spec = cfg_findspec({{'filter','mat'}}); 83 | end 84 | -------------------------------------------------------------------------------- /bf_inverse_champagne.m: -------------------------------------------------------------------------------- 1 | function res = bf_inverse_champagne(BF, S) 2 | % Computes Champagne filters 3 | % See Owen et al. Performance evaluation of the Champagne source 4 | % reconstruction algorithm on simulated and real M/EEG data. Neuroimage. 2012 Mar;60(1):305-23 5 | % Code contributed by Sri Nagarajan 6 | % Copyright (C) 2015 Wellcome Trust Centre for Neuroimaging 7 | 8 | % Vladimir Litvak 9 | % $Id$ 10 | 11 | %-------------------------------------------------------------------------- 12 | if nargin == 0 13 | nem = cfg_entry; 14 | nem.tag = 'nem'; 15 | nem.name = 'Number of EM iterations'; 16 | nem.strtype = 'n'; 17 | nem.num = [1 1]; 18 | nem.val = {100}; 19 | 20 | vcs = cfg_menu; 21 | vcs.tag = 'vcs'; 22 | vcs.name = 'Voxel covariance structure'; 23 | vcs.labels = { 24 | 'scalar' 25 | 'diagonal' 26 | 'general' 27 | }'; 28 | vcs.values = {0, 1, 2}; 29 | vcs.val = {2}; 30 | 31 | nupd = cfg_menu; 32 | nupd.tag = 'nupd'; 33 | nupd.name = 'Noise covariance'; 34 | nupd.labels = { 35 | 'use provided' 36 | 'learn scalar' 37 | 'learn diagonal' 38 | }'; 39 | nupd.values = {0, 1, 2}; 40 | nupd.val = {0}; 41 | 42 | champagne = cfg_branch; 43 | champagne.tag = 'champagne'; 44 | champagne.name = 'Champagne'; 45 | champagne.val = {nem, vcs, nupd}; 46 | res = champagne; 47 | 48 | return 49 | elseif nargin < 2 50 | error('Two input arguments are required'); 51 | end 52 | 53 | 54 | C = BF.features.(S.modality).C; 55 | Y = BF.features.(S.modality).Y; 56 | 57 | L = S.L; 58 | 59 | W = cell(size(L)); 60 | nvert = numel(W); 61 | nd = size(L{1}, 2); 62 | 63 | LL = zeros(size(L{1}, 1), nvert*nd); 64 | ind = 1; 65 | 66 | spm('Pointer', 'Watch');drawnow; 67 | spm_progress_bar('Init', nvert, ['Preparing ' S.modality ' leadfields']); drawnow; 68 | if nvert > 100, Ibar = floor(linspace(1, nvert,100)); 69 | else Ibar = 1:nvert; end 70 | 71 | for i = 1:nvert 72 | 73 | for j = 1:nd 74 | lf = L{i}(:, j); 75 | LL(:, ind) = lf./norm(lf); 76 | ind = ind+1; 77 | end 78 | if ismember(i, Ibar) 79 | spm_progress_bar('Set', i); drawnow; 80 | end 81 | end 82 | 83 | Fgraph = spm_figure('GetWin', 'Champagne'); figure(Fgraph); clf 84 | 85 | %**************************************************************************************** 86 | [gamma,x,w,sigu,like]=champagne_aug2015(Y, LL, C, S.nem, nd, S.vcs, S.nupd, [], 0, Fgraph); 87 | %**************************************************************************************** 88 | 89 | spm_progress_bar('Init', nvert, ['Preparing ' S.modality ' filters']); drawnow; 90 | if nvert > 100, Ibar = floor(linspace(1, nvert,100)); 91 | else Ibar = 1:nvert; end 92 | 93 | for i = 1:nvert 94 | W{i} = w((i-1)*nd+(1:3), :); 95 | 96 | if ismember(i, Ibar) 97 | spm_progress_bar('Set', i); drawnow; 98 | end 99 | end 100 | 101 | 102 | spm_progress_bar('Clear'); 103 | 104 | spm('Pointer', 'Arrow'); 105 | 106 | res.W = W; -------------------------------------------------------------------------------- /bf_inverse_dics.m: -------------------------------------------------------------------------------- 1 | function res = bf_inverse_dics(BF, S) 2 | % Computes DICS filters 3 | % Copyright (C) 2013 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0 10 | 11 | fixedori = cfg_menu; 12 | fixedori.tag = 'fixedori'; 13 | fixedori.name = 'Optimise for maximal power'; 14 | fixedori.labels = {'Yes', 'No'}; 15 | fixedori.val = {'yes'}; 16 | fixedori.values = {'yes', 'no'}; 17 | fixedori.help = {'Optimise dipole orientation for maximal power'}; 18 | 19 | dics = cfg_branch; 20 | dics.tag = 'dics'; 21 | dics.name = 'DICS'; 22 | dics.val = {fixedori}; 23 | 24 | res = dics; 25 | 26 | return 27 | elseif nargin < 2 28 | error('Two input arguments are required'); 29 | end 30 | 31 | 32 | C = BF.features.(S.modality).C; 33 | Cinv = BF.features.(S.modality).Cinv; 34 | 35 | U = BF.features.(S.modality).U; 36 | 37 | L = S.L; 38 | 39 | W = cell(size(L)); 40 | 41 | nvert = numel(W); 42 | 43 | spm('Pointer', 'Watch');drawnow; 44 | spm_progress_bar('Init', nvert, ['Computing ' S.modality ' filters']); drawnow; 45 | if nvert > 100, Ibar = floor(linspace(1, nvert,100)); 46 | else Ibar = 1:nvert; end 47 | 48 | for i = 1:nvert 49 | if ~isnan(L{i}) 50 | lf = U'*L{i}; 51 | 52 | if size(lf, 2) == 1 53 | S.fixedori = 'no'; 54 | end 55 | 56 | estimate = ft_inverse_beamformer_dics(lf, C, 'invCf', Cinv,... 57 | 'fixedori', S.fixedori, 'filteronly', 'yes', 'projectnoise', 'no', ... 58 | 'keepfilter', 'yes', 'keepleadfield', 'no', 'keepcsd', 'no', 'feedback', 'none'); 59 | 60 | W(i) = estimate.filter; 61 | else 62 | W{i} = NaN; 63 | end 64 | 65 | if ismember(i, Ibar) 66 | spm_progress_bar('Set', i); drawnow; 67 | end 68 | end 69 | 70 | spm_progress_bar('Clear'); 71 | 72 | res.W = W; 73 | -------------------------------------------------------------------------------- /bf_inverse_eloreta.m: -------------------------------------------------------------------------------- 1 | function res = bf_inverse_eloreta(BF, S) 2 | % Computes eLORETA projectors 3 | % Copyright (C) 2013 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak, using the code from Guido Nolte 6 | % 7 | % please cite 8 | % R.D. Pascual-Marqui: Discrete, 3D distributed, linear imaging methods of electric neuronal activity. Part 1: exact, zero 9 | % error localization. arXiv:0710.3341 [math-ph], 2007-October-17, http://arxiv.org/pdf/0710.3341 10 | 11 | % $Id$ 12 | 13 | %-------------------------------------------------------------------------- 14 | if nargin == 0 15 | regularisation = cfg_entry; 16 | regularisation.tag = 'regularisation'; 17 | regularisation.name = 'Regularisation parameter'; 18 | regularisation.strtype = 'r'; 19 | regularisation.num = [1 1]; 20 | regularisation.val = {0.05}; 21 | regularisation.help = {'Optional regularization parameter (default is .05 corresponding ',... 22 | 'to 5% of the average of the eigenvalues of some matrix to be inverted.)'}; 23 | 24 | 25 | eloreta = cfg_branch; 26 | eloreta.tag = 'eloreta'; 27 | eloreta.name = 'eLORETA'; 28 | eloreta.val = {regularisation}; 29 | eloreta.help = {'eLORETA implementation by Guido Nolte',... 30 | 'Please cite',... 31 | 'R.D. Pascual-Marqui: Discrete, 3D distributed, linear imaging methods of electric neuronal activity. Part 1: exact, zero',... 32 | 'error localization. arXiv:0710.3341 [math-ph], 2007-October-17, http://arxiv.org/pdf/0710.3341'}; 33 | 34 | res = eloreta; 35 | 36 | return 37 | elseif nargin < 2 38 | error('Two input arguments are required'); 39 | end 40 | 41 | U = BF.features.(S.modality).U; 42 | 43 | L = S.L; 44 | W = cell(size(L)); 45 | nvert = numel(W); 46 | 47 | LL = []; 48 | 49 | spm('Pointer', 'Watch');drawnow; 50 | spm_progress_bar('Init', nvert, ['Preparing ' S.modality ' leadfields']); drawnow; 51 | if nvert > 100, Ibar = floor(linspace(1, nvert,100)); 52 | else Ibar = 1:nvert; end 53 | 54 | for i = 1:nvert 55 | lf = U'*L{i}; 56 | 57 | lf = reshape(lf, [size(lf, 1), 1, size(lf, 2)]); 58 | 59 | LL = cat(2, LL, lf); 60 | 61 | if ismember(i, Ibar) 62 | spm_progress_bar('Set', i); drawnow; 63 | end 64 | end 65 | 66 | 67 | % construct the spatial filter 68 | w = mkfilt_eloreta_v2(LL,S.regularisation); 69 | 70 | spm_progress_bar('Init', nvert, ['Preparing ' S.modality ' filters']); drawnow; 71 | if nvert > 100, Ibar = floor(linspace(1, nvert,100)); 72 | else Ibar = 1:nvert; end 73 | 74 | for i = 1:nvert 75 | W{i} = spm_squeeze(w(:, i, :), 2)'; 76 | 77 | if ismember(i, Ibar) 78 | spm_progress_bar('Set', i); drawnow; 79 | end 80 | end 81 | 82 | 83 | spm_progress_bar('Clear'); 84 | 85 | res.W = W; 86 | -------------------------------------------------------------------------------- /bf_inverse_lcmv.m: -------------------------------------------------------------------------------- 1 | function res = bf_inverse_lcmv(BF, S) 2 | % Computes LCMV filters 3 | % Copyright (C) 2012 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0 10 | orient = cfg_menu; 11 | orient.tag = 'orient'; 12 | orient.name = 'Orient to maximum power'; 13 | orient.labels = {'yes', 'no'}; 14 | orient.values = {true, false}; 15 | orient.val = {true}; 16 | 17 | keeplf = cfg_menu; 18 | keeplf.tag = 'keeplf'; 19 | keeplf.name = 'Keep oriented leadfields'; 20 | keeplf.labels = {'yes', 'no'}; 21 | keeplf.values = {true, false}; 22 | keeplf.val = {false}; 23 | 24 | lcmv = cfg_branch; 25 | lcmv.tag = 'lcmv'; 26 | lcmv.name = 'LCMV'; 27 | lcmv.val = {orient, keeplf}; 28 | res = lcmv; 29 | 30 | return 31 | elseif nargin < 2 32 | error('Two input arguments are required'); 33 | end 34 | 35 | 36 | invCy = BF.features.(S.modality).Cinv; 37 | U = BF.features.(S.modality).U; 38 | 39 | reduce_rank = BF.sources.reduce_rank.(S.modality(1:3)); 40 | 41 | L = S.L; 42 | W = cell(size(L)); 43 | 44 | nvert = numel(W); 45 | 46 | spm('Pointer', 'Watch');drawnow; 47 | spm_progress_bar('Init', nvert, ['Computing ' S.modality ' filters']); drawnow; 48 | if nvert > 100, Ibar = floor(linspace(1, nvert,100)); 49 | else Ibar = 1:nvert; end 50 | 51 | for i = 1:nvert 52 | if ~isnan(L{i}) 53 | lf = U'*L{i}; 54 | 55 | if S.orient 56 | % Robert's code 57 | [u, dum] = svd(real(pinv_plus(lf' * invCy *lf, reduce_rank, 0)),'econ'); 58 | eta = u(:,1); 59 | lf = lf * eta; 60 | end 61 | 62 | % construct the spatial filter 63 | W{i} = pinv_plus(lf' * invCy * lf, reduce_rank, 0)*lf'*invCy; 64 | 65 | if S.keeplf 66 | L{i} = lf; 67 | end 68 | else 69 | W{i} = NaN; 70 | end 71 | 72 | if ismember(i, Ibar) 73 | spm_progress_bar('Set', i); drawnow; 74 | end 75 | end 76 | 77 | 78 | spm_progress_bar('Clear'); 79 | 80 | res.W = W; 81 | res.L = L; -------------------------------------------------------------------------------- /bf_inverse_lcmv_multicov.m: -------------------------------------------------------------------------------- 1 | function res = bf_inverse_lcmv_multicov(BF, S) 2 | % Computes LCMV filters using spm_pca_order to constrain inverse of data 3 | % cov matrix. Based on the paper: 4 | % MEG beamforming using Bayesian PCA for adaptive data covariance matrix regularization. 5 | % Woolrich M, Hunt L, Groves A, Barnes G. 6 | % Neuroimage. 2011 Aug 15;57(4) 7 | % 8 | % and allowing for multiple covariance matrices, e.g. associated with 9 | % multiple states: 10 | % Dynamic State Allocation for MEG Source Reconstruction 11 | % Neuroimage. Woolrich et al. 2013. 12 | % 13 | % Mark Woolrich 14 | %-------------------------------------------------------------------------- 15 | if nargin == 0 16 | 17 | pca_order = cfg_entry; 18 | pca_order.tag = 'pca_order'; 19 | pca_order.name = 'PCA order'; 20 | pca_order.val = {}; 21 | 22 | bilateral = cfg_entry; 23 | bilateral.tag = 'bilateral'; 24 | bilateral.name = 'Do bilateral beamformer'; 25 | bilateral.val = {}; 26 | 27 | type = cfg_menu; 28 | type.tag = 'type'; 29 | type.name = 'Beamformer type'; 30 | type.help = {'Select Scalar or Vector'}; 31 | type.labels = {'Vector', 'Scalar'}; 32 | type.values = {'Vector', 'Scalar'}; 33 | type.val = {'Scalar'}; 34 | 35 | lcmv_multicov = cfg_branch; 36 | lcmv_multicov.tag = 'lcmv_multicov'; 37 | lcmv_multicov.name = 'LCMV use multiple covariance and PCA order'; 38 | lcmv_multicov.val = {pca_order,bilateral,type}; 39 | 40 | res = lcmv_multicov; 41 | 42 | return 43 | elseif nargin < 2 44 | error('Two input arguments are required'); 45 | end 46 | 47 | inverse=[]; 48 | 49 | if isfield(BF.features, S.modality) 50 | 51 | %reduce_rank = S.reduce_rank; 52 | reduce_rank = BF.sources.reduce_rank.(S.modality(1:3)); 53 | 54 | if isfield(BF.features.(S.modality),'class'), 55 | class = BF.features.(S.modality).class; 56 | else 57 | class={}; 58 | class{1} = BF.features.(S.modality); 59 | end; 60 | 61 | % multiple covariances -do separate weights for each one 62 | for kk=1:length(class), 63 | 64 | if ~sum(isnan(squash(class{kk}.C))), 65 | [invCy, pca_order_used] = pinv_plus(class{kk}.C, S.pca_order); % rank maybe not be detected properly by just using pinv - MWW 66 | else 67 | warning(['Nans in covariance matrix for class ' num2str(kk)]); 68 | end; 69 | 70 | L = S.L; 71 | 72 | W = cell(size(L)); 73 | 74 | nvert = numel(W); 75 | 76 | spm('Pointer', 'Watch');drawnow; 77 | spm_progress_bar('Init', nvert, ['Computing ' S.modality ' filters']); drawnow; 78 | if nvert > 100, Ibar = floor(linspace(1, nvert,100)); 79 | else Ibar = 1:nvert; end 80 | 81 | for i = 1:nvert 82 | if ~sum(isnan(squash(L{i}))) && ~sum(isnan(squash(class{kk}.C))), 83 | lf = L{i}; 84 | lf_single = lf; 85 | 86 | do_lat=0; 87 | if S.bilateral, % beamform bilateral dipoles together 88 | if(BF.sources.mni.bilateral_index(i)~=i), 89 | do_lat=1; 90 | lf_lat=L{BF.sources.mni.bilateral_index(i)}; 91 | 92 | lf=[lf_single, lf_lat]; 93 | 94 | end; 95 | 96 | end; 97 | 98 | switch lower(S.type) 99 | 100 | case 'scalar' 101 | tmp=lf' * invCy *lf; 102 | nn=size(lf_single,2); 103 | 104 | [u, ~] = svd(real(pinv_plus(tmp(1:nn,1:nn),reduce_rank,0)),'econ'); % this is faster, - MWW 105 | eta = u(:,1); 106 | lf_single = lf_single * eta; 107 | 108 | if do_lat, 109 | [u, ~] = svd(real(pinv_plus(tmp(nn+1:2*nn,nn+1:2*nn),reduce_rank,0)),'econ'); % this is faster, - MWW 110 | eta = u(:,1); 111 | lf_lat = lf_lat * eta; 112 | 113 | lf=[lf_single, lf_lat]; 114 | tmp2 = pinv_plus(lf' * invCy * lf) * lf' * invCy; 115 | W{i}=tmp2(1,:); 116 | 117 | else 118 | lf=lf_single; 119 | 120 | % construct the spatial filter 121 | %W{i} = pinv(lf' * invCy * lf) * lf' * invCy; 122 | W{i} = lf'*invCy/(lf' * invCy * lf); % this is faster - MWW 123 | end; 124 | 125 | 126 | case 'vector' 127 | W{i} = pinv_plus(lf' * invCy * lf,reduce_rank) * lf' * invCy; % - AB 128 | 129 | end 130 | 131 | else 132 | W{i} = NaN; 133 | end 134 | 135 | if ismember(i, Ibar) 136 | spm_progress_bar('Set', i); drawnow; 137 | end 138 | end 139 | 140 | inverse.class{kk}.W = W; 141 | inverse.class{kk}.L = L; 142 | end; 143 | 144 | end 145 | 146 | res = inverse; -------------------------------------------------------------------------------- /bf_inverse_minimumnorm.m: -------------------------------------------------------------------------------- 1 | function res = bf_inverse_minimumnorm(BF, S) 2 | % Computes Minimum Norm projectors 3 | % Copyright (C) 2013 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak, using the code from Matti Stenroos and Olaf Hauk 6 | % http://imaging.mrc-cbu.cam.ac.uk/meg/AnalyzingData/DeFleCT_SpatialFiltering_Tools 7 | % 8 | % Please cite: 9 | % Hauk O, Stenroos M. 10 | % A framework for the design of flexible cross-talk functions for spatial filtering of EEG/MEG data: DeFleCT. 11 | % Human Brain Mapping 2013 12 | % $Id$ 13 | 14 | %-------------------------------------------------------------------------- 15 | if nargin == 0 16 | snr = cfg_entry; 17 | snr.tag = 'snr'; 18 | snr.name = 'SNR'; 19 | snr.strtype = 'r'; 20 | snr.num = [1 1]; 21 | snr.val = {5}; 22 | snr.help = {'The assumed ratio of variances of signal and noise,',... 23 | 'used for setting the regularisation parameter.'}; 24 | 25 | trunc = cfg_entry; 26 | trunc.tag = 'trunc'; 27 | trunc.name = 'Truncation parameter'; 28 | trunc.strtype = 'w'; 29 | trunc.num = [1 1]; 30 | trunc.val = {0}; 31 | trunc.help = {'The number of (smallest) singular values of the covariance matrix that are set to ',... 32 | 'zero before making the whitener. For example, if the data has been SSP-projected, it needs to be at least the number of ',... 33 | 'components projected away.'}; 34 | 35 | minimumnorm = cfg_branch; 36 | minimumnorm.tag = 'minimumnorm'; 37 | minimumnorm.name = 'Minimum norm'; 38 | minimumnorm.val = {snr, trunc}; 39 | minimumnorm.help = {'Minimum norm implementation by Matti Stenroos and Olaf Hauk',... 40 | 'http://imaging.mrc-cbu.cam.ac.uk/meg/AnalyzingData/DeFleCT_SpatialFiltering_Tools',... 41 | 'Please cite:'... 42 | 'Hauk O, Stenroos M.',... 43 | 'A framework for the design of flexible cross-talk functions for spatial filtering of EEG/MEG data: DeFleCT.',... 44 | 'Human Brain Mapping 2013'}; 45 | res = minimumnorm; 46 | 47 | return 48 | elseif nargin < 2 49 | error('Two input arguments are required'); 50 | end 51 | 52 | 53 | C = BF.features.(S.modality).C; 54 | U = BF.features.(S.modality).U; 55 | 56 | L = S.L; 57 | W = cell(size(L)); 58 | 59 | nvert = numel(W); 60 | 61 | nori = size(L{1}, 2); 62 | 63 | LL = []; 64 | 65 | spm('Pointer', 'Watch');drawnow; 66 | spm_progress_bar('Init', nvert, ['Preparing ' S.modality ' leadfields']); drawnow; 67 | if nvert > 100, Ibar = floor(linspace(1, nvert,100)); 68 | else Ibar = 1:nvert; end 69 | 70 | for i = 1:nvert 71 | lf = U'*L{i}; 72 | 73 | LL = cat(2, LL, lf); 74 | 75 | if ismember(i, Ibar) 76 | spm_progress_bar('Set', i); drawnow; 77 | end 78 | end 79 | 80 | WW = MNestimator(LL,C, S.snr,S.trunc); 81 | 82 | spm_progress_bar('Init', nvert, ['Preparing ' S.modality ' filters']); drawnow; 83 | if nvert > 100, Ibar = floor(linspace(1, nvert,100)); 84 | else Ibar = 1:nvert; end 85 | 86 | for i = 1:nvert 87 | W{i} = WW(((i-1)*nori+1):(i*nori), :); 88 | 89 | if ismember(i, Ibar) 90 | spm_progress_bar('Set', i); drawnow; 91 | end 92 | end 93 | 94 | 95 | spm_progress_bar('Clear'); 96 | 97 | res.W = W; 98 | -------------------------------------------------------------------------------- /bf_inverse_nutmeg.m: -------------------------------------------------------------------------------- 1 | function res = bf_inverse_nutmeg(BF, S) 2 | % Interface to NUTMEG inverse methods 3 | % http://www.nitrc.org/plugins/mwiki/index.php/nutmeg:MainPage 4 | % Copyright (C) 2015 Wellcome Trust Centre for Neuroimaging 5 | 6 | 7 | % $Id: bf_inverse_eloreta.m 96 2013-12-10 17:48:00Z litvak.vladimir@gmail.com $ 8 | 9 | %-------------------------------------------------------------------------- 10 | if nargin == 0 11 | method = cfg_menu; 12 | method.tag = 'method'; 13 | method.name = 'Method'; 14 | method.labels = { 15 | 'sLORETA' 16 | 'swLORETA' 17 | 'dSPM'}; 18 | method.values = method.labels; 19 | method.help = {'Select one of NUTMEG methods'}; 20 | 21 | snr = cfg_entry; 22 | snr.tag = 'snr'; 23 | snr.name = 'SNR'; 24 | snr.strtype = 'e'; 25 | snr.num = [0 0]; 26 | snr.val = {[]}; 27 | snr.help = {'The assumed ratio of variances of signal and noise,',... 28 | 'used for setting the regularisation parameter.'}; 29 | 30 | regularisation = cfg_entry; 31 | regularisation.tag = 'regularisation'; 32 | regularisation.name = 'Regularisation parameter'; 33 | regularisation.strtype = 'e'; 34 | regularisation.num = [0 0]; 35 | regularisation.val = {[]}; 36 | regularisation.help = {'Optional regularization parameter.'}; 37 | 38 | 39 | nutmeg = cfg_branch; 40 | nutmeg.tag = 'nutmeg'; 41 | nutmeg.name = 'NUTMEG methods'; 42 | nutmeg.val = {method, snr, regularisation}; 43 | nutmeg.help = {'Methods ported from NUTMEG toolbox',... 44 | 'See http://www.nitrc.org/plugins/mwiki/index.php/nutmeg:MainPage'}; 45 | 46 | res = nutmeg; 47 | 48 | return 49 | elseif nargin < 2 50 | error('Two input arguments are required'); 51 | end 52 | 53 | 54 | C = BF.features.(S.modality).C; 55 | U = BF.features.(S.modality).U; 56 | 57 | L = S.L; 58 | W = cell(size(L)); 59 | nvert = numel(W); 60 | 61 | data.Ryy = C; 62 | flags = []; 63 | if ~isempty(S.snr) 64 | flags.snr = S.snr; 65 | end 66 | if ~isempty(S.regularisation) 67 | flags.gamma = S.regularisation; 68 | end 69 | 70 | LL = []; 71 | spm('Pointer', 'Watch');drawnow; 72 | spm_progress_bar('Init', nvert, ['Preparing ' S.modality ' leadfields']); drawnow; 73 | if nvert > 100, Ibar = floor(linspace(1, nvert,100)); 74 | else Ibar = 1:nvert; end 75 | 76 | for i = 1:nvert 77 | lf = U'*L{i}; 78 | 79 | LL = cat(3, LL, lf); 80 | 81 | if ismember(i, Ibar) 82 | spm_progress_bar('Set', i); drawnow; 83 | end 84 | end 85 | 86 | 87 | switch S.method 88 | case 'sLORETA' 89 | w = nut_sLORETA(LL,data,flags); 90 | case 'swLORETA' 91 | w = nut_swLORETA(LL,data,flags); 92 | case 'dSPM' 93 | w = nut_dSPM(LL,data,flags); 94 | end 95 | 96 | 97 | spm_progress_bar('Init', nvert, ['Preparing ' S.modality ' filters']); drawnow; 98 | if nvert > 100, Ibar = floor(linspace(1, nvert,100)); 99 | else Ibar = 1:nvert; end 100 | 101 | for i = 1:nvert 102 | W{i} = spm_squeeze(w(:, :, i), 3)'; 103 | 104 | if ismember(i, Ibar) 105 | spm_progress_bar('Set', i); drawnow; 106 | end 107 | end 108 | 109 | 110 | spm_progress_bar('Clear'); 111 | 112 | res.W = W; -------------------------------------------------------------------------------- /bf_load.m: -------------------------------------------------------------------------------- 1 | function BF = bf_load(file, fields) 2 | % Loads BF data into memory with just the requested fields 3 | % Copyright (C) 2012 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id: bf_load.m 131 2015-08-19 16:04:20Z litvak.vladimir@gmail.com $ 7 | 8 | % get filename 9 | %------------------------------------------------------------------------- 10 | if nargin == 0 11 | [file, sts] = spm_select(1, '^BF.mat$', 'Select BF.mat file'); 12 | if ~sts, BF = []; return; end 13 | end 14 | 15 | vars = whos('-file', file); 16 | if numel(intersect({vars(:).name}, bf_std_fields)) == 0 17 | error('No BF fields in the file'); 18 | end 19 | 20 | % load MAT file 21 | %-------------------------------------------------------------------------- 22 | if nargin <= 1 23 | BF = load(file); 24 | else 25 | if ~iscell(fields) 26 | fields = {fields}; 27 | end 28 | BF = load(file, fields{:}); 29 | end 30 | 31 | [sel1, sel2] = spm_match_str(bf_std_fields, fieldnames(BF)); 32 | 33 | [other_fields, sel3] = setdiff(fieldnames(BF), bf_std_fields); 34 | [other_fields_sorted, sel4] = sort(other_fields); 35 | 36 | tmpcell = struct2cell(BF); 37 | BF = cell2struct(tmpcell([sel2 sel3(sel4)]), [bf_std_fields(sel1) other_fields_sorted], 1); 38 | 39 | -------------------------------------------------------------------------------- /bf_output.m: -------------------------------------------------------------------------------- 1 | function out = bf_output 2 | % Performs postprocessing based on beamforming projectors 3 | % Copyright (C) 2012 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | % dir Directory 9 | % --------------------------------------------------------------------- 10 | BF = cfg_files; 11 | BF.tag = 'BF'; 12 | BF.name = 'BF.mat file'; 13 | BF.filter = '^BF.mat$'; 14 | BF.num = [1 1]; 15 | BF.help = {'Select BF.mat file.'}; 16 | 17 | 18 | %-------------------------------------------------------------------------- 19 | % method 20 | %-------------------------------------------------------------------------- 21 | plugin = cfg_choice; 22 | plugin.tag = 'plugin'; 23 | plugin.name = 'Output method'; 24 | 25 | output_funs = spm_select('List', fileparts(mfilename('fullpath')), '^bf_output_.*\.m$'); 26 | output_funs = cellstr(output_funs ); 27 | for i = 1:numel(output_funs) 28 | plugin.values{i} = feval(spm_file(output_funs{i},'basename')); 29 | end 30 | 31 | out = cfg_exbranch; 32 | out.tag = 'output'; 33 | out.name = 'Output'; 34 | out.val = {BF, plugin}; 35 | out.help = {'Compute output measures'}; 36 | out.prog = @bf_output_run; 37 | out.vout = @bf_output_vout; 38 | out.modality = {'EEG'}; 39 | end 40 | 41 | function out = bf_output_run(job) 42 | 43 | outdir = spm_file(job.BF{1}, 'fpath'); 44 | 45 | cd(outdir); 46 | 47 | BF = bf_load('BF.mat', {'data','sources', 'features', 'inverse'}); 48 | 49 | plugin_name = cell2mat(fieldnames(job.plugin)); 50 | 51 | outfield_name = strtok(plugin_name, '_'); 52 | 53 | BF.output.(outfield_name) = feval(['bf_output_' plugin_name], BF, job.plugin.(plugin_name)); 54 | 55 | bf_save(BF); 56 | 57 | out.BF{1} = fullfile(outdir, 'BF.mat'); 58 | end 59 | 60 | function dep = bf_output_vout(job) 61 | % Output is always in field "D", no matter how job is structured 62 | dep = cfg_dep; 63 | dep.sname = 'BF.mat file'; 64 | % reference field "B" from output 65 | dep.src_output = substruct('.','BF'); 66 | % this can be entered into any evaluated input 67 | dep.tgt_spec = cfg_findspec({{'filter','mat'}}); 68 | end 69 | -------------------------------------------------------------------------------- /bf_output_image_filtcorr.m: -------------------------------------------------------------------------------- 1 | function res = bf_output_image_filtcorr(BF, S) 2 | % Computes filter correlation images 3 | % Copyright (C) 2013 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0 10 | pos = cfg_entry; 11 | pos.tag = 'pos'; 12 | pos.name = 'Seed MNI coordinates'; 13 | pos.strtype = 'r'; 14 | pos.num = [1 3]; 15 | pos.help = {'Locations for the seed in MNI coordinates (closest point is chosen'}; 16 | pos.val = {}; 17 | 18 | label = cfg_entry; 19 | label.tag = 'label'; 20 | label.name = 'Label'; 21 | label.strtype = 's'; 22 | label.help = {'Label for source of interest'}; 23 | 24 | seedspec = cfg_choice; 25 | seedspec.tag = 'seedspec'; 26 | seedspec.name = 'Seed specification'; 27 | seedspec.values = {pos, label}; 28 | 29 | corrtype = cfg_menu; 30 | corrtype.tag = 'corrtype'; 31 | corrtype.name = 'Correlation type'; 32 | corrtype.help = {'Whether to correlate filters with other filters of with other leadfields'}; 33 | corrtype.labels = {'Filter-Filter', 'Filter-Leadfield'}; 34 | corrtype.values = {'filtfilt', 'filtlf'}; 35 | corrtype.val = {'filtfilt'}; 36 | 37 | modality = cfg_menu; 38 | modality.tag = 'modality'; 39 | modality.name = 'Modality'; 40 | modality.help = {'Specify modality'}; 41 | modality.labels = { 42 | 'MEG' 43 | 'MEGPLANAR' 44 | 'EEG' 45 | }'; 46 | modality.values = { 47 | 'MEG' 48 | 'MEGPLANAR' 49 | 'EEG' 50 | }'; 51 | modality.val = {'MEG'}; 52 | 53 | filtcorr = cfg_branch; 54 | filtcorr.tag = 'image_filtcorr'; 55 | filtcorr.name = 'Filter correlations image'; 56 | filtcorr.val = {seedspec, corrtype, modality}; 57 | 58 | res = filtcorr; 59 | 60 | return 61 | elseif nargin < 2 62 | error('Two input arguments are required'); 63 | end 64 | 65 | nvert = size(BF.sources.pos, 1); 66 | 67 | % transform coords in MNI space into space where we are doing the beamforming 68 | if isfield(S.seedspec, 'pos') 69 | mnipos = spm_eeg_inv_transform_points(BF.data.transforms.toMNI, BF.sources.pos); 70 | 71 | dist = sqrt(sum((mnipos - repmat(S.seedspec.pos, nvert, 1)).^2, 2)); 72 | 73 | [mdist, ind] = min(dist); 74 | 75 | if mdist > 20 76 | warning(['Closest match is ' mdist ' mm away from the specified location.']); 77 | end 78 | else 79 | if isfield(BF.inverse.(S.modality), 'label') 80 | ind = strmatch(S.seedspec.label, BF.inverse.(S.modality).label, 'exact'); 81 | else 82 | error('Filters are not labeled, use position to specify seed.'); 83 | end 84 | end 85 | 86 | ws = BF.inverse.(S.modality).W{ind}; 87 | 88 | [QA, dum] = qr(orth(ws'),0); 89 | Q = svd(QA'*QA); 90 | scale = 1/sum(Q); 91 | 92 | spm('Pointer', 'Watch');drawnow; 93 | 94 | spm_progress_bar('Init', nvert, 'Scanning grid points'); drawnow; 95 | if nvert > 100, Ibar = floor(linspace(1, nvert,100)); 96 | else Ibar = 1:nvert; end 97 | 98 | pow = nan(1, nvert); 99 | 100 | U = BF.features.(S.modality).U; 101 | 102 | for i = 1:nvert 103 | switch S.corrtype 104 | case 'filtfilt' 105 | w = BF.inverse.(S.modality).W{i}'; 106 | case 'filtlf' 107 | w = U'*BF.inverse.(S.modality).L{i}; 108 | end 109 | 110 | if ~isnan(w) 111 | % This is subspace intersection which is supposed to handle the case 112 | % when filters are more than 1D and be equivalent to correlation 113 | % coefficient for the 1D case 114 | [QB, dum] = qr(orth(w),0); 115 | Q = svd(QA'*QB); 116 | pow(i) = scale*sum(Q); 117 | end 118 | 119 | if ismember(i, Ibar) 120 | spm_progress_bar('Set', i); drawnow; 121 | end 122 | end 123 | 124 | spm_progress_bar('Clear'); 125 | 126 | image.val = pow; 127 | 128 | image.label = ['filtcorr_' spm_file(fname(BF.data.D), 'basename')]; 129 | 130 | spm('Pointer', 'Arrow');drawnow; 131 | 132 | res = image; -------------------------------------------------------------------------------- /bf_output_image_gain.m: -------------------------------------------------------------------------------- 1 | function res = bf_output_image_gain(BF, S) 2 | % Computes gain image 3 | % Copyright (C) 2013 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Ashwini Oswal, Vladimir Litvak 6 | % $Id$ 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0 10 | type = cfg_menu; 11 | type.tag = 'type'; 12 | type.name = 'Output type'; 13 | type.help = {'The calculation that should be performed'}; 14 | type.labels = {'Reduced/Original'}; 15 | type.values = {'reduced_vs_orig'}; 16 | type.val = {'reduced_vs_orig'}; 17 | 18 | modality = cfg_menu; 19 | modality.tag = 'modality'; 20 | modality.name = 'Modality'; 21 | modality.help = {'Specify modality'}; 22 | modality.labels = { 23 | 'MEG' 24 | 'MEGPLANAR' 25 | 'EEG' 26 | }'; 27 | modality.values = { 28 | 'MEG' 29 | 'MEGPLANAR' 30 | 'EEG' 31 | }'; 32 | modality.val = {'MEG'}; 33 | 34 | gain = cfg_branch; 35 | gain.tag = 'image_gain'; 36 | gain.name = 'Gain image'; 37 | gain.val = {type, modality}; 38 | 39 | res = gain; 40 | 41 | return 42 | elseif nargin < 2 43 | error('Two input arguments are required'); 44 | end 45 | 46 | nvert = size(BF.sources.pos, 1); 47 | 48 | spm('Pointer', 'Watch');drawnow; 49 | 50 | spm_progress_bar('Init', nvert, 'Scanning grid points'); drawnow; 51 | if nvert > 100, Ibar = floor(linspace(1, nvert,100)); 52 | else Ibar = 1:nvert; end 53 | 54 | val = nan(1, nvert); 55 | 56 | U = BF.features.(S.modality).U; 57 | 58 | for i = 1:nvert 59 | switch S.type 60 | case 'reduced_vs_orig' 61 | lt = U; 62 | 63 | if isfield(BF, 'inverse') 64 | lf = BF.inverse.(S.modality).L{i}; 65 | else 66 | lf = BF.sources.L.(S.modality(1:3)){i}; 67 | end 68 | if ~isnan(lf) 69 | % spatial filtering function defined in equation (7) of VanVeen 70 | % paper NB there is a slight error in the paper itself 71 | val(i) = trace(lf'*lt*(lf'*lt)')/trace(lf'*lf); 72 | end 73 | end 74 | 75 | if ismember(i, Ibar) 76 | spm_progress_bar('Set', i); drawnow; 77 | end 78 | end 79 | 80 | spm_progress_bar('Clear'); 81 | 82 | image.val = val; 83 | 84 | image.label = ['gain_' spm_file(fname(BF.data.D), 'basename')]; 85 | 86 | spm('Pointer', 'Arrow');drawnow; 87 | 88 | res = image; -------------------------------------------------------------------------------- /bf_output_image_kurtosis.m: -------------------------------------------------------------------------------- 1 | function res = bf_output_image_kurtosis(BF, S) 2 | % Computes kurtosis image 3 | % Copyright (C) 2019 Wellcome Centre for Human Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0 10 | all = cfg_const; 11 | all.tag = 'all'; 12 | all.name = 'All'; 13 | all.val = {1}; 14 | 15 | condlabel = cfg_entry; 16 | condlabel.tag = 'condlabel'; 17 | condlabel.name = 'Condition label'; 18 | condlabel.strtype = 's'; 19 | condlabel.val = {''}; 20 | 21 | conditions = cfg_repeat; 22 | conditions.tag = 'conditions'; 23 | conditions.name = 'Conditions'; 24 | conditions.help = {'Specify the labels of the conditions to be included in the inversion'}; 25 | conditions.num = [1 Inf]; 26 | conditions.values = {condlabel}; 27 | conditions.val = {condlabel}; 28 | 29 | whatconditions = cfg_choice; 30 | whatconditions.tag = 'whatconditions'; 31 | whatconditions.name = 'What conditions to include?'; 32 | whatconditions.values = {all, conditions}; 33 | whatconditions.val = {all}; 34 | 35 | method = cfg_menu; 36 | method.tag = 'method'; 37 | method.name = 'Summary method'; 38 | method.labels = {'max', 'svd'}; 39 | method.val = {'max'}; 40 | method.values = {'max', 'svd'}; 41 | method.help = {'How to summarise orientations'}; 42 | 43 | modality = cfg_menu; 44 | modality.tag = 'modality'; 45 | modality.name = 'Modality'; 46 | modality.help = {'Specify modality'}; 47 | modality.labels = { 48 | 'MEG' 49 | 'MEGPLANAR' 50 | 'EEG' 51 | }'; 52 | modality.values = { 53 | 'MEG' 54 | 'MEGPLANAR' 55 | 'EEG' 56 | }'; 57 | modality.val = {'MEG'}; 58 | 59 | image_kurtosis = cfg_branch; 60 | image_kurtosis.tag = 'image_kurtosis'; 61 | image_kurtosis.name = 'Kurtosis image'; 62 | image_kurtosis.val = {whatconditions, modality}; 63 | 64 | res = image_kurtosis; 65 | 66 | return 67 | elseif nargin < 2 68 | error('Two input arguments are required'); 69 | end 70 | 71 | D = BF.data.D; 72 | 73 | if isfield(S.whatconditions, 'all') 74 | S.whatconditions.condlabel = D.condlist; 75 | end 76 | 77 | for i = 1:numel(S.whatconditions.condlabel) 78 | 79 | trials{i} = D.indtrial(S.whatconditions.condlabel{i}, 'GOOD'); 80 | 81 | if isempty(trials{i}) 82 | error('No trials matched the selection.'); 83 | end 84 | 85 | end 86 | 87 | if isempty(trials) 88 | error('No trials matched the selection, check the specified condition labels'); 89 | end 90 | 91 | channels = BF.features.(S.modality).chanind; 92 | U = BF.features.(S.modality).U; 93 | nchan = size(U, 2); 94 | 95 | alltrials = spm_vec(trials); 96 | ntrials = length(alltrials); 97 | 98 | W = BF.inverse.(S.modality).W; 99 | nvert = numel(W); 100 | 101 | WW = []; 102 | 103 | spm('Pointer', 'Watch');drawnow; 104 | 105 | spm_progress_bar('Init', nvert, ... 106 | sprintf('Preparing filters')); drawnow; 107 | if nvert > 100, Ibar = floor(linspace(1, nvert,100)); 108 | else Ibar = 1:nvert; end 109 | 110 | for i = 1:nvert 111 | if ~isnan(W{i}) 112 | w = W{i}; 113 | 114 | if size(w, 1)>1 115 | switch S.method 116 | case 'max' 117 | Wc = w* BF.features.(modalities{m}).C*w'; % bf estimated source covariance matrix 118 | [dum, mi] = max(diag(Wc)); 119 | w = w(mi, :); 120 | case 'svd' 121 | %% just take top pca component for now 122 | Wc = w* BF.features.(modalities{m}).C*w'; % bf estimated source covariance matrix 123 | 124 | [V,dum,dum]=svd(Wc); 125 | w = (V(:,1)'/sqrt(size(Wc, 1)))*w; 126 | end 127 | end 128 | end 129 | 130 | WW = [WW; w(:)']; 131 | end 132 | 133 | 134 | s2 = zeros(size(WW, 1), 1); 135 | m4 = zeros(size(WW, 1), 1); 136 | 137 | spm('Pointer', 'Watch');drawnow; 138 | spm_progress_bar('Init', ntrials , 'Computing kurtosis'); drawnow; 139 | if ntrials > 100, Ibar = floor(linspace(1, ntrials ,100)); 140 | else Ibar = 1:ntrials; end 141 | 142 | 143 | for i = 1:ntrials 144 | Y = U'*squeeze(D(channels, ':', alltrials(i))); 145 | Y = detrend(Y', 'constant')'; 146 | 147 | Ys = WW*Y; 148 | 149 | s2 = s2+sum(Ys.^2, 2); 150 | m4 = m4+sum(Ys.^4, 2); 151 | 152 | if ismember(i, Ibar) 153 | spm_progress_bar('Set', i); drawnow; 154 | end 155 | end 156 | 157 | s2 = s2/(D.nsamples*ntrials); 158 | m4 = m4/(D.nsamples*ntrials); 159 | 160 | k = m4 ./ s2.^2; 161 | 162 | spm_progress_bar('Clear'); 163 | 164 | spm('Pointer', 'Arrow');drawnow; 165 | 166 | image(1).val = k; 167 | image(1).label = ['kurtosis_' spm_file(D.fname, 'basename')]; 168 | 169 | res = image; -------------------------------------------------------------------------------- /bf_output_image_sensitivity.m: -------------------------------------------------------------------------------- 1 | function res = bf_output_image_sensitivity(BF, S) 2 | % Sensitivity profile for a group of sensors 3 | % Copyright (C) 2017 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0 10 | modality = cfg_menu; 11 | modality.tag = 'modality'; 12 | modality.name = 'Modality'; 13 | modality.help = {'Specify modality'}; 14 | modality.labels = { 15 | 'MEG' 16 | 'MEGPLANAR' 17 | 'EEG' 18 | }'; 19 | modality.values = { 20 | 'MEG' 21 | 'MEGPLANAR' 22 | 'EEG' 23 | }'; 24 | modality.val = {'MEG'}; 25 | 26 | sensitivity = cfg_branch; 27 | sensitivity.tag = 'image_sensitivity'; 28 | sensitivity.name = 'Sensitivity image'; 29 | sensitivity.val = {spm_cfg_eeg_channel_selector, modality}; 30 | 31 | res = sensitivity; 32 | 33 | return 34 | elseif nargin < 2 35 | error('Two input arguments are required'); 36 | end 37 | 38 | nvert = size(BF.sources.pos, 1); 39 | 40 | spm('Pointer', 'Watch');drawnow; 41 | 42 | spm_progress_bar('Init', nvert, 'Scanning grid points'); drawnow; 43 | if nvert > 100, Ibar = floor(linspace(1, nvert,100)); 44 | else Ibar = 1:nvert; end 45 | 46 | val = nan(1, nvert); 47 | D = BF.data.D; 48 | 49 | selectchan = D.chanlabels(D.selectchannels(spm_cfg_eeg_channel_selector(S.channels))); 50 | 51 | for i = 1:nvert 52 | 53 | if isfield(BF, 'inverse') 54 | lf = BF.inverse.(S.modality).L{i}; 55 | channels = BF.inverse.(S.modality).channels; 56 | else 57 | lf = BF.sources.L.(S.modality(1:3)){i}; 58 | channels = BF.sources.channels.(S.modality(1:3)); 59 | end 60 | 61 | [sel1, sel2] = spm_match_str(selectchan, channels); 62 | 63 | lf = lf(sel2, :); 64 | 65 | if ~any(isnan(lf)) 66 | val(i) = sqrt(trace(lf'*lf)); 67 | end 68 | 69 | 70 | if ismember(i, Ibar) 71 | spm_progress_bar('Set', i); drawnow; 72 | end 73 | end 74 | 75 | spm_progress_bar('Clear'); 76 | 77 | image.val = val; 78 | 79 | image.label = ['sensitivity_' spm_file(fname(BF.data.D), 'basename')]; 80 | 81 | spm('Pointer', 'Arrow');drawnow; 82 | 83 | res = image; -------------------------------------------------------------------------------- /bf_output_sourcedata_robust.m: -------------------------------------------------------------------------------- 1 | function sourcedata_robust = bf_output_sourcedata_robust(BF, S) 2 | % Extracts source data, handling bad data segments 3 | % Copyright (C) 2013 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id: bf_output_sourcedata_robust.m 89 2013-11-14 12:34:26Z adambaker86@gmail.com $ 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0 10 | method = cfg_menu; 11 | method.tag = 'method'; 12 | method.name = 'Summary method'; 13 | method.labels = {'max', 'svd', 'keep'}; 14 | method.val = {'max'}; 15 | method.values = {'max', 'svd', 'keep'}; 16 | method.help = {'How to summarise sources in the ROI'}; 17 | 18 | sourcedata_robust = cfg_branch; 19 | sourcedata_robust.tag = 'sourcedata_robust'; 20 | sourcedata_robust.name = 'Source data (robust)'; 21 | sourcedata_robust.val = {method}; 22 | return 23 | elseif nargin < 2 24 | error('Two input arguments are required'); 25 | end 26 | 27 | D = BF.data.D; 28 | 29 | modalities = intersect(fieldnames(BF.features), {'EEG', 'MEG', 'MEGPLANAR'}); 30 | samples = 1:D.nsamples; 31 | 32 | 33 | for m = 1:numel(modalities) 34 | U = BF.features.(modalities{m}).U; 35 | if any(any(U-eye(size(U, 1)))) 36 | error('Projection to modes is not supported by this plug-in'); 37 | end 38 | 39 | chanind = D.indchannel(BF.inverse.(modalities{m}).channels); 40 | 41 | bad = badsamples(D, chanind, samples, 1); 42 | 43 | chngpnt = [1 find(any(diff(bad, [], 2)))]; 44 | 45 | nsegments = length(chngpnt); 46 | 47 | id = zeros(1, length(samples)); 48 | 49 | L = {}; 50 | 51 | ev = []; 52 | for i = 1:nsegments 53 | goodind = ~bad(:, chngpnt(i)); 54 | 55 | if i 100, Ibar = floor(linspace(1, length(uid),100)); 120 | else Ibar = 1:length(uid); end 121 | 122 | for i = 1:length(uid) 123 | goodind = ~bad(:, find(id==uid(i), 1, 'first')); 124 | Cy = C(goodind, goodind); 125 | invCy = pinv_plus(Cy); 126 | 127 | n = 1; 128 | for j = 1:length(ftdata.label) 129 | w = []; 130 | for k = 1:size(L{j}, 2) 131 | lf = L{j}(goodind, k); 132 | 133 | w = [w; lf'*invCy/(lf' * invCy * lf)]; 134 | end 135 | 136 | data(n:(n+size(w, 1)-1), id==uid(i)) = w*D(chanind(goodind), find(id==uid(i))); 137 | 138 | n = n+size(w, 1); 139 | end 140 | if ismember(i, Ibar) 141 | spm_progress_bar('Set', i); drawnow; 142 | end 143 | end 144 | 145 | spm_progress_bar('Clear'); 146 | 147 | ftdata.trial{1} = data; 148 | ftdata.time{1} = D.time(samples); 149 | ftdata.label = lbl; 150 | 151 | sourcedata_robust.(modalities{m}).ftdata = ftdata; 152 | sourcedata_robust.(modalities{m}).events = ev; 153 | end 154 | -------------------------------------------------------------------------------- /bf_pipeline_Champagne.m: -------------------------------------------------------------------------------- 1 | %----------------------------------------------------------------------- 2 | % Job saved on 04-Sep-2015 11:55:24 by cfg_util (rev $Rev: 6460 $) 3 | % spm SPM - SPM12 (12.1) 4 | % cfg_basicio BasicIO - Unknown 5 | %-----------------------------------------------------------------------# 6 | matlabbatch{1}.spm.tools.beamforming.data.val = 1; 7 | matlabbatch{1}.spm.tools.beamforming.data.gradsource = 'inv'; 8 | matlabbatch{1}.spm.tools.beamforming.data.space = 'MNI-aligned'; 9 | matlabbatch{1}.spm.tools.beamforming.data.overwrite = 0; 10 | matlabbatch{2}.spm.tools.beamforming.sources.BF(1) = cfg_dep('Prepare data: BF.mat file', substruct('.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 11 | matlabbatch{2}.spm.tools.beamforming.sources.reduce_rank = [2 3]; 12 | matlabbatch{2}.spm.tools.beamforming.sources.keep3d = 1; 13 | matlabbatch{2}.spm.tools.beamforming.sources.plugin.mesh.orient = 'unoriented'; 14 | matlabbatch{2}.spm.tools.beamforming.sources.plugin.mesh.fdownsample = 1; 15 | matlabbatch{2}.spm.tools.beamforming.sources.plugin.mesh.symmetric = 'no'; 16 | matlabbatch{2}.spm.tools.beamforming.sources.plugin.mesh.flip = false; 17 | matlabbatch{2}.spm.tools.beamforming.sources.visualise = 1; 18 | matlabbatch{3}.spm.tools.beamforming.features.BF(1) = cfg_dep('Define sources: BF.mat file', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 19 | matlabbatch{3}.spm.tools.beamforming.features.whatconditions.all = 1; 20 | matlabbatch{3}.spm.tools.beamforming.features.woi = [-100 0 21 | 100 200]; 22 | matlabbatch{3}.spm.tools.beamforming.features.modality = {'MEG'}; 23 | matlabbatch{3}.spm.tools.beamforming.features.fuse = 'no'; 24 | matlabbatch{3}.spm.tools.beamforming.features.plugin.vbfa.nl = 5; 25 | matlabbatch{3}.spm.tools.beamforming.features.plugin.vbfa.nem = 50; 26 | matlabbatch{3}.spm.tools.beamforming.features.regularisation.manual.lambda = 0; 27 | matlabbatch{3}.spm.tools.beamforming.features.bootstrap = false; 28 | matlabbatch{4}.spm.tools.beamforming.inverse.BF(1) = cfg_dep('Covariance features: BF.mat file', substruct('.','val', '{}',{3}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 29 | matlabbatch{4}.spm.tools.beamforming.inverse.plugin.champagne.nem = 100; 30 | matlabbatch{4}.spm.tools.beamforming.inverse.plugin.champagne.vcs = 0; 31 | matlabbatch{4}.spm.tools.beamforming.inverse.plugin.champagne.nupd = 0; 32 | matlabbatch{5}.spm.tools.beamforming.output.BF(1) = cfg_dep('Inverse solution: BF.mat file', substruct('.','val', '{}',{4}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 33 | matlabbatch{5}.spm.tools.beamforming.output.plugin.image_power.whatconditions.all = 1; 34 | matlabbatch{5}.spm.tools.beamforming.output.plugin.image_power.sametrials = false; 35 | matlabbatch{5}.spm.tools.beamforming.output.plugin.image_power.woi = [100 200]; 36 | matlabbatch{5}.spm.tools.beamforming.output.plugin.image_power.foi = [0 Inf]; 37 | matlabbatch{5}.spm.tools.beamforming.output.plugin.image_power.contrast = 1; 38 | matlabbatch{5}.spm.tools.beamforming.output.plugin.image_power.result = 'bycondition'; 39 | matlabbatch{5}.spm.tools.beamforming.output.plugin.image_power.scale = 0; 40 | matlabbatch{5}.spm.tools.beamforming.output.plugin.image_power.powermethod = 'trace'; 41 | matlabbatch{5}.spm.tools.beamforming.output.plugin.image_power.modality = 'MEG'; 42 | matlabbatch{6}.spm.tools.beamforming.write.BF(1) = cfg_dep('Output: BF.mat file', substruct('.','val', '{}',{5}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 43 | matlabbatch{6}.spm.tools.beamforming.write.plugin.gifti.normalise = 'all'; 44 | matlabbatch{6}.spm.tools.beamforming.write.plugin.gifti.space = 'mni'; 45 | matlabbatch{6}.spm.tools.beamforming.write.plugin.gifti.visualise = 2; 46 | -------------------------------------------------------------------------------- /bf_pipeline_DICS_coherence.m: -------------------------------------------------------------------------------- 1 | %----------------------------------------------------------------------- 2 | % Job saved on 08-Feb-2017 12:31:47 by cfg_util (rev $Rev: 6942 $) 3 | % spm SPM - SPM12 (12.3) 4 | % cfg_basicio BasicIO - Unknown 5 | %----------------------------------------------------------------------- 6 | matlabbatch{1}.spm.meeg.source.headmodel.D = ''; 7 | matlabbatch{1}.spm.meeg.source.headmodel.val = 1; 8 | matlabbatch{1}.spm.meeg.source.headmodel.comment = ''; 9 | matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshes.template = 1; 10 | matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshres = 2; 11 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).fidname = 'nas'; 12 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).specification.select = 'nas'; 13 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).fidname = 'lpa'; 14 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).specification.select = 'FIL_CTF_L'; 15 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).fidname = 'rpa'; 16 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).specification.select = 'FIL_CTF_R'; 17 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.useheadshape = 0; 18 | matlabbatch{1}.spm.meeg.source.headmodel.forward.eeg = 'EEG BEM'; 19 | matlabbatch{1}.spm.meeg.source.headmodel.forward.meg = 'Single Shell'; 20 | matlabbatch{2}.spm.tools.beamforming.data.dir = ''; 21 | matlabbatch{2}.spm.tools.beamforming.data.D(1) = cfg_dep('Head model specification: M/EEG dataset(s) with a forward model', substruct('.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','D')); 22 | matlabbatch{2}.spm.tools.beamforming.data.val = 1; 23 | matlabbatch{2}.spm.tools.beamforming.data.gradsource = 'inv'; 24 | matlabbatch{2}.spm.tools.beamforming.data.space = 'MNI-aligned'; 25 | matlabbatch{2}.spm.tools.beamforming.data.overwrite = 0; 26 | matlabbatch{3}.spm.tools.beamforming.sources.BF(1) = cfg_dep('Prepare data: BF.mat file', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 27 | matlabbatch{3}.spm.tools.beamforming.sources.reduce_rank = [2 3]; 28 | matlabbatch{3}.spm.tools.beamforming.sources.keep3d = 1; 29 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.grid.resolution = 10; 30 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.grid.space = 'MNI template'; 31 | matlabbatch{3}.spm.tools.beamforming.sources.visualise = 1; 32 | matlabbatch{4}.spm.tools.beamforming.features.BF(1) = cfg_dep('Define sources: BF.mat file', substruct('.','val', '{}',{3}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 33 | matlabbatch{4}.spm.tools.beamforming.features.whatconditions.all = 1; 34 | matlabbatch{4}.spm.tools.beamforming.features.woi = [-Inf Inf]; 35 | matlabbatch{4}.spm.tools.beamforming.features.modality = {'MEG'}; 36 | matlabbatch{4}.spm.tools.beamforming.features.fuse = 'no'; 37 | matlabbatch{4}.spm.tools.beamforming.features.plugin.csd.foi = ''; 38 | matlabbatch{4}.spm.tools.beamforming.features.plugin.csd.taper = 'dpss'; 39 | matlabbatch{4}.spm.tools.beamforming.features.plugin.csd.keepreal = 0; 40 | matlabbatch{4}.spm.tools.beamforming.features.plugin.csd.hanning = 0; 41 | matlabbatch{4}.spm.tools.beamforming.features.regularisation.manual.lambda = 5; 42 | matlabbatch{4}.spm.tools.beamforming.features.bootstrap = false; 43 | matlabbatch{5}.spm.tools.beamforming.inverse.BF(1) = cfg_dep('Covariance features: BF.mat file', substruct('.','val', '{}',{4}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 44 | matlabbatch{5}.spm.tools.beamforming.inverse.plugin.dics.fixedori = 'yes'; 45 | matlabbatch{6}.spm.tools.beamforming.output.BF(1) = cfg_dep('Inverse solution: BF.mat file', substruct('.','val', '{}',{5}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 46 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.reference.refchan.name = ''; 47 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.reference.refchan.shuffle = 0; 48 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.powmethod = 'lambda1'; 49 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.whatconditions.all = 1; 50 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.sametrials = false; 51 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.woi = [-Inf Inf]; 52 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.contrast = 1; 53 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.logpower = false; 54 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.foi = ''; 55 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.taper = 'dpss'; 56 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.result = 'singleimage'; 57 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.scale = 'no'; 58 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.modality = 'MEG'; 59 | matlabbatch{7}.spm.tools.beamforming.write.BF(1) = cfg_dep('Output: BF.mat file', substruct('.','val', '{}',{6}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 60 | matlabbatch{7}.spm.tools.beamforming.write.plugin.nifti.normalise = 'separate'; 61 | matlabbatch{7}.spm.tools.beamforming.write.plugin.nifti.space = 'mni'; 62 | -------------------------------------------------------------------------------- /bf_pipeline_DICS_power.m: -------------------------------------------------------------------------------- 1 | %----------------------------------------------------------------------- 2 | % Job saved on 08-Feb-2017 12:29:28 by cfg_util (rev $Rev: 6942 $) 3 | % spm SPM - SPM12 (12.3) 4 | % cfg_basicio BasicIO - Unknown 5 | %----------------------------------------------------------------------- 6 | matlabbatch{1}.spm.meeg.source.headmodel.D = ''; 7 | matlabbatch{1}.spm.meeg.source.headmodel.val = 1; 8 | matlabbatch{1}.spm.meeg.source.headmodel.comment = ''; 9 | matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshes.template = 1; 10 | matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshres = 2; 11 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).fidname = 'nas'; 12 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).specification.select = 'nas'; 13 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).fidname = 'lpa'; 14 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).specification.select = 'FIL_CTF_L'; 15 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).fidname = 'rpa'; 16 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).specification.select = 'FIL_CTF_R'; 17 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.useheadshape = 0; 18 | matlabbatch{1}.spm.meeg.source.headmodel.forward.eeg = 'EEG BEM'; 19 | matlabbatch{1}.spm.meeg.source.headmodel.forward.meg = 'Single Shell'; 20 | matlabbatch{2}.spm.tools.beamforming.data.dir = ''; 21 | matlabbatch{2}.spm.tools.beamforming.data.D(1) = cfg_dep('Head model specification: M/EEG dataset(s) with a forward model', substruct('.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','D')); 22 | matlabbatch{2}.spm.tools.beamforming.data.val = 1; 23 | matlabbatch{2}.spm.tools.beamforming.data.gradsource = 'inv'; 24 | matlabbatch{2}.spm.tools.beamforming.data.space = 'MNI-aligned'; 25 | matlabbatch{2}.spm.tools.beamforming.data.overwrite = 0; 26 | matlabbatch{3}.spm.tools.beamforming.sources.BF(1) = cfg_dep('Prepare data: BF.mat file', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 27 | matlabbatch{3}.spm.tools.beamforming.sources.reduce_rank = [2 3]; 28 | matlabbatch{3}.spm.tools.beamforming.sources.keep3d = 1; 29 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.grid.resolution = 10; 30 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.grid.space = 'MNI template'; 31 | matlabbatch{3}.spm.tools.beamforming.sources.visualise = 1; 32 | matlabbatch{4}.spm.tools.beamforming.features.BF(1) = cfg_dep('Define sources: BF.mat file', substruct('.','val', '{}',{3}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 33 | matlabbatch{4}.spm.tools.beamforming.features.whatconditions.all = 1; 34 | matlabbatch{4}.spm.tools.beamforming.features.woi = [-Inf Inf]; 35 | matlabbatch{4}.spm.tools.beamforming.features.modality = {'MEG'}; 36 | matlabbatch{4}.spm.tools.beamforming.features.fuse = 'no'; 37 | matlabbatch{4}.spm.tools.beamforming.features.plugin.csd.foi = ''; 38 | matlabbatch{4}.spm.tools.beamforming.features.plugin.csd.taper = 'dpss'; 39 | matlabbatch{4}.spm.tools.beamforming.features.plugin.csd.keepreal = 0; 40 | matlabbatch{4}.spm.tools.beamforming.features.plugin.csd.hanning = 0; 41 | matlabbatch{4}.spm.tools.beamforming.features.regularisation.manual.lambda = 5; 42 | matlabbatch{4}.spm.tools.beamforming.features.bootstrap = false; 43 | matlabbatch{5}.spm.tools.beamforming.inverse.BF(1) = cfg_dep('Covariance features: BF.mat file', substruct('.','val', '{}',{4}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 44 | matlabbatch{5}.spm.tools.beamforming.inverse.plugin.dics.fixedori = 'yes'; 45 | matlabbatch{6}.spm.tools.beamforming.output.BF(1) = cfg_dep('Inverse solution: BF.mat file', substruct('.','val', '{}',{5}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 46 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.reference.power = 1; 47 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.powmethod = 'lambda1'; 48 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.whatconditions.all = 1; 49 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.sametrials = false; 50 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.woi = [-Inf Inf]; 51 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.contrast = 1; 52 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.logpower = false; 53 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.foi = ''; 54 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.taper = 'dpss'; 55 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.result = 'singleimage'; 56 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.scale = 'yes'; 57 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_dics.modality = 'MEG'; 58 | matlabbatch{7}.spm.tools.beamforming.write.BF(1) = cfg_dep('Output: BF.mat file', substruct('.','val', '{}',{6}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 59 | matlabbatch{7}.spm.tools.beamforming.write.plugin.nifti.normalise = 'separate'; 60 | matlabbatch{7}.spm.tools.beamforming.write.plugin.nifti.space = 'mni'; 61 | -------------------------------------------------------------------------------- /bf_pipeline_GALA.m: -------------------------------------------------------------------------------- 1 | %----------------------------------------------------------------------- 2 | % Job saved on 27-Nov-2015 18:36:22 by cfg_util (rev $Rev: 6460 $) 3 | % spm SPM - SPM12 (12.1) 4 | % cfg_basicio BasicIO - Unknown 5 | %----------------------------------------------------------------------- 6 | matlabbatch{1}.spm.tools.beamforming.group.BF = ''; 7 | matlabbatch{1}.spm.tools.beamforming.group.prefix = ''; 8 | matlabbatch{1}.spm.tools.beamforming.group.plugin.batch.batchfile = {'C:\spm12\toolbox\DAiSS\batch_group_GALA_data_sources.m'}; 9 | matlabbatch{2}.spm.tools.beamforming.group.BF(1) = cfg_dep('Group analysis: BF.mat files', substruct('.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 10 | matlabbatch{2}.spm.tools.beamforming.group.prefix = ''; 11 | matlabbatch{2}.spm.tools.beamforming.group.plugin.GALA.iter = 3; 12 | matlabbatch{3}.spm.tools.beamforming.group.BF(1) = cfg_dep('Group analysis: BF.mat files', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 13 | matlabbatch{3}.spm.tools.beamforming.group.prefix = ''; 14 | matlabbatch{3}.spm.tools.beamforming.group.plugin.functionalROI.measure = 'lJcov'; 15 | matlabbatch{3}.spm.tools.beamforming.group.plugin.functionalROI.spread = 4; 16 | matlabbatch{3}.spm.tools.beamforming.group.plugin.functionalROI.threshold = 0.01; 17 | matlabbatch{3}.spm.tools.beamforming.group.plugin.functionalROI.mincorr = 0.7; 18 | matlabbatch{3}.spm.tools.beamforming.group.plugin.functionalROI.maxsize = 50; 19 | matlabbatch{3}.spm.tools.beamforming.group.plugin.functionalROI.distratio1 = 4; 20 | matlabbatch{3}.spm.tools.beamforming.group.plugin.functionalROI.distratio2 = 2; 21 | matlabbatch{3}.spm.tools.beamforming.group.plugin.functionalROI.cluster.maxclust.maxclustsize = 30; 22 | matlabbatch{3}.spm.tools.beamforming.group.plugin.functionalROI.linkmeth = 'complete'; 23 | matlabbatch{3}.spm.tools.beamforming.group.plugin.functionalROI.similarity = 0; 24 | matlabbatch{4}.spm.tools.beamforming.group.BF(1) = cfg_dep('Group analysis: BF.mat files', substruct('.','val', '{}',{3}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 25 | matlabbatch{4}.spm.tools.beamforming.group.prefix = ''; 26 | matlabbatch{4}.spm.tools.beamforming.group.plugin.batch.batchfile = {'C:\spm12\toolbox\DAiSS\batch_group_GALA_write.m'}; -------------------------------------------------------------------------------- /bf_pipeline_LCMV_all_mesh_sources.m: -------------------------------------------------------------------------------- 1 | %----------------------------------------------------------------------- 2 | % Job saved on 08-Feb-2017 12:33:41 by cfg_util (rev $Rev: 6942 $) 3 | % spm SPM - SPM12 (12.3) 4 | % cfg_basicio BasicIO - Unknown 5 | %----------------------------------------------------------------------- 6 | matlabbatch{1}.spm.meeg.source.headmodel.D = ''; 7 | matlabbatch{1}.spm.meeg.source.headmodel.val = 1; 8 | matlabbatch{1}.spm.meeg.source.headmodel.comment = ''; 9 | matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshes.template = 1; 10 | matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshres = 2; 11 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).fidname = 'nas'; 12 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).specification.select = 'nas'; 13 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).fidname = 'lpa'; 14 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).specification.select = 'lpa'; 15 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).fidname = 'rpa'; 16 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).specification.select = 'rpa'; 17 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.useheadshape = 0; 18 | matlabbatch{1}.spm.meeg.source.headmodel.forward.eeg = 'EEG BEM'; 19 | matlabbatch{1}.spm.meeg.source.headmodel.forward.meg = 'Single Shell'; 20 | matlabbatch{2}.spm.tools.beamforming.data.dir = ''; 21 | matlabbatch{2}.spm.tools.beamforming.data.D(1) = cfg_dep('M/EEG head model specification: M/EEG dataset(s) with a forward model', substruct('.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','D')); 22 | matlabbatch{2}.spm.tools.beamforming.data.val = 1; 23 | matlabbatch{2}.spm.tools.beamforming.data.gradsource = 'inv'; 24 | matlabbatch{2}.spm.tools.beamforming.data.space = 'MNI-aligned'; 25 | matlabbatch{2}.spm.tools.beamforming.data.overwrite = 1; 26 | matlabbatch{3}.spm.tools.beamforming.sources.BF(1) = cfg_dep('Prepare data: BF.mat file', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 27 | matlabbatch{3}.spm.tools.beamforming.sources.reduce_rank = [2 3]; 28 | matlabbatch{3}.spm.tools.beamforming.sources.keep3d = 1; 29 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.mesh.orient = 'original'; 30 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.mesh.fdownsample = 1; 31 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.mesh.symmetric = 'no'; 32 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.mesh.flip = false; 33 | matlabbatch{3}.spm.tools.beamforming.sources.visualise = 1; 34 | matlabbatch{4}.spm.tools.beamforming.features.BF(1) = cfg_dep('Define sources: BF.mat file', substruct('.','val', '{}',{3}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 35 | matlabbatch{4}.spm.tools.beamforming.features.whatconditions.all = 1; 36 | matlabbatch{4}.spm.tools.beamforming.features.woi = [-Inf Inf]; 37 | matlabbatch{4}.spm.tools.beamforming.features.modality = {'MEG'}; 38 | matlabbatch{4}.spm.tools.beamforming.features.fuse = 'no'; 39 | matlabbatch{4}.spm.tools.beamforming.features.plugin.cov.foi = [0 Inf]; 40 | matlabbatch{4}.spm.tools.beamforming.features.plugin.cov.taper = 'none'; 41 | matlabbatch{4}.spm.tools.beamforming.features.regularisation.manual.lambda = 5; 42 | matlabbatch{4}.spm.tools.beamforming.features.bootstrap = false; 43 | matlabbatch{5}.spm.tools.beamforming.inverse.BF(1) = cfg_dep('Covariance features: BF.mat file', substruct('.','val', '{}',{4}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 44 | matlabbatch{5}.spm.tools.beamforming.inverse.plugin.lcmv.orient = true; 45 | matlabbatch{5}.spm.tools.beamforming.inverse.plugin.lcmv.keeplf = false; 46 | matlabbatch{6}.spm.tools.beamforming.output.BF(1) = cfg_dep('Inverse solution: BF.mat file', substruct('.','val', '{}',{5}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 47 | matlabbatch{6}.spm.tools.beamforming.output.plugin.montage.method = 'keep'; 48 | matlabbatch{6}.spm.tools.beamforming.output.plugin.montage.vois = {}; 49 | matlabbatch{7}.spm.tools.beamforming.write.BF(1) = cfg_dep('Output: BF.mat file', substruct('.','val', '{}',{6}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 50 | matlabbatch{7}.spm.tools.beamforming.write.plugin.spmeeg.mode = 'onlinecopy'; 51 | matlabbatch{7}.spm.tools.beamforming.write.plugin.spmeeg.modality = 'MEG'; 52 | matlabbatch{7}.spm.tools.beamforming.write.plugin.spmeeg.addchannels.none = 0; 53 | matlabbatch{7}.spm.tools.beamforming.write.plugin.spmeeg.prefix = 'B'; 54 | -------------------------------------------------------------------------------- /bf_pipeline_LCMV_imaging.m: -------------------------------------------------------------------------------- 1 | %----------------------------------------------------------------------- 2 | % Job saved on 08-Feb-2017 12:32:51 by cfg_util (rev $Rev: 6942 $) 3 | % spm SPM - SPM12 (12.3) 4 | % cfg_basicio BasicIO - Unknown 5 | %----------------------------------------------------------------------- 6 | matlabbatch{1}.spm.meeg.source.headmodel.D = {''}; 7 | matlabbatch{1}.spm.meeg.source.headmodel.val = 1; 8 | matlabbatch{1}.spm.meeg.source.headmodel.comment = ''; 9 | matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshes.template = 1; 10 | matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshres = 2; 11 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).fidname = 'nas'; 12 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).specification.select = 'nas'; 13 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).fidname = 'lpa'; 14 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).specification.select = 'FIL_CTF_L'; 15 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).fidname = 'rpa'; 16 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).specification.select = 'FIL_CTF_R'; 17 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.useheadshape = 0; 18 | matlabbatch{1}.spm.meeg.source.headmodel.forward.eeg = 'EEG BEM'; 19 | matlabbatch{1}.spm.meeg.source.headmodel.forward.meg = 'Single Shell'; 20 | matlabbatch{2}.spm.tools.beamforming.data.dir = ''; 21 | matlabbatch{2}.spm.tools.beamforming.data.D(1) = cfg_dep('M/EEG head model specification: M/EEG dataset(s) with a forward model', substruct('.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','D')); 22 | matlabbatch{2}.spm.tools.beamforming.data.val = 1; 23 | matlabbatch{2}.spm.tools.beamforming.data.gradsource = 'inv'; 24 | matlabbatch{2}.spm.tools.beamforming.data.space = 'MNI-aligned'; 25 | matlabbatch{2}.spm.tools.beamforming.data.overwrite = 0; 26 | matlabbatch{3}.spm.tools.beamforming.sources.BF(1) = cfg_dep('Prepare data: BF.mat file', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 27 | matlabbatch{3}.spm.tools.beamforming.sources.reduce_rank = [2 3]; 28 | matlabbatch{3}.spm.tools.beamforming.sources.keep3d = 1; 29 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.grid.resolution = 5; 30 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.grid.space = 'MNI template'; 31 | matlabbatch{3}.spm.tools.beamforming.sources.visualise = 1; 32 | matlabbatch{4}.spm.tools.beamforming.features.BF(1) = cfg_dep('Define sources: BF.mat file', substruct('.','val', '{}',{3}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 33 | matlabbatch{4}.spm.tools.beamforming.features.whatconditions.all = 1; 34 | matlabbatch{4}.spm.tools.beamforming.features.woi = [-Inf Inf]; 35 | matlabbatch{4}.spm.tools.beamforming.features.modality = {'MEG'}; 36 | matlabbatch{4}.spm.tools.beamforming.features.fuse = 'no'; 37 | matlabbatch{4}.spm.tools.beamforming.features.plugin.cov.foi = [0 Inf]; 38 | matlabbatch{4}.spm.tools.beamforming.features.plugin.cov.taper = 'none'; 39 | matlabbatch{4}.spm.tools.beamforming.features.regularisation.manual.lambda = 5; 40 | matlabbatch{4}.spm.tools.beamforming.features.bootstrap = false; 41 | matlabbatch{5}.spm.tools.beamforming.inverse.BF(1) = cfg_dep('Covariance features: BF.mat file', substruct('.','val', '{}',{4}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 42 | matlabbatch{5}.spm.tools.beamforming.inverse.plugin.lcmv.orient = true; 43 | matlabbatch{5}.spm.tools.beamforming.inverse.plugin.lcmv.keeplf = false; 44 | matlabbatch{6}.spm.tools.beamforming.output.BF(1) = cfg_dep('Inverse solution: BF.mat file', substruct('.','val', '{}',{5}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 45 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.whatconditions.all = 1; 46 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.sametrials = false; 47 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.woi = [-Inf Inf]; 48 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.foi = ''; 49 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.contrast = 1; 50 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.logpower = false; 51 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.result = 'singleimage'; 52 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.scale = 1; 53 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.powermethod = 'trace'; 54 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.modality = 'MEG'; 55 | matlabbatch{7}.spm.tools.beamforming.write.BF(1) = cfg_dep('Output: BF.mat file', substruct('.','val', '{}',{6}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 56 | matlabbatch{7}.spm.tools.beamforming.write.plugin.nifti.normalise = 'separate'; 57 | matlabbatch{7}.spm.tools.beamforming.write.plugin.nifti.space = 'mni'; 58 | -------------------------------------------------------------------------------- /bf_pipeline_LCMV_source_extraction.m: -------------------------------------------------------------------------------- 1 | %----------------------------------------------------------------------- 2 | % Job saved on 08-Feb-2017 12:34:54 by cfg_util (rev $Rev: 6942 $) 3 | % spm SPM - SPM12 (12.3) 4 | % cfg_basicio BasicIO - Unknown 5 | %----------------------------------------------------------------------- 6 | matlabbatch{1}.spm.meeg.source.headmodel.D = {''}; 7 | matlabbatch{1}.spm.meeg.source.headmodel.val = 1; 8 | matlabbatch{1}.spm.meeg.source.headmodel.comment = ''; 9 | matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshes.template = 1; 10 | matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshres = 2; 11 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).fidname = 'nas'; 12 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).specification.select = 'nas'; 13 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).fidname = 'lpa'; 14 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).specification.select = 'FIL_CTF_L'; 15 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).fidname = 'rpa'; 16 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).specification.select = 'FIL_CTF_R'; 17 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.useheadshape = 0; 18 | matlabbatch{1}.spm.meeg.source.headmodel.forward.eeg = 'EEG BEM'; 19 | matlabbatch{1}.spm.meeg.source.headmodel.forward.meg = 'Single Shell'; 20 | matlabbatch{2}.spm.tools.beamforming.data.dir = ''; 21 | matlabbatch{2}.spm.tools.beamforming.data.D(1) = cfg_dep('M/EEG head model specification: M/EEG dataset(s) with a forward model', substruct('.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','D')); 22 | matlabbatch{2}.spm.tools.beamforming.data.val = 1; 23 | matlabbatch{2}.spm.tools.beamforming.data.gradsource = 'inv'; 24 | matlabbatch{2}.spm.tools.beamforming.data.space = 'MNI-aligned'; 25 | matlabbatch{2}.spm.tools.beamforming.data.overwrite = 0; 26 | matlabbatch{3}.spm.tools.beamforming.sources.BF(1) = cfg_dep('Prepare data: BF.mat file', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 27 | matlabbatch{3}.spm.tools.beamforming.sources.reduce_rank = [2 3]; 28 | matlabbatch{3}.spm.tools.beamforming.sources.keep3d = 1; 29 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.voi.vois{1}.voidef.label = ''; 30 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.voi.vois{1}.voidef.pos = ''; 31 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.voi.vois{1}.voidef.ori = [0 0 0]; 32 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.voi.radius = 0; 33 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.voi.resolution = 5; 34 | matlabbatch{3}.spm.tools.beamforming.sources.visualise = 1; 35 | matlabbatch{4}.spm.tools.beamforming.features.BF(1) = cfg_dep('Define sources: BF.mat file', substruct('.','val', '{}',{3}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 36 | matlabbatch{4}.spm.tools.beamforming.features.whatconditions.all = 1; 37 | matlabbatch{4}.spm.tools.beamforming.features.woi = [-Inf Inf]; 38 | matlabbatch{4}.spm.tools.beamforming.features.modality = {'MEG'}; 39 | matlabbatch{4}.spm.tools.beamforming.features.fuse = 'no'; 40 | matlabbatch{4}.spm.tools.beamforming.features.plugin.cov.foi = [0 Inf]; 41 | matlabbatch{4}.spm.tools.beamforming.features.plugin.cov.taper = 'none'; 42 | matlabbatch{4}.spm.tools.beamforming.features.regularisation.manual.lambda = 5; 43 | matlabbatch{4}.spm.tools.beamforming.features.bootstrap = false; 44 | matlabbatch{5}.spm.tools.beamforming.inverse.BF(1) = cfg_dep('Covariance features: BF.mat file', substruct('.','val', '{}',{4}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 45 | matlabbatch{5}.spm.tools.beamforming.inverse.plugin.lcmv.orient = true; 46 | matlabbatch{5}.spm.tools.beamforming.inverse.plugin.lcmv.keeplf = false; 47 | matlabbatch{6}.spm.tools.beamforming.output.BF(1) = cfg_dep('Inverse solution: BF.mat file', substruct('.','val', '{}',{5}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 48 | matlabbatch{6}.spm.tools.beamforming.output.plugin.montage.method = 'max'; 49 | matlabbatch{6}.spm.tools.beamforming.output.plugin.montage.vois = {}; 50 | matlabbatch{7}.spm.tools.beamforming.write.BF(1) = cfg_dep('Output: BF.mat file', substruct('.','val', '{}',{6}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 51 | matlabbatch{7}.spm.tools.beamforming.write.plugin.spmeeg.mode = 'write'; 52 | matlabbatch{7}.spm.tools.beamforming.write.plugin.spmeeg.modality = 'MEG'; 53 | matlabbatch{7}.spm.tools.beamforming.write.plugin.spmeeg.addchannels.none = 0; 54 | matlabbatch{7}.spm.tools.beamforming.write.plugin.spmeeg.prefix = 'B'; 55 | -------------------------------------------------------------------------------- /bf_pipeline_MVAR_activation_vs_baseline.m: -------------------------------------------------------------------------------- 1 | %----------------------------------------------------------------------- 2 | % Job saved on 08-Feb-2017 12:35:41 by cfg_util (rev $Rev: 6942 $) 3 | % spm SPM - SPM12 (12.3) 4 | % cfg_basicio BasicIO - Unknown 5 | %----------------------------------------------------------------------- 6 | matlabbatch{1}.spm.meeg.source.headmodel.D = {''}; 7 | matlabbatch{1}.spm.meeg.source.headmodel.val = 1; 8 | matlabbatch{1}.spm.meeg.source.headmodel.comment = ''; 9 | matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshes.template = 1; 10 | matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshres = 2; 11 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).fidname = 'nas'; 12 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).specification.select = 'nas'; 13 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).fidname = 'lpa'; 14 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).specification.select = 'FIL_CTF_L'; 15 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).fidname = 'rpa'; 16 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).specification.select = 'FIL_CTF_R'; 17 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.useheadshape = 0; 18 | matlabbatch{1}.spm.meeg.source.headmodel.forward.eeg = 'EEG BEM'; 19 | matlabbatch{1}.spm.meeg.source.headmodel.forward.meg = 'Single Shell'; 20 | matlabbatch{2}.spm.tools.beamforming.data.dir = ''; 21 | matlabbatch{2}.spm.tools.beamforming.data.D(1) = cfg_dep('Head model specification: M/EEG dataset(s) with a forward model', substruct('.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','D')); 22 | matlabbatch{2}.spm.tools.beamforming.data.val = 1; 23 | matlabbatch{2}.spm.tools.beamforming.data.gradsource = 'inv'; 24 | matlabbatch{2}.spm.tools.beamforming.data.space = 'MNI-aligned'; 25 | matlabbatch{2}.spm.tools.beamforming.data.overwrite = 0; 26 | matlabbatch{3}.spm.tools.beamforming.sources.BF(1) = cfg_dep('Prepare data: BF.mat file', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 27 | matlabbatch{3}.spm.tools.beamforming.sources.reduce_rank = [2 3]; 28 | matlabbatch{3}.spm.tools.beamforming.sources.keep3d = 1; 29 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.grid.resolution = 10; 30 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.grid.space = 'MNI template'; 31 | matlabbatch{3}.spm.tools.beamforming.sources.visualise = 1; 32 | matlabbatch{4}.spm.tools.beamforming.features.BF(1) = cfg_dep('Define sources: BF.mat file', substruct('.','val', '{}',{3}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 33 | matlabbatch{4}.spm.tools.beamforming.features.whatconditions.all = 1; 34 | matlabbatch{4}.spm.tools.beamforming.features.woi = [-Inf Inf]; 35 | matlabbatch{4}.spm.tools.beamforming.features.modality = {'MEG'}; 36 | matlabbatch{4}.spm.tools.beamforming.features.fuse = 'no'; 37 | matlabbatch{4}.spm.tools.beamforming.features.plugin.cov.foi = [0 100]; 38 | matlabbatch{4}.spm.tools.beamforming.features.plugin.cov.taper = 'none'; 39 | matlabbatch{4}.spm.tools.beamforming.features.regularisation.manual.lambda = 5; 40 | matlabbatch{4}.spm.tools.beamforming.features.bootstrap = false; 41 | matlabbatch{5}.spm.tools.beamforming.inverse.BF(1) = cfg_dep('Covariance features: BF.mat file', substruct('.','val', '{}',{4}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 42 | matlabbatch{5}.spm.tools.beamforming.inverse.plugin.lcmv.orient = true; 43 | matlabbatch{5}.spm.tools.beamforming.inverse.plugin.lcmv.keeplf = false; 44 | matlabbatch{6}.spm.tools.beamforming.output.BF(1) = cfg_dep('Inverse solution: BF.mat file', substruct('.','val', '{}',{5}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 45 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.isdesign.custom.whatconditions.all = 1; 46 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.isdesign.custom.contrast = [-1 1]; 47 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.isdesign.custom.woi = [-100 0 48 | 100 200]; 49 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.datafeatures = 'sumpower'; 50 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.foi = [5 15 51 | 15 30 52 | 30 60 53 | 60 90]; 54 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.result = 'BIC'; 55 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.sametrials = false; 56 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.modality = 'MEG'; 57 | matlabbatch{7}.spm.tools.beamforming.write.BF(1) = cfg_dep('Output: BF.mat file', substruct('.','val', '{}',{6}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 58 | matlabbatch{7}.spm.tools.beamforming.write.plugin.nifti.normalise = 'no'; 59 | matlabbatch{7}.spm.tools.beamforming.write.plugin.nifti.space = 'mni'; 60 | -------------------------------------------------------------------------------- /bf_pipeline_MVAR_two_conditions.m: -------------------------------------------------------------------------------- 1 | %----------------------------------------------------------------------- 2 | % Job saved on 08-Feb-2017 12:38:53 by cfg_util (rev $Rev: 6942 $) 3 | % spm SPM - SPM12 (12.3) 4 | % cfg_basicio BasicIO - Unknown 5 | %----------------------------------------------------------------------- 6 | matlabbatch{1}.spm.meeg.source.headmodel.D = {''}; 7 | matlabbatch{1}.spm.meeg.source.headmodel.val = 1; 8 | matlabbatch{1}.spm.meeg.source.headmodel.comment = ''; 9 | matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshes.template = 1; 10 | matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshres = 2; 11 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).fidname = 'nas'; 12 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).specification.select = 'nas'; 13 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).fidname = 'lpa'; 14 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).specification.select = 'FIL_CTF_L'; 15 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).fidname = 'rpa'; 16 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).specification.select = 'FIL_CTF_R'; 17 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.useheadshape = 0; 18 | matlabbatch{1}.spm.meeg.source.headmodel.forward.eeg = 'EEG BEM'; 19 | matlabbatch{1}.spm.meeg.source.headmodel.forward.meg = 'Single Shell'; 20 | matlabbatch{2}.spm.tools.beamforming.data.dir = ''; 21 | matlabbatch{2}.spm.tools.beamforming.data.D(1) = cfg_dep('Head model specification: M/EEG dataset(s) with a forward model', substruct('.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','D')); 22 | matlabbatch{2}.spm.tools.beamforming.data.val = 1; 23 | matlabbatch{2}.spm.tools.beamforming.data.gradsource = 'inv'; 24 | matlabbatch{2}.spm.tools.beamforming.data.space = 'MNI-aligned'; 25 | matlabbatch{2}.spm.tools.beamforming.data.overwrite = 0; 26 | matlabbatch{3}.spm.tools.beamforming.sources.BF(1) = cfg_dep('Prepare data: BF.mat file', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 27 | matlabbatch{3}.spm.tools.beamforming.sources.reduce_rank = [2 3]; 28 | matlabbatch{3}.spm.tools.beamforming.sources.keep3d = 1; 29 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.grid.resolution = 10; 30 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.grid.space = 'MNI template'; 31 | matlabbatch{3}.spm.tools.beamforming.sources.visualise = 1; 32 | matlabbatch{4}.spm.tools.beamforming.features.BF(1) = cfg_dep('Define sources: BF.mat file', substruct('.','val', '{}',{3}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 33 | matlabbatch{4}.spm.tools.beamforming.features.whatconditions.all = 1; 34 | matlabbatch{4}.spm.tools.beamforming.features.woi = [-Inf Inf]; 35 | matlabbatch{4}.spm.tools.beamforming.features.modality = {'MEG'}; 36 | matlabbatch{4}.spm.tools.beamforming.features.fuse = 'no'; 37 | matlabbatch{4}.spm.tools.beamforming.features.plugin.cov.foi = [0 100]; 38 | matlabbatch{4}.spm.tools.beamforming.features.plugin.cov.taper = 'none'; 39 | matlabbatch{4}.spm.tools.beamforming.features.regularisation.manual.lambda = 5; 40 | matlabbatch{4}.spm.tools.beamforming.features.bootstrap = false; 41 | matlabbatch{5}.spm.tools.beamforming.inverse.BF(1) = cfg_dep('Covariance features: BF.mat file', substruct('.','val', '{}',{4}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 42 | matlabbatch{5}.spm.tools.beamforming.inverse.plugin.lcmv.orient = true; 43 | matlabbatch{5}.spm.tools.beamforming.inverse.plugin.lcmv.keeplf = false; 44 | matlabbatch{6}.spm.tools.beamforming.output.BF(1) = cfg_dep('Inverse solution: BF.mat file', substruct('.','val', '{}',{5}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 45 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.isdesign.custom.whatconditions.all = 1; 46 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.isdesign.custom.contrast = [-1 1]; 47 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.isdesign.custom.woi = [-100 0 48 | 100 200]; 49 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.datafeatures = 'sumpower'; 50 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.foi = [5 15 51 | 15 30 52 | 30 60 53 | 60 90]; 54 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.result = 'BIC'; 55 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.sametrials = false; 56 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.modality = 'MEG'; 57 | matlabbatch{7}.spm.tools.beamforming.write.BF(1) = cfg_dep('Output: BF.mat file', substruct('.','val', '{}',{6}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 58 | matlabbatch{7}.spm.tools.beamforming.write.plugin.nifti.normalise = 'no'; 59 | matlabbatch{7}.spm.tools.beamforming.write.plugin.nifti.space = 'mni'; 60 | -------------------------------------------------------------------------------- /bf_pipeline_Minimum_Norm.m: -------------------------------------------------------------------------------- 1 | %----------------------------------------------------------------------- 2 | % Job saved on 02-Apr-2014 13:13:09 by cfg_util (rev $Rev$) 3 | % spm SPM - SPM12b (beta) 4 | % cfg_basicio BasicIO - Unknown 5 | %----------------------------------------------------------------------- 6 | matlabbatch{1}.spm.meeg.source.headmodel.D = ''; 7 | matlabbatch{1}.spm.meeg.source.headmodel.val = 1; 8 | matlabbatch{1}.spm.meeg.source.headmodel.comment = ''; 9 | matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshes.template = 1; 10 | matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshres = 2; 11 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).fidname = ''; 12 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).specification = ''; 13 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).fidname = ''; 14 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).specification = ''; 15 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).fidname = ''; 16 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).specification = ''; 17 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.useheadshape = 0; 18 | matlabbatch{1}.spm.meeg.source.headmodel.forward.eeg = 'EEG BEM'; 19 | matlabbatch{1}.spm.meeg.source.headmodel.forward.meg = 'Single Shell'; 20 | matlabbatch{2}.spm.tools.beamforming.data.dir = ''; 21 | matlabbatch{2}.spm.tools.beamforming.data.D(1) = cfg_dep('M/EEG head model specification: M/EEG dataset(s) with a forward model', substruct('.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','D')); 22 | matlabbatch{2}.spm.tools.beamforming.data.val = 1; 23 | matlabbatch{2}.spm.tools.beamforming.data.gradsource = 'inv'; 24 | matlabbatch{2}.spm.tools.beamforming.data.space = 'MNI-aligned'; 25 | matlabbatch{2}.spm.tools.beamforming.data.overwrite = 1; 26 | matlabbatch{3}.spm.tools.beamforming.sources.BF(1) = cfg_dep('Prepare data: BF.mat file', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 27 | matlabbatch{3}.spm.tools.beamforming.sources.reduce_rank = [2 3]; 28 | matlabbatch{3}.spm.tools.beamforming.sources.keep3d = 1; 29 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.mesh.orient = 'original'; 30 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.mesh.fdownsample = 1; 31 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.mesh.flip = false; 32 | matlabbatch{3}.spm.tools.beamforming.sources.visualise = 1; 33 | matlabbatch{4}.spm.tools.beamforming.features.BF(1) = cfg_dep('Define sources: BF.mat file', substruct('.','val', '{}',{3}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 34 | matlabbatch{4}.spm.tools.beamforming.features.whatconditions.all = 1; 35 | matlabbatch{4}.spm.tools.beamforming.features.woi = [-Inf Inf]; 36 | matlabbatch{4}.spm.tools.beamforming.features.modality = {'MEG'}; 37 | matlabbatch{4}.spm.tools.beamforming.features.fuse = 'no'; 38 | matlabbatch{4}.spm.tools.beamforming.features.plugin.cov.foi = [0 Inf]; 39 | matlabbatch{4}.spm.tools.beamforming.features.plugin.cov.taper = 'none'; 40 | matlabbatch{4}.spm.tools.beamforming.features.regularisation.manual.lambda = 0; 41 | matlabbatch{4}.spm.tools.beamforming.features.bootstrap = false; 42 | matlabbatch{5}.spm.tools.beamforming.inverse.BF(1) = cfg_dep('Covariance features: BF.mat file', substruct('.','val', '{}',{4}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 43 | matlabbatch{5}.spm.tools.beamforming.inverse.plugin.minimumnorm.snr = 5; 44 | matlabbatch{5}.spm.tools.beamforming.inverse.plugin.minimumnorm.trunc = 0; 45 | matlabbatch{6}.spm.tools.beamforming.output.BF(1) = cfg_dep('Inverse solution: BF.mat file', substruct('.','val', '{}',{5}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 46 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.whatconditions.all = 1; 47 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.sametrials = false; 48 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.woi = [-Inf Inf]; 49 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.contrast = 1; 50 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.result = 'singleimage'; 51 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.scale = 0; 52 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.powermethod = 'trace'; 53 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.modality = 'MEG'; 54 | matlabbatch{7}.spm.tools.beamforming.write.BF(1) = cfg_dep('Output: BF.mat file', substruct('.','val', '{}',{6}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 55 | matlabbatch{7}.spm.tools.beamforming.write.plugin.gifti.normalise = 'no'; 56 | matlabbatch{7}.spm.tools.beamforming.write.plugin.gifti.space = 'mni'; 57 | matlabbatch{7}.spm.tools.beamforming.write.plugin.gifti.visualise = 2; 58 | -------------------------------------------------------------------------------- /bf_pipeline_eLORETA.m: -------------------------------------------------------------------------------- 1 | %----------------------------------------------------------------------- 2 | % Job saved on 19-Jan-2014 14:08:03 by cfg_util (rev $Rev$) 3 | % spm SPM - SPM12b (beta) 4 | % cfg_basicio BasicIO - Unknown 5 | %----------------------------------------------------------------------- 6 | matlabbatch{1}.spm.meeg.source.headmodel.val = 1; 7 | matlabbatch{1}.spm.meeg.source.headmodel.comment = ''; 8 | matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshes.template = 1; 9 | matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshres = 2; 10 | matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.useheadshape = 0; 11 | matlabbatch{1}.spm.meeg.source.headmodel.forward.eeg = 'EEG BEM'; 12 | matlabbatch{1}.spm.meeg.source.headmodel.forward.meg = 'Single Shell'; 13 | matlabbatch{2}.spm.tools.beamforming.data.D(1) = cfg_dep('M/EEG head model specification: M/EEG dataset(s) with a forward model', substruct('.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','D')); 14 | matlabbatch{2}.spm.tools.beamforming.data.val = 1; 15 | matlabbatch{2}.spm.tools.beamforming.data.gradsource = 'inv'; 16 | matlabbatch{2}.spm.tools.beamforming.data.space = 'MNI-aligned'; 17 | matlabbatch{2}.spm.tools.beamforming.data.overwrite = 1; 18 | matlabbatch{3}.spm.tools.beamforming.sources.BF(1) = cfg_dep('Prepare data: BF.mat file', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 19 | matlabbatch{3}.spm.tools.beamforming.sources.reduce_rank = [2 3]; 20 | matlabbatch{3}.spm.tools.beamforming.sources.keep3d = 1; 21 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.mesh.orient = 'original'; 22 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.mesh.fdownsample = 1; 23 | matlabbatch{3}.spm.tools.beamforming.sources.plugin.mesh.flip = false; 24 | matlabbatch{3}.spm.tools.beamforming.sources.visualise = 1; 25 | matlabbatch{4}.spm.tools.beamforming.features.BF(1) = cfg_dep('Define sources: BF.mat file', substruct('.','val', '{}',{3}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 26 | matlabbatch{4}.spm.tools.beamforming.features.whatconditions.all = 1; 27 | matlabbatch{4}.spm.tools.beamforming.features.woi = [-Inf Inf]; 28 | matlabbatch{4}.spm.tools.beamforming.features.modality = {'MEG'}; 29 | matlabbatch{4}.spm.tools.beamforming.features.fuse = 'no'; 30 | matlabbatch{4}.spm.tools.beamforming.features.plugin.cov.foi = [0 Inf]; 31 | matlabbatch{4}.spm.tools.beamforming.features.plugin.cov.taper = 'none'; 32 | matlabbatch{4}.spm.tools.beamforming.features.regularisation.manual.lambda = 1; 33 | matlabbatch{4}.spm.tools.beamforming.features.bootstrap = false; 34 | matlabbatch{5}.spm.tools.beamforming.inverse.BF(1) = cfg_dep('Covariance features: BF.mat file', substruct('.','val', '{}',{4}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 35 | matlabbatch{5}.spm.tools.beamforming.inverse.plugin.eloreta.regularisation = 0.05; 36 | matlabbatch{6}.spm.tools.beamforming.output.BF(1) = cfg_dep('Inverse solution: BF.mat file', substruct('.','val', '{}',{5}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 37 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.whatconditions.all = 1; 38 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.sametrials = false; 39 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.contrast = 1; 40 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.result = 'singleimage'; 41 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.scale = 2; 42 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.powermethod = 'trace'; 43 | matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.modality = 'MEG'; 44 | matlabbatch{7}.spm.tools.beamforming.write.BF(1) = cfg_dep('Output: BF.mat file', substruct('.','val', '{}',{6}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF')); 45 | matlabbatch{7}.spm.tools.beamforming.write.plugin.gifti.normalise = 'no'; 46 | matlabbatch{7}.spm.tools.beamforming.write.plugin.gifti.space = 'mni'; 47 | matlabbatch{7}.spm.tools.beamforming.write.plugin.gifti.visualise = 2; 48 | -------------------------------------------------------------------------------- /bf_regularise_mantrunc.m: -------------------------------------------------------------------------------- 1 | function res = bf_regularise_mantrunc(BF, S) 2 | % User-specified dimensional reduction 3 | % Copyright (C) 2013 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0 10 | pcadim = cfg_entry; 11 | pcadim.tag = 'pcadim'; 12 | pcadim.name = 'Dimensionality'; 13 | pcadim.strtype = 'n'; 14 | pcadim.num = [1 1]; 15 | pcadim.val = {100}; 16 | pcadim.help = {'User-specified number of dimensions'}; 17 | 18 | res = cfg_branch; 19 | res.tag = 'mantrunc'; 20 | res.name = 'Manual truncation'; 21 | res.val = {pcadim}; 22 | 23 | return 24 | elseif nargin < 2 25 | error('Two input arguments are required'); 26 | end 27 | 28 | C = BF.features.(S.modality).C; 29 | N = BF.features.(S.modality).N; 30 | 31 | [U, alls] = svd(C); 32 | 33 | U = U(:,1:S.pcadim); 34 | C = U'*C*U; %% compact version of the covariance matrix 35 | Cinv = pinv_plus(C); 36 | 37 | 38 | features = BF.features.(S.modality); 39 | features.C = C; 40 | features.Cinv = Cinv; 41 | features.U = U; 42 | 43 | res = features; -------------------------------------------------------------------------------- /bf_regularise_manual.m: -------------------------------------------------------------------------------- 1 | function res = bf_regularise_manual(BF, S) 2 | % Manual specification of the regularisation parameter 3 | % Copyright (C) 2013 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0 10 | lambda = cfg_entry; 11 | lambda.tag = 'lambda'; 12 | lambda.name = 'Regularisation'; 13 | lambda.strtype = 'r'; 14 | lambda.num = [1 1]; 15 | lambda.val = {0}; 16 | lambda.help = {'Select the regularisation (in %)'}; 17 | 18 | res = cfg_branch; 19 | res.tag = 'manual'; 20 | res.name = 'User-specified regularisation'; 21 | res.val = {lambda}; 22 | 23 | return 24 | elseif nargin < 2 25 | error('Two input arguments are required'); 26 | end 27 | 28 | %%%%%%%%% 29 | %MWW 19/11/2014 30 | % added to be compatible with multi-class festures (see bf_features) 31 | if isfield(S,'class'), 32 | features_mod = BF.features.(S.modality).class{S.class}; 33 | else 34 | features_mod = BF.features.(S.modality); 35 | end; 36 | C = features_mod.C; 37 | %%%%%%%%% 38 | 39 | lambda = (S.lambda/100) * trace(C)/size(C,1); 40 | C = C + lambda * eye(size(C)); 41 | Cinv = pinv_plus(C); 42 | U = eye(size(C)); 43 | 44 | features = BF.features.(S.modality); 45 | features.C = C; 46 | features.Cinv = Cinv; 47 | features.U = U; 48 | 49 | res = features; -------------------------------------------------------------------------------- /bf_regularise_minkatrunc.m: -------------------------------------------------------------------------------- 1 | function res = bf_regularise_minkatrunc(BF, S) 2 | % Bayesian regularisation based on Minka's method 3 | % Copyright (C) 2013 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Gareth Barnes 6 | % $Id$ 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0 10 | reduce = cfg_menu; 11 | reduce.tag = 'reduce'; 12 | reduce.name = 'Reduce data dimension'; 13 | reduce.help = {'Reduce the data to spatial modes based on Bayesian PCA'}; 14 | reduce.labels = {'yes', 'no'}; 15 | reduce.values = {1, 0}; 16 | reduce.val = {1}; 17 | 18 | res = cfg_branch; 19 | res.tag = 'minkatrunc'; 20 | res.name = 'Minka truncation'; 21 | res.val = {reduce}; 22 | 23 | return 24 | elseif nargin < 2 25 | error('Two input arguments are required'); 26 | end 27 | 28 | C = BF.features.(S.modality).C; 29 | N = BF.features.(S.modality).N; 30 | 31 | [U, alls] = svd(C); 32 | 33 | [M_opt,log_ev,lambda1] = spm_pca_order (C, N); 34 | 35 | fprintf('Estimated covariance matrix order %d\n', M_opt); 36 | 37 | 38 | if S.reduce 39 | U = U(:,1:M_opt); 40 | C = U'*C*U; %% compact version of the covariance matrix 41 | Cinv = pinv_plus(C); 42 | else 43 | C = U(:,1:M_opt)*alls(1:M_opt,1:M_opt)*U(:,1:M_opt)'; 44 | U = eye(size(C)); 45 | Cinv = pinv_plus(C, M_opt); 46 | end 47 | 48 | features = BF.features.(S.modality); 49 | features.C = C; 50 | features.Cinv = Cinv; 51 | features.U = U; 52 | 53 | res = features; -------------------------------------------------------------------------------- /bf_regularise_roi.m: -------------------------------------------------------------------------------- 1 | function res = bf_regularise_roi(BF, S) 2 | % ROI regularisation 3 | % See: Oswal et al. Optimising beamformer regions of interest analysis, Neuroimage, 2014 4 | % Copyright (C) 2014 Wellcome Trust Centre for Neuroimaging 5 | 6 | % Ashwini Oswal, Vladimir Litvak 7 | % $Id$ 8 | 9 | %-------------------------------------------------------------------------- 10 | if nargin == 0 11 | pos = cfg_entry; 12 | pos.tag = 'pos'; 13 | pos.name = 'MNI coordinates'; 14 | pos.strtype = 'r'; 15 | pos.num = [1 3]; 16 | pos.help = {'Locations for the VOI in MNI coordinates'}; 17 | pos.val = {}; 18 | 19 | radius = cfg_entry; 20 | radius.tag = 'radius'; 21 | radius.name = 'Radius'; 22 | radius.strtype = 'r'; 23 | radius.num = [1 1]; 24 | radius.val = {0}; 25 | radius.help = {'Radius (in mm) for the VOIs (leave 0 for single point)'}; 26 | 27 | voidef = cfg_branch; 28 | voidef.tag = 'voidef'; 29 | voidef.name = 'VOI'; 30 | voidef.val = {pos, radius}; 31 | 32 | vois = cfg_repeat; 33 | vois.tag = 'vois'; 34 | vois.name = 'ROI(s)'; 35 | vois.num = [1 Inf]; 36 | vois.values = {voidef}; 37 | vois.val = {}; 38 | vois.help = {'This makes it possible to define new VOIs when the original source space was mesh or grid.',... 39 | 'Only the sources present in the original source space can be used at this stage'}; 40 | 41 | manual = cfg_entry; 42 | manual.tag = 'manual'; 43 | manual.name = 'User-specified'; 44 | manual.strtype = 'n'; 45 | manual.num = [1 1]; 46 | manual.help = {'User-specified number of dimensions'}; 47 | 48 | original = cfg_const; 49 | original.tag = 'original'; 50 | original.name = 'Keep original'; 51 | original.help = {'Keep the original dimensionality of the ROI'}; 52 | original.val = {1}; 53 | 54 | minka = cfg_const; 55 | minka.tag = 'minka'; 56 | minka.name = 'Minka truncation'; 57 | minka.help = {'Use Bayesian algorithm to determine dimensionality'}; 58 | minka.val = {1}; 59 | 60 | dimred = cfg_choice; 61 | dimred.tag = 'dimred'; 62 | dimred.name = 'Dimension choice'; 63 | dimred.values = {original, manual, minka}; 64 | dimred.val = {original}; 65 | 66 | res = cfg_branch; 67 | res.tag = 'roi'; 68 | res.name = 'ROI regularisation'; 69 | res.val = {vois, dimred}; 70 | 71 | return 72 | elseif nargin < 2 73 | error('Two input arguments are required'); 74 | end 75 | 76 | mnipos = spm_eeg_inv_transform_points(BF.data.transforms.toMNI, BF.sources.pos); 77 | 78 | ind = []; 79 | for v = 1:numel(S.voidef) 80 | dist = sqrt(sum((mnipos-repmat(S.voidef(v).pos, size(mnipos, 1), 1)).^2, 2)); 81 | if S.voidef(v).radius>0 82 | ind = [ind find(dist20 % if there is nothing within 2cm something must be wrong 86 | mind = []; 87 | warning(['No sources were found close enough for VOI ' num2str(2)]); 88 | end 89 | ind = [ind mind]; 90 | end 91 | end 92 | 93 | ind = unique(ind); 94 | 95 | if isempty(ind) 96 | error('No sources were found in the defined ROI'); 97 | end 98 | 99 | BF.features.(S.modality).chanind = S.chanind; 100 | 101 | [L, channels] = bf_fuse_lf(BF, S.modality); 102 | 103 | LL = cat(2, L{ind}); 104 | 105 | Clf = LL*LL'; 106 | 107 | [LU, Sv, LV] = svd(Clf); 108 | 109 | C = BF.features.(S.modality).C; 110 | N = BF.features.(S.modality).N; 111 | 112 | switch char(fieldnames(S.dimred)) 113 | case 'original' 114 | U = LU; 115 | case 'manual' 116 | U = LU(:, 1:S.dimred.manual); 117 | case 'minka' 118 | [M_opt,log_ev,lambda1] = spm_pca_order (LU'*C*LU, N); 119 | fprintf('Estimated covariance matrix order %d\n', M_opt); 120 | 121 | [U, dum] = svd(LU'*C*LU); 122 | U = LU*U(:, 1:M_opt); 123 | end 124 | 125 | C = U'*C*U; 126 | Cinv = pinv_plus(C); 127 | 128 | features = BF.features.(S.modality); 129 | features.C = C; 130 | features.Cinv = Cinv; 131 | features.U = U; 132 | 133 | res = features; 134 | 135 | %% 136 | %% plot the mean square root error here defined in the Van Veen paper as the sum of eigenvalues of components not taken over the sum of all eigenvalues 137 | Fgraph = spm_figure('GetWin','Graphics'); figure(Fgraph); clf 138 | all_eig = diag(Sv).^2; 139 | den = sum(all_eig); 140 | all_e = []; 141 | for n = 1:numel(all_eig) 142 | v = 1:n; 143 | num = sum(all_eig(v)); 144 | e = (den-num)/den; 145 | all_e = [all_e,e]; 146 | end 147 | semilogy(all_e,'ro-');title('error as a function of dimensionality reduction'); 148 | hold on 149 | plot(size(U, 2)*[1 1], ylim, 'k'); 150 | xlabel('components'); 151 | ylabel('error defined from Van Veen paper'); -------------------------------------------------------------------------------- /bf_regularise_tichonov_rankdef.m: -------------------------------------------------------------------------------- 1 | function res = bf_regularise_tichonov_rankdef(BF, S) 2 | % Tichonov regularisation for rank deficient matrices based on the function 3 | % contribute by Olaf Hauk 4 | % Copyright (C) 2018 Wellcome Centre for Human Neuroimaging 5 | 6 | % Vladimir Litvak 7 | % $Id$ 8 | 9 | %-------------------------------------------------------------------------- 10 | if nargin == 0 11 | rank = cfg_entry; 12 | rank.tag = 'rank'; 13 | rank.name = 'Dimensionality'; 14 | rank.strtype = 'n'; 15 | rank.num = [1 1]; 16 | rank.val = {80}; 17 | rank.help = {'True known data rank'}; 18 | 19 | lambda = cfg_entry; 20 | lambda.tag = 'lambda'; 21 | lambda.name = 'Regularisation'; 22 | lambda.strtype = 'r'; 23 | lambda.num = [1 1]; 24 | lambda.val = {5}; 25 | lambda.help = {'Select the regularisation (in %)'}; 26 | 27 | res = cfg_branch; 28 | res.tag = 'tichonov_rankdef'; 29 | res.name = 'Tichonov regularisation'; 30 | res.val = {rank, lambda}; 31 | 32 | return 33 | elseif nargin < 2 34 | error('Two input arguments are required'); 35 | end 36 | 37 | C = BF.features.(S.modality).C; 38 | N = BF.features.(S.modality).N; 39 | 40 | Cinv = Tikhonov_rank_def(C, S.rank, S.lambda); 41 | 42 | features = BF.features.(S.modality); 43 | features.C = C; 44 | features.Cinv = Cinv; 45 | features.U = eye(size(C, 1)); 46 | 47 | res = features; -------------------------------------------------------------------------------- /bf_save.m: -------------------------------------------------------------------------------- 1 | function bf_save(BF, overwrite) 2 | % Saves BF data in a mat file 3 | % Copyright (C) 2012 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | if nargin == 1 && exist(fullfile(pwd, 'BF.mat'), 'file') 9 | save('BF.mat', '-struct', 'BF', '-append'); 10 | else 11 | save('BF.mat', '-struct', 'BF', '-v7'); 12 | end -------------------------------------------------------------------------------- /bf_save_path.m: -------------------------------------------------------------------------------- 1 | function bf_save_path(BF,path, overwrite) 2 | % Saves BF data in a mat file 3 | % Copyright (C) 2012 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | if nargin == 2 && exist(path, 'file') 9 | save(path, '-struct', 'BF', '-append'); 10 | else 11 | save(path, '-struct', 'BF', '-v7.3'); 12 | end -------------------------------------------------------------------------------- /bf_slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spm/DAiSS/617f5606a5bd106e11b2d6d66ec0203147780d6d/bf_slides.pdf -------------------------------------------------------------------------------- /bf_sources_grid.m: -------------------------------------------------------------------------------- 1 | function res = bf_sources_grid(BF, S) 2 | % Generate beamforming grid 3 | % Copyright (C) 2012 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0 10 | resolution = cfg_entry; 11 | resolution.tag = 'resolution'; 12 | resolution.name = 'Grid resolution'; 13 | resolution.strtype = 'n'; 14 | resolution.num = [1 1]; 15 | resolution.val = {5}; 16 | resolution.help = {'Select the resolution of the grid (in mm)'}; 17 | 18 | space = cfg_menu; 19 | space.tag = 'space'; 20 | space.name = 'Coordinate system'; 21 | space.help = {'Select the coordinate system in which the grid should be generated'}; 22 | space.labels = {'MNI template', 'MNI-aligned', 'Head', 'Native'}; 23 | space.values = {'MNI template', 'MNI-aligned', 'Head', 'Native'}; 24 | space.val = {'MNI template'}; 25 | 26 | constrain = cfg_menu; 27 | constrain.tag = 'constrain'; 28 | constrain.name = 'Coordinate sources to'; 29 | constrain.help = {'The boundary to which the grid is confined'}; 30 | constrain.labels = {'Inner skull', 'Scalp'}; 31 | constrain.values = {'iskull', 'scalp'}; 32 | constrain.val = {'iskull'}; 33 | 34 | grid = cfg_branch; 35 | grid.tag = 'grid'; 36 | grid.name = 'Grid'; 37 | grid.val = {resolution, space, constrain}; 38 | 39 | res = grid; 40 | 41 | return 42 | elseif nargin < 2 43 | error('Two input arguments are required'); 44 | end 45 | 46 | if ~isfield(S, 'constrain') 47 | S.constrain = 'iskull'; 48 | end 49 | 50 | switch S.constrain 51 | case 'iskull' 52 | constraint = export(gifti(BF.data.mesh.tess_iskull), 'ft'); 53 | case 'scalp' 54 | constraint = export(gifti(BF.data.mesh.tess_scalp), 'ft'); 55 | end 56 | 57 | M1 = BF.data.transforms.toNative; 58 | 59 | switch S.space 60 | case 'MNI template' 61 | M1 = BF.data.transforms.toMNI/M1; 62 | M2 = inv(BF.data.transforms.toMNI); 63 | case 'MNI-aligned' 64 | M1 = BF.data.transforms.toMNI_aligned/M1; 65 | M2 = inv(BF.data.transforms.toMNI_aligned); 66 | case 'Head' 67 | M1 = BF.data.transforms.toHead/M1; 68 | M2 = inv(BF.data.transforms.toHead); 69 | case 'Native' 70 | M2 = inv(M1); 71 | M1 = eye(4); 72 | end 73 | 74 | constraint = ft_determine_units(ft_transform_geometry(M1, constraint)); 75 | 76 | mn = min(constraint.pnt); 77 | mx = max(constraint.pnt); 78 | 79 | resolution = S.resolution; 80 | 81 | if isequal(constraint.unit, 'm') 82 | resolution = 1e-3*resolution; 83 | end 84 | 85 | % If zero is inside the brain, make sure grid points fall on multiples of 86 | % resolution to ease simulating data from points on the grid 87 | if mn(1)<0 && mx(1)>0 88 | grid.xgrid = [fliplr(0:-resolution:mn(1)) resolution:resolution:mx(1)]; 89 | else 90 | grid.xgrid = mn(1):resolution:mx(1); 91 | end 92 | 93 | if mn(2)<0 && mx(2)>0 94 | grid.ygrid = [fliplr(0:-resolution:mn(2)) resolution:resolution:mx(2)]; 95 | else 96 | grid.ygrid = mn(2):resolution:mx(2); 97 | end 98 | 99 | if mn(3)<0 && mx(3)>0 100 | grid.zgrid = [fliplr(0:-resolution:mn(3)) resolution:resolution:mx(3)]; 101 | else 102 | grid.zgrid = mn(3):resolution:mx(3); 103 | end 104 | 105 | grid.dim = [length(grid.xgrid) length(grid.ygrid) length(grid.zgrid)]; 106 | [X, Y, Z] = ndgrid(grid.xgrid, grid.ygrid, grid.zgrid); 107 | 108 | pos = [X(:) Y(:) Z(:)]; 109 | 110 | inside = ft_inside_headmodel(pos, struct('bnd', constraint)); 111 | 112 | pos = spm_eeg_inv_transform_points(M2, pos); 113 | 114 | grid.allpos = pos; 115 | grid.inside = find(inside); 116 | grid.outside = find(~inside); 117 | 118 | grid.pos = pos(inside, :); 119 | 120 | res = grid; -------------------------------------------------------------------------------- /bf_sources_grid_phantom.m: -------------------------------------------------------------------------------- 1 | function res = bf_sources_grid_phantom(BF, S) 2 | % Generate beamforming grid 3 | % Copyright (C) 2012 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0 10 | resolution = cfg_entry; 11 | resolution.tag = 'resolution'; 12 | resolution.name = 'Grid resolution'; 13 | resolution.strtype = 'n'; 14 | resolution.num = [1 1]; 15 | resolution.val = {5}; 16 | resolution.help = {'Select the resolution of the grid (in mm)'}; 17 | 18 | grid = cfg_branch; 19 | grid.tag = 'grid_phantom'; 20 | grid.name = 'Phantom Grid'; 21 | grid.val = {resolution}; 22 | 23 | res = grid; 24 | 25 | return 26 | elseif nargin < 2 27 | error('Two input arguments are required'); 28 | end 29 | 30 | vol = BF.data.MEG.vol; 31 | 32 | if ~isequal(vol.type, 'singlesphere') || any(vol.o) 33 | error('Expecting a spherical volume centered at the origin'); 34 | end 35 | 36 | M1 = BF.data.transforms.toNative; 37 | M1 = BF.data.transforms.toHead/M1; 38 | M2 = inv(BF.data.transforms.toHead); 39 | 40 | mn = -vol.r*[1 1 1]; 41 | mx = vol.r*[1 1 1]; 42 | 43 | resolution = S.resolution; 44 | 45 | if isequal(vol.unit, 'm') 46 | resolution = 1e-3*resolution; 47 | end 48 | 49 | % If zero is inside the brain, make sure grid points fall on multiples of 50 | % resolution to ease simulating data from points on the grid 51 | if mn(1)<0 && mx(1)>0 52 | grid.xgrid = [fliplr(0:-resolution:mn(1)) resolution:resolution:mx(1)]; 53 | else 54 | grid.xgrid = mn(1):resolution:mx(1); 55 | end 56 | 57 | if mn(2)<0 && mx(2)>0 58 | grid.ygrid = [fliplr(0:-resolution:mn(2)) resolution:resolution:mx(2)]; 59 | else 60 | grid.ygrid = mn(2):resolution:mx(2); 61 | end 62 | 63 | if mn(3)<0 && mx(3)>0 64 | grid.zgrid = [fliplr(0:-resolution:mn(3)) resolution:resolution:mx(3)]; 65 | else 66 | grid.zgrid = mn(3):resolution:mx(3); 67 | end 68 | 69 | grid.dim = [length(grid.xgrid) length(grid.ygrid) length(grid.zgrid)]; 70 | [X, Y, Z] = ndgrid(grid.xgrid, grid.ygrid, grid.zgrid); 71 | 72 | pos = [X(:) Y(:) Z(:)]; 73 | 74 | inside = ft_inside_headmodel(pos, vol); 75 | 76 | pos = spm_eeg_inv_transform_points(M2, pos); 77 | 78 | grid.allpos = pos; 79 | grid.inside = find(inside); 80 | grid.outside = find(~inside); 81 | 82 | grid.pos = pos(inside, :); 83 | 84 | res = grid; -------------------------------------------------------------------------------- /bf_sources_mesh.m: -------------------------------------------------------------------------------- 1 | function mesh = bf_sources_mesh(BF, S) 2 | % Generate cortical mesh 3 | % Copyright (C) 2013 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id: bf_sources_mesh.m 98 2013-12-12 16:06:30Z litvak.vladimir@gmail.com $ 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0 10 | orient = cfg_menu; 11 | orient.tag = 'orient'; 12 | orient.name = 'How to orient the sources'; 13 | orient.labels = {'Unoriented', 'Original', 'Downsampled'}; 14 | orient.values = {'unoriented', 'original', 'downsampled'}; 15 | orient.val = {'unoriented'}; 16 | 17 | fdownsample = cfg_entry; 18 | fdownsample.tag = 'fdownsample'; 19 | fdownsample.name = 'Downsample factor'; 20 | fdownsample.strtype = 'r'; 21 | fdownsample.num = [1 1]; 22 | fdownsample.val = {1}; 23 | fdownsample.help = {'A number that determines mesh downsampling',... 24 | 'e.g 5 for taking every 5th vertex'}; 25 | 26 | symmetric = cfg_menu; 27 | symmetric.tag = 'symmetric'; 28 | symmetric.name = 'Symmetric'; 29 | symmetric.help = {'Create a symmetric mesh by reflecting on of the hemispheres.'}; 30 | symmetric.labels = {'No', 'Reflect left', 'Reflect right'}; 31 | symmetric.values = {'no', 'left', 'right'}; 32 | symmetric.val = {'no'}; 33 | 34 | flip = cfg_menu; 35 | flip.tag = 'flip'; 36 | flip.name = 'Flip'; 37 | flip.help = {'Flip the mesh relative to midsagittal plane.'}; 38 | flip.labels = {'yes', 'no'}; 39 | flip.values = {true, false}; 40 | flip.val = {false}; 41 | 42 | mesh = cfg_branch; 43 | mesh.tag = 'mesh'; 44 | mesh.name = 'Cortical mesh'; 45 | mesh.val = {orient, fdownsample, symmetric, flip}; 46 | 47 | return 48 | elseif nargin < 2 49 | error('Two input arguments are required'); 50 | end 51 | 52 | original = BF.data.mesh.tess_mni; 53 | 54 | canonical = original; 55 | 56 | if S.fdownsample ~= 1 57 | canonical = export(gifti(reducepatch(export(gifti(canonical), 'patch'), 1/S.fdownsample)), 'spm'); 58 | end 59 | 60 | if ~isequal(S.symmetric, 'no') 61 | meshcomp = spm_mesh_split(gifti(canonical)); 62 | 63 | if isequal(S.symmetric, 'left') 64 | if median(meshcomp(1).vertices(:, 1))<0 65 | side = meshcomp(1); 66 | else 67 | side = meshcomp(2); 68 | end 69 | elseif isequal(S.symmetric, 'right') 70 | if median(meshcomp(1).vertices(:, 1))>0 71 | side = meshcomp(1); 72 | else 73 | side = meshcomp(2); 74 | end 75 | end 76 | 77 | cside = side; 78 | cside.vertices(:, 1) = -1*side.vertices(:, 1); 79 | cside.faces = side.faces+size(side.vertices, 1); 80 | 81 | canonical = []; 82 | if isequal(S.symmetric, 'left') 83 | canonical.vert = [side.vertices; cside.vertices]; 84 | else 85 | canonical.vert = [cside.vertices; side.vertices]; 86 | end 87 | 88 | canonical.face = [side.faces; cside.faces]; 89 | end 90 | 91 | mesh = []; 92 | mesh.canonical = canonical; 93 | 94 | 95 | if isfield(BF.data.mesh, 'def') 96 | mesh.individual = spm_swarp(gifti(mesh.canonical), BF.data.mesh.def); 97 | original = spm_swarp(gifti(original), BF.data.mesh.def); 98 | else 99 | mesh.individual = mesh.canonical; 100 | end 101 | 102 | M = BF.data.transforms.toNative; 103 | 104 | mesh.individual = export(gifti(mesh.individual), 'spm'); 105 | mesh.individual.vert = spm_eeg_inv_transform_points(inv(M), mesh.individual.vert); 106 | 107 | original = export(gifti(original), 'spm'); 108 | original.vert = spm_eeg_inv_transform_points(inv(M), original.vert); 109 | 110 | mesh.pos = mesh.individual.vert; 111 | 112 | if S.flip 113 | M1 = eye(4); 114 | M1(1, 1) = -1; 115 | M1 = BF.data.transforms.toMNI_aligned\M1*BF.data.transforms.toMNI_aligned; 116 | mesh.pos = spm_eeg_inv_transform_points(M1, mesh.individual.vert); 117 | end 118 | 119 | switch S.orient 120 | case 'original' 121 | norm = spm_mesh_normals(export(gifti(original), 'patch'), true); 122 | if S.fdownsample == 1 123 | mesh.ori = norm; 124 | else 125 | mesh.ori = 0*mesh.pos; 126 | for i = 1:size(mesh.pos, 1) 127 | mesh.ori(i, :) = norm(all(repmat(mesh.pos(i, :), size(original.vert, 1), 1) == original.vert, 2), :); 128 | end 129 | end 130 | case 'downsampled' 131 | mesh.ori = spm_mesh_normals(export(gifti(mesh.individual), 'patch'), true); 132 | end 133 | -------------------------------------------------------------------------------- /bf_sources_mni_coords.m: -------------------------------------------------------------------------------- 1 | function res = bf_sources_mni_coords(BF, S) 2 | % Generate beamforming grid 3 | % Copyright (C) 2012 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Mark Woolrich 6 | % $Id: bf_sources_mni_coords.m 4847 2012-08-16 17:29:23Z vladimir $ 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0 10 | pos = cfg_entry; 11 | pos.tag = 'pos'; 12 | pos.name = 'Pos coords'; 13 | pos.val = {}; 14 | 15 | mni_coords = cfg_branch; 16 | mni_coords.tag = 'mni_coords'; 17 | mni_coords.name = 'Mni Coords'; 18 | mni_coords.val = {pos}; 19 | 20 | res=mni_coords; 21 | 22 | return 23 | elseif nargin < 2 24 | error('Two input arguments are required'); 25 | end 26 | 27 | % transform MNI coords in MNI space into space where we are doing the 28 | % beamforming 29 | M = inv(BF.data.transforms.toMNI); 30 | 31 | grid.pos = S.pos; 32 | 33 | res = ft_transform_geometry(M, grid); 34 | 35 | % establish index of nearest bilateral grid point 36 | % for potential use in lateral beamformer. 37 | res.bilateral_index=zeros(size(S.pos,1),1); 38 | for jj=1:size(S.pos,1), 39 | mnic=S.pos(jj,:); 40 | mnic(1)=-mnic(1); 41 | res.bilateral_index(jj)=nearest_vec(S.pos,mnic); 42 | end; 43 | 44 | %pos=S.pos;figure;scatter3(pos(:,1),pos(:,2),pos(:,3),'.'); 45 | %hold on; jj=100; kk=res.bilateral_index(jj); 46 | %scatter3(pos(jj,1),pos(jj,2),pos(jj,3),'og'); 47 | %scatter3(pos(kk,1),pos(kk,2),pos(kk,3),'or'); 48 | -------------------------------------------------------------------------------- /bf_sources_voi.m: -------------------------------------------------------------------------------- 1 | function voi = bf_sources_voi(BF, S) 2 | % Generate a set of VOIs specified in MNI coordinates 3 | % Copyright (C) 2013 Wellcome Trust Centre for Neuroimaging 4 | 5 | % $Id$ 6 | 7 | %-------------------------------------------------------------------------- 8 | if nargin == 0 9 | label = cfg_entry; 10 | label.tag = 'label'; 11 | label.name = 'Label'; 12 | label.strtype = 's'; 13 | label.help = {'Label for the VOI'}; 14 | 15 | pos = cfg_entry; 16 | pos.tag = 'pos'; 17 | pos.name = 'MNI coordinates'; 18 | pos.strtype = 'r'; 19 | pos.num = [1 3]; 20 | pos.help = {'Locations for the VOI in MNI coordinates'}; 21 | pos.val = {}; 22 | 23 | ori = cfg_entry; 24 | ori.tag = 'ori'; 25 | ori.name = 'Orientation'; 26 | ori.strtype = 'r'; 27 | ori.num = [1 3]; 28 | ori.help = {'Source orientatons (only for single points, leave zeros for unoriented)'}; 29 | ori.val = {[0 0 0]}; 30 | 31 | voidef = cfg_branch; 32 | voidef.tag = 'voidef'; 33 | voidef.name = 'VOI'; 34 | voidef.val = {label, pos, ori}; 35 | 36 | mask = cfg_files; 37 | mask.tag = 'mask'; 38 | mask.name = 'MNI mask'; 39 | mask.filter = 'image'; 40 | mask.ufilter = '.*'; 41 | mask.num = [1 1]; 42 | mask.help = {'Select a mask image'}; 43 | 44 | maskdef = cfg_branch; 45 | maskdef.tag = 'maskdef'; 46 | maskdef.name = 'Mask VOI'; 47 | maskdef.val = {label, mask}; 48 | 49 | vois = cfg_repeat; 50 | vois.tag = 'vois'; 51 | vois.name = 'VOIs'; 52 | vois.num = [1 Inf]; 53 | vois.values = {voidef, maskdef}; 54 | vois.val = {voidef}; 55 | 56 | radius = cfg_entry; 57 | radius.tag = 'radius'; 58 | radius.name = 'Radius'; 59 | radius.strtype = 'r'; 60 | radius.num = [1 1]; 61 | radius.val = {0}; 62 | radius.help = {'Radius (in mm) for the VOIs (leave 0 for single point)'}; 63 | 64 | resolution = cfg_entry; 65 | resolution.tag = 'resolution'; 66 | resolution.name = 'Resolution'; 67 | resolution.strtype = 'r'; 68 | resolution.num = [1 1]; 69 | resolution.val = {5}; 70 | resolution.help = {'Resolution for placing grid points in each VOI (in mm)'}; 71 | 72 | voi = cfg_branch; 73 | voi.tag = 'voi'; 74 | voi.name = 'VOIs in MNI space'; 75 | voi.val = {vois, radius, resolution}; 76 | 77 | return 78 | elseif nargin < 2 79 | error('Two input arguments are required'); 80 | end 81 | 82 | 83 | iskull = export(gifti(BF.data.mesh.tess_iskull), 'ft'); 84 | 85 | M1 = BF.data.transforms.toNative; 86 | M1 = BF.data.transforms.toMNI/M1; 87 | 88 | iskull = ft_determine_units(ft_transform_geometry(M1, iskull)); 89 | 90 | 91 | % transform MNI coords in MNI space into space where we are doing the 92 | % beamforming 93 | M = inv(BF.data.transforms.toMNI); 94 | 95 | if S.radius > 0 96 | vec = -S.radius:S.resolution:S.radius; 97 | [X, Y, Z] = ndgrid(vec, vec, vec); 98 | sphere = [X(:) Y(:) Z(:)]; 99 | sphere(sqrt(X(:).^2 + Y(:).^2 + Z(:).^2) > S.radius, :) = []; 100 | npnt = size(sphere, 1); 101 | else 102 | sphere = 0; 103 | npnt = 1; 104 | end 105 | 106 | grid = bf_sources_grid(BF, struct('resolution', S.resolution, 'space', 'MNI template')); 107 | mnigrid = ft_transform_geometry(BF.data.transforms.toMNI, grid); 108 | 109 | nvoi = numel(S.vois); 110 | voi = []; 111 | voi.label = {}; 112 | voi.pos = []; 113 | ori = []; 114 | voi.pos2voi = []; 115 | 116 | for i = 1:nvoi 117 | switch char(fieldnames(S.vois{i})) 118 | case 'voidef' 119 | voi.label{i} = S.vois{i}.voidef.label; 120 | voi.pos = [voi.pos; sphere+repmat(S.vois{i}.voidef.pos, npnt, 1)]; 121 | ori = [ori; S.vois{i}.voidef.ori]; 122 | voi.pos2voi = [voi.pos2voi i*ones(1, npnt)]; 123 | case 'maskdef' 124 | voi.label{i} = S.vois{i}.maskdef.label; 125 | V = spm_vol(char(S.vois{i}.maskdef.mask)); 126 | 127 | vox = spm_eeg_inv_transform_points(inv(V.mat), mnigrid.pos); 128 | Y = spm_sample_vol(V, vox(:, 1), vox(:, 2), vox(:, 3), 0); 129 | ind = find(~isnan(Y) & abs(Y)>0); 130 | voi.pos = [voi.pos; mnigrid.pos(ind, :)]; 131 | ori = [ori;zeros(length(ind), 3)]; 132 | voi.pos2voi = [voi.pos2voi i*ones(1, length(ind))]; 133 | end 134 | end 135 | 136 | voi.label = voi.label(:); 137 | 138 | % Remove points outside the brain 139 | inside = ft_inside_headmodel(voi.pos, struct('bnd', iskull)); 140 | 141 | voi.pos(~inside, :) = []; 142 | voi.pos2voi(~inside) = []; 143 | 144 | if any(any(ori)) 145 | voi.ori = ori(inside, :); 146 | end 147 | 148 | 149 | voi = ft_transform_geometry(M, voi); -------------------------------------------------------------------------------- /bf_std_fields.m: -------------------------------------------------------------------------------- 1 | function fields = bf_std_fields(sel) 2 | 3 | fields = { 4 | 'data' 5 | 'sources' 6 | 'features' 7 | 'inverse' 8 | 'output' 9 | 'write' 10 | }; 11 | 12 | if nargin > 0 13 | fields = fields(sel); 14 | end 15 | -------------------------------------------------------------------------------- /bf_write.m: -------------------------------------------------------------------------------- 1 | function out = bf_write 2 | % Writes out the results of beamforming analysis 3 | % Copyright (C) 2012 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | % dir Directory 9 | % --------------------------------------------------------------------- 10 | BF = cfg_files; 11 | BF.tag = 'BF'; 12 | BF.name = 'BF.mat file'; 13 | BF.filter = '^BF.mat$'; 14 | BF.num = [1 1]; 15 | BF.help = {'Select BF.mat file.'}; 16 | 17 | %-------------------------------------------------------------------------- 18 | % method 19 | %-------------------------------------------------------------------------- 20 | plugin = cfg_choice; 21 | plugin.tag = 'plugin'; 22 | plugin.name = 'What to write out'; 23 | 24 | write_funs = spm_select('List', fileparts(mfilename('fullpath')), '^bf_write_.*\.m$'); 25 | write_funs = cellstr(write_funs ); 26 | for i = 1:numel(write_funs) 27 | plugin.values{i} = feval(spm_file(write_funs{i},'basename')); 28 | end 29 | 30 | out = cfg_exbranch; 31 | out.tag = 'write'; 32 | out.name = 'Write'; 33 | out.val = {BF, plugin}; 34 | out.help = {'Write out results'}; 35 | out.prog = @bf_write_run; 36 | out.vout = @bf_write_vout; 37 | out.modality = {'EEG'}; 38 | end 39 | 40 | function out = bf_write_run(job) 41 | 42 | outdir = spm_file(job.BF{1}, 'fpath'); 43 | 44 | cd(outdir); 45 | 46 | BF = bf_load('BF.mat', {'data', 'sources', 'features', 'output'}); 47 | 48 | plugin_name = cell2mat(fieldnames(job.plugin)); 49 | 50 | outfield_name = strtok(plugin_name, '_'); 51 | 52 | BF.write.(outfield_name) = feval(['bf_write_' plugin_name], BF, job.plugin.(plugin_name)); 53 | 54 | bf_save(BF); 55 | 56 | out.BF{1} = fullfile(outdir, 'BF.mat'); 57 | out.files = BF.write.(outfield_name).files; 58 | end 59 | 60 | function dep = bf_write_vout(job) 61 | % Output is always in field "D", no matter how job is structured 62 | dep(1) = cfg_dep; 63 | dep(1).sname = 'BF.mat file'; 64 | % reference field "B" from output 65 | dep(1).src_output = substruct('.','BF'); 66 | % this can be entered into any evaluated input 67 | dep(1).tgt_spec = cfg_findspec({{'filter','mat'}}); 68 | dep(2).sname = 'Output files'; 69 | dep(2).src_output = substruct('.','files'); 70 | 71 | plugin_name = cell2mat(fieldnames(job.plugin)); 72 | 73 | switch plugin_name 74 | case 'spmeeg' 75 | dep(2).tgt_spec = cfg_findspec({{'filter','mat','strtype','e'}}); 76 | case 'nifti' 77 | dep(2).tgt_spec = cfg_findspec({{'filter','image','strtype','e'}}); 78 | case 'gifti' 79 | dep(2).tgt_spec = cfg_findspec({{'filter','mesh','strtype','e'}}); 80 | end 81 | end -------------------------------------------------------------------------------- /bf_write_gifti.m: -------------------------------------------------------------------------------- 1 | function res = bf_write_gifti(BF, S) 2 | % Writes out beamformer results as GIfTI meshes 3 | % Copyright (C) 2013 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0 10 | normalise = cfg_menu; 11 | normalise.tag = 'normalise'; 12 | normalise.name = 'Global normalisation'; 13 | normalise.help = {'Normalise image values by the mean'}; 14 | normalise.labels = { 15 | 'No' 16 | 'Each image separately' 17 | 'Across images' 18 | }'; 19 | normalise.values = { 20 | 'no' 21 | 'separate' 22 | 'all' 23 | }'; 24 | normalise.val = {'no'}; 25 | 26 | space = cfg_menu; 27 | space.tag = 'space'; 28 | space.name = 'Image space'; 29 | space.help = {'Specify image space'}; 30 | space.labels = { 31 | 'MNI' 32 | 'Native' 33 | 'MNI-aligned' 34 | }'; 35 | space.values = { 36 | 'mni' 37 | 'native' 38 | 'aligned' 39 | }'; 40 | space.val = {'mni'}; 41 | 42 | visualise = cfg_menu; 43 | visualise.tag = 'visualise'; 44 | visualise.name = 'Visualise the outputs'; 45 | visualise.help = {'Visualise the outputs in the graphics window.'}; 46 | visualise.labels = {'inflated', 'yes', 'no'}; 47 | visualise.values = {2, 1, 0}; 48 | visualise.val = {0}; 49 | 50 | res = cfg_branch; 51 | res.tag = 'gifti'; 52 | res.name = 'GIfTI'; 53 | res.val = {normalise, space, visualise}; 54 | 55 | return 56 | elseif nargin < 2 57 | error('Two input arguments are required'); 58 | end 59 | 60 | if ~isfield(BF.sources, 'mesh') 61 | error('Only mesh source space is supported'); 62 | end 63 | 64 | scale = ones(1, numel(BF.output.image)); 65 | switch S.normalise 66 | case 'separate' 67 | for i = 1:numel(BF.output.image) 68 | val = BF.output.image(i).val; 69 | scale(i) = 1./mean(abs(val(~isnan(val)))); 70 | end 71 | case 'all' 72 | val = spm_vec({BF.output.image(:).val}); 73 | scale = scale./mean(abs(val(~isnan(val)))); 74 | end 75 | 76 | switch S.space 77 | case 'mni' 78 | source = BF.sources.mesh.canonical; 79 | case 'aligned' 80 | source = BF.sources.mesh.individual; 81 | source.vert = spm_eeg_inv_transform_points(BF.data.transforms.toMNI_aligned, source.vert); 82 | case 'native' 83 | source = BF.sources.mesh.individual; 84 | source.vert = spm_eeg_inv_transform_points(BF.data.transforms.toNative, source.vert); 85 | end 86 | 87 | save(gifti(source), [BF.data.D.fname '.surf.gii']); 88 | 89 | nimages = numel(BF.output.image); 90 | 91 | spm('Pointer', 'Watch');drawnow; 92 | spm_progress_bar('Init', nimages , 'Writing out images'); drawnow; 93 | if nimages > 100, Ibar = floor(linspace(1, nimages ,100)); 94 | else Ibar = 1:nimages; end 95 | 96 | for i = 1:nimages 97 | fname = fullfile(pwd, [BF.output.image(i).label '.gii']); 98 | 99 | G = gifti; 100 | G.private.metadata(1).name = 'SurfaceID'; 101 | G.private.metadata(1).value = [BF.data.D.fname '.surf.gii']; 102 | 103 | G.cdata = scale(i)*BF.output.image(i).val; 104 | 105 | G.cdata = G.cdata(:); 106 | 107 | save(G, fname, 'ExternalFileBinary'); 108 | 109 | res.files{i, 1} = fname; 110 | 111 | if S.visualise 112 | Fgraph = spm_figure('GetWin', fname); figure(Fgraph); clf 113 | a = axes; 114 | if S.visualise == 2 115 | H = spm_mesh_render('Disp', spm_mesh_inflate(gifti([BF.data.D.fname '.surf.gii'])), 'Parent', a); 116 | H = spm_mesh_render('Overlay', H, gifti(fname)); 117 | else 118 | H = spm_mesh_render('Disp',gifti([BF.data.D.fname '.surf.gii']), 'Parent', a); 119 | H = spm_mesh_render('Overlay', H, gifti(fname)); 120 | end 121 | spm_mesh_render('Colormap', H, jet(256)); 122 | end 123 | 124 | if ismember(i, Ibar) 125 | spm_progress_bar('Set', i); drawnow; 126 | end 127 | end 128 | 129 | spm_progress_bar('Clear'); 130 | -------------------------------------------------------------------------------- /bf_write_nifti.m: -------------------------------------------------------------------------------- 1 | function res = bf_write_nifti(BF, S) 2 | % Writes out nifti images of beamformer results 3 | % Copyright (C) 2013 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | %-------------------------------------------------------------------------- 9 | if nargin == 0 10 | normalise = cfg_menu; 11 | normalise.tag = 'normalise'; 12 | normalise.name = 'Global normalisation'; 13 | normalise.help = {'Normalise image values by the mean'}; 14 | normalise.labels = { 15 | 'No' 16 | 'Each image separately' 17 | 'Across images' 18 | }'; 19 | normalise.values = { 20 | 'no' 21 | 'separate' 22 | 'all' 23 | }'; 24 | normalise.val = {'no'}; 25 | 26 | space = cfg_menu; 27 | space.tag = 'space'; 28 | space.name = 'Image space'; 29 | space.help = {'Specify image space'}; 30 | space.labels = { 31 | 'MNI' 32 | 'Native' 33 | 'MNI-aligned' 34 | }'; 35 | space.values = { 36 | 'mni' 37 | 'native' 38 | 'aligned' 39 | }'; 40 | space.val = {'mni'}; 41 | 42 | nifti = cfg_branch; 43 | nifti.tag = 'nifti'; 44 | nifti.name = 'NIfTI'; 45 | nifti.val = {normalise, space}; 46 | 47 | res = nifti; 48 | 49 | return 50 | elseif nargin < 2 51 | error('Two input arguments are required'); 52 | end 53 | 54 | scale = ones(1, numel(BF.output.image)); 55 | switch S.normalise 56 | case 'separate' 57 | for i = 1:numel(BF.output.image) 58 | val = BF.output.image(i).val; 59 | scale(i) = 1./mean(abs(val(~isnan(val)))); 60 | end 61 | case 'all' 62 | val = spm_vec({BF.output.image(:).val}); 63 | scale = scale./mean(abs(val(~isnan(val)))); 64 | end 65 | 66 | switch S.space 67 | case 'mni' 68 | sMRI = fullfile(spm('dir'), 'canonical', 'single_subj_T1.nii'); 69 | case 'aligned' 70 | sMRI = fullfile(spm('dir'), 'canonical', 'single_subj_T1.nii'); 71 | case 'native' 72 | sMRI = BF.data.mesh.sMRI; 73 | end 74 | 75 | [pth,nam,ext,num] = spm_fileparts(sMRI); 76 | sMRI = fullfile(pth, [nam ext]); 77 | 78 | if isfield(BF.sources, 'grid') || isfield(BF.sources, 'voi') 79 | if isfield(BF.sources, 'grid') 80 | sourcespace = 'grid'; 81 | source = BF.sources.grid; 82 | source.pos = BF.sources.grid.allpos; 83 | else 84 | sourcespace = 'voi'; 85 | source = []; 86 | source.pos = BF.sources.pos; 87 | source.inside = 1:size(BF.sources.pos, 1); 88 | source.outside = []; 89 | end 90 | 91 | 92 | 93 | switch S.space 94 | case 'mni' 95 | source = ft_transform_geometry(BF.data.transforms.toMNI, source); 96 | case 'aligned' 97 | source = ft_transform_geometry(BF.data.transforms.toMNI_aligned, source); 98 | case 'native' 99 | source = ft_transform_geometry(BF.data.transforms.toNative, source); 100 | end 101 | 102 | cfg = []; 103 | cfg.parameter = 'pow'; 104 | cfg.downsample = 1; 105 | cfg.showcallinfo = 'no'; 106 | 107 | elseif isfield(BF.sources, 'mesh') 108 | sourcespace = 'mesh'; 109 | 110 | switch S.space 111 | case 'mni' 112 | source = BF.sources.mesh.canonical; 113 | case 'aligned' 114 | source = BF.sources.mesh.individual; 115 | source.vert = spm_eeg_inv_transform_points(BF.data.transforms.toMNI_aligned, source.vert); 116 | case 'native' 117 | source = BF.sources.mesh.individual; 118 | source.vert = spm_eeg_inv_transform_points(BF.data.transforms.toNative, source.vert); 119 | end 120 | 121 | source = export(gifti(source), 'patch'); 122 | else 123 | error('Unsupported source space type'); 124 | end 125 | 126 | 127 | outvol = spm_vol(sMRI); 128 | outvol.dt(1) = spm_type('float32'); 129 | 130 | 131 | nimages = numel(BF.output.image); 132 | 133 | spm('Pointer', 'Watch');drawnow; 134 | spm_progress_bar('Init', nimages , 'Writing out images'); drawnow; 135 | if nimages > 100, Ibar = floor(linspace(1, nimages ,100)); 136 | else Ibar = 1:nimages; end 137 | 138 | 139 | for i = 1:nimages 140 | outvol.fname= fullfile(pwd, [BF.output.image(i).label '.nii']); 141 | outvol = spm_create_vol(outvol); 142 | 143 | source.pow = scale(i)*BF.output.image(i).val; 144 | 145 | source.pow = source.pow(:); 146 | 147 | switch sourcespace 148 | case 'grid' 149 | pow = source.pow; 150 | source.pow = nan(size(source.pos, 1), 1); 151 | source.pow(source.inside) = pow; 152 | sourceint = ft_sourceinterpolate(cfg, source, ft_read_mri(sMRI, 'dataformat', 'nifti_spm')); 153 | Y = sourceint.pow; 154 | case 'mesh' 155 | Y = spm_mesh_to_grid(source, outvol, source.pow); 156 | spm_smooth(Y, Y, 1); 157 | Y = Y.*(Y > max(source.pow)*exp(-8)); 158 | case 'voi' 159 | cfg.interpmethod = 'sphere_avg'; 160 | cfg.sphereradius = 5; 161 | sourceint = ft_sourceinterpolate(cfg, source, ft_read_mri(sMRI, 'dataformat', 'nifti_spm')); 162 | Y = sourceint.pow; 163 | Y = reshape(Y, sourceint.dim); 164 | end 165 | 166 | spm_write_vol(outvol, Y); 167 | 168 | nifti.files{i, 1} = outvol.fname; 169 | 170 | if ismember(i, Ibar) 171 | spm_progress_bar('Set', i); drawnow; 172 | end 173 | end 174 | 175 | spm_progress_bar('Clear'); 176 | 177 | res = nifti; 178 | -------------------------------------------------------------------------------- /private/DeFleCT.m: -------------------------------------------------------------------------------- 1 | function w=DeFleCT(passband,SVDpassband,force_passband_flag,stopband,SVDstopband,... 2 | LFM,C,SNR2,Csvdtrunc) 3 | % function w=DeFleCT(passband,SVDpassband,force_passband_flag,stopband,SVDstopband,... 4 | % LFM,C,SNR2,Csvdtrunc) 5 | % function w=DeFleCT(passband,SVDpassband,force_passband_flag,stopband,SVDstopband,... 6 | % LFM,[],SNR2,Whitener) 7 | % 8 | % Makes a DeFleCT spatial filter with given passband and stopband. 9 | % passband: indices to sources for which the targeted output is 1 10 | % SVDpassband: how many components represent the passband (optional) 11 | % force_passband_flag: forces the output for all passband components to 1 12 | % stopband: indices to sources for which the output is 0 13 | % SVDstopband: how many components represent the stopband (optional) 14 | % LFM: forward model 15 | % C: noise covariance matrix (or measurement covariance matrix) 16 | % SNR2: assumed signal-to-noise ratio (for setting regularization) 17 | % Csvdtrunc: number of truncated singular values for the inversion of C. 18 | % Whitener: the whitener that is applied to the leadfields (optional; if C 19 | % is given, the whitener is built from C) 20 | % 21 | % L, C, SNR2, Csvdtrunc/Whitener need to be given only, when any of these 22 | % parameters changes 23 | % 24 | % This function is implemented according to: 25 | % Hauk and Stenroos: A Framework for the Design of Flexible Cross-Talk 26 | % Functions for Spatial Filtering of EEG/MEG Data: DeFleCT. HBM 2013. 27 | % 28 | % Copyright (c) 2012--2013 Matti Stenroos (matti.stenroos@aalto.fi) 29 | % -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30 | % !! There is no warranty of any kind !! 31 | % -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 32 | % 17 Oct 2013 33 | 34 | 35 | persistent Sinv L Nch Ns W 36 | if nargin>5 37 | [Nch,Ns]=size(LFM); 38 | if length(Csvdtrunc)==1 39 | W=MakeWhitener(C,Csvdtrunc); 40 | else 41 | W=Csvdtrunc; 42 | end 43 | L=W*LFM;%persistent 44 | lambda2=trace(L*L')/(Nch*SNR2); 45 | S=L*L'+lambda2*eye(Nch); 46 | Sinv=inv(S);%persistent 47 | end 48 | 49 | 50 | %how many indices in the stopband and passband 51 | if nargin>3, Nstop=length(stopband);end 52 | Npass=length(passband); 53 | 54 | if nargin<3 || isempty(force_passband_flag), force_passband_flag=0;end 55 | 56 | %Build projector P, wP=i strictly. 57 | %if force_passband_flag, then set wP=1 for the passband vector, else leave 58 | %passband out. 59 | Ppass=L(:,passband); 60 | Pstop=L(:,stopband); 61 | 62 | %take svd components for the stopband 63 | if nargin>4 && ~isempty(SVDstopband) && SVDstopband1 && ~isempty(SVDpassband) && SVDpassband2 && force_passband_flag 76 | P=[Ppass Pstop]; 77 | i=zeros(1,Npass+Nstop); 78 | i(1:Npass)=1; 79 | else 80 | P=Pstop; 81 | i=zeros(1,Nstop); 82 | end 83 | %make passband-vector for "traditional" minimisation 84 | t=zeros(1,Ns); 85 | if ~force_passband_flag 86 | t(passband)=1; 87 | end 88 | % and make the final minimiser 89 | % Pinv=inv(P'*Sinv*P); 90 | % term2=(i-t*L'*Sinv*P)*Pinv*P'; 91 | term2=(i-t*L'*Sinv*P)/(P'*Sinv*P)*P'; 92 | w=(t*L'+term2)*Sinv*W; 93 | 94 | function [W,deW]=MakeWhitener(C,trunc) 95 | % function [W,deW]=MakeWhitener(C,trunc) 96 | % Computes whitener C^(-1/2) and de-whitener sqrt(C) 97 | % trunc: how many smallest eigenvalues are set to zero before inversion 98 | % (all other regularization has to be applied to C before calling this 99 | % routine) 100 | % 101 | % Copyright (c) 2012--2013 Matti Stenroos (matti.stenroos@aalto.fi) 102 | % -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 103 | % !! There is no warranty of any kind !! 104 | % -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 105 | % version 130610 106 | if min(size(C))==1, 107 | C=diag(diag(C)); 108 | end 109 | 110 | [U,D]=eig(C); 111 | [ds,sortind]=sort(diag(D)); 112 | if trunc 113 | ds(1:trunc)=0; 114 | end 115 | Us=U(:,sortind); 116 | dsinv=zeros(size(ds)); 117 | dsinv((trunc+1):end)=1./ds((trunc+1):end); 118 | W=Us*diag(sqrt(dsinv))*Us'; 119 | 120 | if nargout==2 121 | deW=U*diag(sqrt(diag(D)))*Us'; 122 | end 123 | -------------------------------------------------------------------------------- /private/GALA_calculate_distance.m: -------------------------------------------------------------------------------- 1 | function distance = GALA_calculate_distance(mesh) 2 | 3 | Vertices = mesh.Vertices; 4 | Faces = mesh.Faces; 5 | 6 | %first hemisphere 7 | A = spm_mesh_distmtx(struct('vertices',Vertices,'faces',Faces),0); 8 | A = A(1:length(Vertices)/2,1:length(Vertices)/2); 9 | AA = A; 10 | B = A+speye(length(Vertices)/2); 11 | DD1 = full(A); 12 | i=2; 13 | while ~all(all(DD1+eye(length(Vertices)/2))) 14 | AA = AA*A; 15 | in = find(AA); 16 | Bn=zeros(length(Vertices)/2,length(Vertices)/2); 17 | Bn(in)=1; 18 | D=full(Bn-B); 19 | B=Bn; 20 | DD1 = DD1+i*D; 21 | i=i+1; 22 | end 23 | 24 | %second hemisphere 25 | A = spm_mesh_distmtx(struct('vertices',Vertices,'faces',Faces),0); 26 | A = A(length(Vertices)/2+1:length(Vertices),length(Vertices)/2+1:length(Vertices)); 27 | AA = A; 28 | B = A+speye(length(Vertices)/2); 29 | DD2 = full(A); 30 | i=2; 31 | while ~all(all(DD2+eye(length(Vertices)/2))) 32 | AA = AA*A; 33 | in = find(AA); 34 | Bn=zeros(length(Vertices)/2,length(Vertices)/2); 35 | Bn(in)=1; 36 | D=full(Bn-B); 37 | B=Bn; 38 | DD2 = DD2+i*D; 39 | i=i+1; 40 | end 41 | 42 | distance = Inf*ones(length(Vertices),length(Vertices)); 43 | distance(1:length(Vertices)/2,1:length(Vertices)/2)=DD1; 44 | distance(length(Vertices)/2+1:length(Vertices),length(Vertices)/2+1:length(Vertices))=DD2; 45 | 46 | return 47 | 48 | -------------------------------------------------------------------------------- /private/GALA_find_localmin.m: -------------------------------------------------------------------------------- 1 | function regions = GALA_find_localmin(lJcov,Nl,Nd,A,thresh) 2 | 3 | 4 | for p=1:Nl % loop by persons 5 | 6 | lJcovp{p}=lJcov(1+(p-1)*Nd:Nd+(p-1)*Nd); % separate for individual person 7 | 8 | [slJcovp, islJcovp] = sort(lJcovp{p},'descend'); 9 | Aip = A(islJcovp,islJcovp); % reindex adjacency matrix 10 | slJcovp(slJcovp<=thresh*max(slJcovp)) = 0; % set zero (and negative) values to -1 11 | 12 | % find boundary of basins for every local maximum 13 | 14 | nclb = 0; % initialize number of blobs 15 | bound = []; 16 | 17 | Ndd = length(find(slJcovp>0)); % number of nonzero vertices 18 | 19 | for j=1:Ndd % loop by nonzero vertices 20 | 21 | % find vertices above slJcovp(j) 22 | up = spdiags(slJcovp'>=slJcovp(j),0,length(Aip),length(Aip)); 23 | 24 | reg = up*Aip*up; % adjacency matrix above slJcovp(j) 25 | [v_cl,cl_sz]=get_components(reg); % get connected components 26 | 27 | cll=find(cl_sz >= 2); % find indices of blobs (blob is >=2 anjacent vertices) 28 | 29 | % check if current vertex joins blobs 30 | % i.e. reduces number of blobs and is not disconnected (for 31 | % equal values) 32 | if length(cll)1 33 | % then this vertex is boundary vertex 34 | bound = [bound; j]; 35 | slJcovp(j) = 0; % set boundary vertex to zero 36 | else 37 | nclb=length(cll); % else update number of blobs 38 | % we must not change the number of blobs for boundary vertex 39 | % because it removed (set to zero) from vertices above the 40 | % threshold and so nclb stay the same 41 | end 42 | end 43 | 44 | % find indices of clusters and local maxima 45 | 46 | maxsp = []; 47 | 48 | up = spdiags(slJcovp'>0,0,length(Aip),length(Aip)); 49 | reg = up*Aip*up; 50 | [v_cl,cl_sz]=get_components(reg); 51 | cllp{p}=find(cl_sz >= 2); 52 | 53 | clviA=[]; 54 | for i=1:length(cllp{p}) 55 | clvi{p,i} = find(v_cl==cllp{p}(i)); 56 | [nu mi] = max(slJcovp(clvi{p,i})); 57 | maxsp = [maxsp; clvi{p,i}(mi)]; 58 | clviA = [clviA clvi{p,i}]; 59 | end 60 | 61 | maxs{p} = maxsp; 62 | 63 | % add boundary vertices to appropriate cluster 64 | 65 | A0=Aip-eye(length(Aip)); % direct neighbors matrix 66 | for i=1:length(bound) % loop by all boudary vertices 67 | 68 | neib = find(A0(:,bound(i))); % direct neighbors of current verex 69 | 70 | cln = Inf; % initialize number of appropriate cluster 71 | 72 | for j=1:length(neib) % loop by all neighbors 73 | % find cluster index for current neighbor 74 | ind = find(cllp{p}==v_cl(neib(j))); 75 | % if there is no cluster set ind to Inf 76 | if isempty(ind); 77 | ind = Inf; 78 | end 79 | % choose minimum of cluster numbers providing clusters with 80 | % bigger local maximum (less index) have priority 81 | cln = min(cln,ind); 82 | end 83 | % add vertex to the cluster with cln number 84 | clvi{p,cln}=sort([clvi{p,cln} bound(i)]); 85 | end 86 | clviAb = sort([clviA bound']); 87 | 88 | % reindex back all indices 89 | for i=1:length(cllp{p}) 90 | regions.clvi{p,i} = islJcovp(clvi{p,i}); 91 | end 92 | regions.boundp{p} = islJcovp(bound); 93 | regions.maxs{p} = islJcovp(maxs{p}); 94 | regions.clviAp{p} = islJcovp(clviAb); 95 | 96 | end 97 | -------------------------------------------------------------------------------- /private/MNestimator.m: -------------------------------------------------------------------------------- 1 | function [Linv,W]=MNestimator(L,C,SNR2,trunc) 2 | % function [Linv,W]=MNestimator(L,C,SNR2,trunc) 3 | % This function makes a basic minimum-morm pseudoinverse operator = MN estimator. 4 | % - L: the forward solution, lead-field matrix 5 | % - C: noise covariance matrix 6 | % This is used for combining different sensortypes, whitening the 7 | % data and setting the regularisation parameter. If C is empty, it is 8 | % assumed eye matrix --- that would be the basic Tikhonov 0 9 | % regularization for one sensortype. 10 | % - SNR2: the assumed ratio of variances of signal and noise, used for 11 | % setting the regularisation parameter. 12 | % - trunc: the number of (smallest) singular values of C that are set to 13 | % zero before making the whitener. For example, if the data / C has 14 | % been SSP-projected, "trunc" needs to be at least the number of 15 | % components projected away. 16 | % 17 | % The whitening/regularization approach of this routine follows that used in 18 | % the MNE software, 19 | % http://martinos.org/mne/, 20 | % http://www.martinos.org/meg/manuals/MNE-manual-2.7.pdf 21 | % --- the influence of MNE software on this function is fully acknowledged! 22 | % 23 | % Copyright (c) 2011--2013 Matti Stenroos (matti.stenroos@aalto.fi) 24 | % -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 25 | % !! There is no warranty of any kind !! 26 | % -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 27 | % 17 Oct 2013 28 | Nsens=size(L,1); 29 | 30 | if nargin==3 || isempty(trunc) 31 | trunc=0; 32 | end 33 | if isempty(C) 34 | C=eye(Nsens); 35 | end 36 | 37 | W=MakeWhitener(C,trunc); 38 | 39 | LW=W*L; 40 | lambda2=trace(LW*LW')/(Nsens*SNR2); 41 | temp=LW*LW'+lambda2*eye(Nsens); 42 | Linv=LW'/temp*W; 43 | 44 | function [W,deW]=MakeWhitener(C,trunc) 45 | % function [W,deW]=MakeWhitener(C,trunc) 46 | % Computes whitener C^(-1/2) and de-whitener sqrt(C) 47 | % trunc: how many smallest eigenvalues are set to zero before inversion 48 | % (all other regularization has to be applied to C before calling this 49 | % routine) 50 | % 51 | % Copyright (c) 2011--2013 Matti Stenroos (matti.stenroos@aalto.fi) 52 | % -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 53 | % !! There is no warranty of any kind !! 54 | % -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 55 | % version 130610 56 | if min(size(C))==1, 57 | C=diag(diag(C)); 58 | end 59 | 60 | [U,D]=eig(C); 61 | [ds,sortind]=sort(diag(D)); 62 | if trunc 63 | ds(1:trunc)=0; 64 | end 65 | Us=U(:,sortind); 66 | dsinv=zeros(size(ds)); 67 | dsinv((trunc+1):end)=1./ds((trunc+1):end); 68 | W=Us*diag(sqrt(dsinv))*Us'; 69 | 70 | if nargout==2 71 | deW=U*diag(sqrt(diag(D)))*Us'; 72 | end 73 | 74 | -------------------------------------------------------------------------------- /private/Tikhonov_rank_def.m: -------------------------------------------------------------------------------- 1 | function matreg = Tikhonov_rank_def(mat, rank, lambda) 2 | 3 | % Apply Tikhonov regularisation to rank-deficient matrix 4 | 5 | % mat: square matrix 6 | 7 | % rank: number of singular values to be considered in inversion 8 | 9 | % lambda: regularisation parameters 10 | 11 | % OH, Sep 2018 12 | 13 | 14 | % SVD of input matrix 15 | 16 | [U,S,V] = svd(mat); 17 | 18 | 19 | % get singular values 20 | 21 | s = diag(S); 22 | 23 | 24 | % take only relevant values 25 | 26 | s2 = s(1:rank); 27 | 28 | 29 | lambda = (lambda/100) * (sum(s2)/rank); 30 | 31 | % regularise eigenvalues with Tikhonov and invert 32 | 33 | s2 = s2 ./ (s2.^2 + lambda); 34 | 35 | 36 | % reconstitute regularised inverse matrix 37 | 38 | matreg = V(:,1:rank)*diag(s2)*U(:,1:rank)'; -------------------------------------------------------------------------------- /private/bf_fuse_lf.m: -------------------------------------------------------------------------------- 1 | function [L, channels] = bf_fuse_lf(BF, modality) 2 | % Prepares lead-fields to match channels in covariance 3 | % Copyright (C) 2014 Wellcome Trust Centre for Neuroimaging 4 | 5 | % Vladimir Litvak 6 | % $Id$ 7 | 8 | D = BF.data.D; 9 | 10 | L = cell(size(BF.sources.L.(modality(1:3)))); 11 | channels = cell(length(BF.features.(modality).chanind), 1); 12 | 13 | [sel1, sel2] = spm_match_str(D.chanlabels(BF.features.(modality).chanind),... 14 | BF.sources.channels.(modality(1:3))); 15 | 16 | nlfcolumns = max(cellfun('size', BF.sources.L.(modality(1:3)), 2)); 17 | 18 | channels(sel1) = BF.sources.channels.(modality(1:3))(sel2); 19 | 20 | % This is for MEG-EEG fusion 21 | if isequal(modality, 'MEG') && length(sel1) 100, Ibar = floor(linspace(1, numel(L),100)); 33 | else Ibar = 1:numel(L); end 34 | 35 | for i = 1:numel(L) 36 | if ~isnan(BF.sources.L.(modality(1:3)){i}) 37 | L{i} = nan(length(BF.features.(modality).chanind), nlfcolumns); 38 | L{i}(sel1, :) = BF.sources.L.(modality(1:3)){i}(sel2, :); 39 | 40 | if fuse 41 | L{i}(sel3, :) = BF.sources.L.('EEG'){i}(sel4, :); 42 | end 43 | else 44 | L{i} = nan; 45 | end 46 | 47 | if ismember(i, Ibar) 48 | spm_progress_bar('Set', i); drawnow; 49 | end 50 | end 51 | 52 | spm_progress_bar('Clear') -------------------------------------------------------------------------------- /private/gen_bf_ttest.m: -------------------------------------------------------------------------------- 1 | 2 | function [t_stat,B,SE,F_stat] = gen_bf_ttest(X,Y,c,U) 3 | % Run a t-test 4 | 5 | if nargin<4, 6 | U=[]; 7 | end; 8 | if isempty(U), 9 | U=eye(size(Y,2)); 10 | end; 11 | 12 | X0 = X - X*c*pinv(c); %% make sure X0 is orthogonal to X 13 | Xred = full(X*c); %% reduced design matrix 14 | X0 = spm_svd(X0); %% X0 is null space i.e. everything that is happening in other columns of X 15 | 16 | % ========================================================================== 17 | % remove null space of contrast 18 | %-------------------------------------------------------------------------- 19 | Y = Y - X0*(X0'*Y); %% eg remove DC level or drift terms from all of Y 20 | Xred = Xred - X0*(X0'*Xred); 21 | 22 | P = pinv(Xred); 23 | 24 | 25 | [n,b] = size(Xred); 26 | [n,m] = size(Y); %% n is number of epochs, m is number of features 27 | b = rank(Xred); 28 | h = min(b,m); %% either number of features or rank of X 29 | 30 | Ym=mean(Y,2); 31 | B = pinv(Xred)*Ym; 32 | RSS = sum((Ym - Xred*B).^2); 33 | MRSS = RSS / (n-b); 34 | SE = sqrt(MRSS*(pinv(Xred'*Xred))); 35 | t_stat=B./SE; 36 | F_stat=(B./SE).^2; 37 | 38 | 39 | 40 | 41 | 42 | 43 | end 44 | 45 | -------------------------------------------------------------------------------- /private/get_components.m: -------------------------------------------------------------------------------- 1 | function [comps,comp_sizes] = get_components(adj) 2 | %GET_COMPONENTS connected components 3 | % 4 | % [comps,comp_sizes] = get_components(adj); 5 | % 6 | % Returns the components of an undirected graph specified by the binary and 7 | % undirected adjacency matrix adj. Components and their constitutent nodes are 8 | % assigned the same index and stored in the vector, comps. The vector, comp_sizes, 9 | % contains the number of nodes beloning to each component. 10 | % 11 | % Inputs: adj, binary and undirected adjacency matrix 12 | % 13 | % Outputs: comps, vector of component assignments for each node 14 | % comp_sizes, vector of component sizes 15 | % 16 | % Note: disconnected nodes will appear as components with a component 17 | % size of 1 18 | % 19 | % J Goni, University of Navarra and Indiana University, 2009/2011 20 | 21 | 22 | if size(adj,1)~=size(adj,2) 23 | error('this adjacency matrix is not square'); 24 | end 25 | 26 | if ~any(adj-triu(adj)) 27 | adj = adj | adj'; 28 | end 29 | 30 | %if main diagonal of adj do not contain all ones, i.e. autoloops 31 | if sum(diag(adj))~=size(adj,1) 32 | 33 | %the main diagonal is set to ones 34 | adj = adj|speye(size(adj)); 35 | end 36 | 37 | %Dulmage-Mendelsohn decomposition 38 | [useless1,p,useless2,r] = dmperm(adj); 39 | 40 | %p indicates a permutation (along rows and columns) 41 | %r is a vector indicating the component boundaries 42 | 43 | % List including the number of nodes of each component. ith entry is r(i+1)-r(i) 44 | comp_sizes = diff(r); 45 | 46 | % Number of components found. 47 | num_comps = numel(comp_sizes); 48 | 49 | % initialization 50 | comps = zeros(1,size(adj,1)); 51 | 52 | % first position of each component is set to one 53 | comps(r(1:num_comps)) = ones(1,num_comps); 54 | 55 | % cumulative sum produces a label for each component (in a consecutive way) 56 | comps = cumsum(comps); 57 | 58 | %re-order component labels according to adj. 59 | comps(p) = comps; 60 | -------------------------------------------------------------------------------- /private/get_data_features.m: -------------------------------------------------------------------------------- 1 | 2 | function [trialfeatures,vedata]=get_data_features(flatpepdata,Nbins,Ntrials,weights,Tfull,datatype,featureind,regressout) 3 | 4 | %%% put data in form for mv test 5 | %% options are datatye 6 | %% {'peakabs','peakreal','peakimag','peaksin','peakcos','sumpower'}; 7 | %% datatype=pwr power (re^2+comp^2) 8 | %% datatpe=pwrsincos: power+sin and cos terms 9 | %% datatype=4: 10 | %% if weights==-1 just set up static variables depnding on datatype 11 | %% 12 | flagnames={'peakabs','peakreal','peakimag','peaksin','peakcos','sumpower'}; 13 | 14 | if nargin==0, %% for menu 15 | trialfeatures=flagnames; 16 | return; 17 | end; 18 | 19 | if nargin<8 20 | regressout=[]; 21 | end; 22 | 23 | persistent colflags 24 | 25 | 26 | Nfeaturebands=numel(featureind); %% number of bands to take features from 27 | %Ntrials=size(allepdata,1); 28 | Nchans=size(flatpepdata,2); 29 | %Nbins=size(allepdata,3); 30 | 31 | 32 | if weights==-1, 33 | colflags=zeros(1,numel(flagnames)); 34 | disp('using the following features per band'); 35 | for f=1:numel(flagnames), 36 | colflags(f)=~isempty(findstr(datatype,flagnames{f})); 37 | if colflags(f), 38 | disp(sprintf('%s',flagnames{f})); 39 | end; 40 | end; 41 | 42 | trialfeatures=[]; 43 | return; 44 | end; % if weights=-1 45 | 46 | fperbandind=find(colflags); 47 | Nfperband=length(fperbandind); 48 | 49 | trialfeatures=zeros(Ntrials,Nfeaturebands*Nfperband); 50 | 51 | 52 | vedata=flatpepdata*weights'; 53 | vedata=vedata-mean(vedata); 54 | if ~isempty(regressout), 55 | %keyboard; 56 | [B,BINT,residuals,rint,stats] = regress(vedata,[regressout ones(size(regressout)).*std(regressout)]); 57 | vedata=residuals; 58 | if stats(1)==1, %% r squared is equal to one, i.e. 100% variance explained 59 | disp('replacing perfectly predicted data with random sequence') 60 | vedata=randn(size(vedata)); 61 | end; 62 | end; 63 | trialvedata=(reshape(vedata,Nbins,Ntrials))'; 64 | 65 | trialvedata=trialvedata-repmat(mean(trialvedata,2),1,Nbins); %% remove mean 66 | trialvedata=trialvedata.*repmat(spm_hanning(Nbins)',Ntrials,1); %% window 67 | 68 | features=zeros(Ntrials,Nfperband); 69 | for f=1:Nfeaturebands, 70 | Tband=Tfull(:,featureind{f}); % filter to this band 71 | 72 | dcttrialdata=trialvedata*Tband; %% frequency representation 73 | ftrialdata=dcttrialdata*Tband'; %% filter data 74 | 75 | Ff=fft(ftrialdata'); 76 | meanpower=mean(abs(Ff')); %% get bin with highest power and use the phase from this 77 | [maxval,maxbin]=max(meanpower(round(1:length(meanpower)/2)+1)); %% only take 1st half 78 | 79 | features(1:Ntrials,1)=abs(Ff(maxbin,:))'; %% could use mean or peak 80 | features(1:Ntrials,2)=real(Ff(maxbin,:))'; 81 | features(1:Ntrials,3)=imag(Ff(maxbin,:))'; 82 | features(1:Ntrials,4)=sin(angle(Ff(maxbin,:)))'; 83 | features(1:Ntrials,5)=cos(angle(Ff(maxbin,:)))'; 84 | 85 | features(1:Ntrials,6)=sum(Ff.*conj(Ff))'; 86 | trialfeatures(1:Ntrials,(f-1)*Nfperband+1:f*Nfperband)=features(1:Ntrials,fperbandind); 87 | 88 | end; % for f 89 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /private/mkfilt_eloreta_v2.m: -------------------------------------------------------------------------------- 1 | function A=mkfilt_eloreta_v2(L,regu); 2 | % makes spatial filter according to eLoreta 3 | % usage A=mkfilt_eloreta_v2(L); or A=mkfilt_eloreta_v2(L,regu); 4 | % 5 | % input L: NxMxP leadfield tensor for N channels, M voxels, and 6 | % P dipole directions. Typically P=3. (If you do MEG for 7 | % a spherical volume conductor or reduce the rank, you must 8 | % reduce L such that it has full rank for each voxel, such that, 9 | % e.g., P=2) 10 | % regu: optional regularization parameter (default is .05 corresponding 11 | % to 5% of the average of the eigenvalues of some matrix to be inverted.) 12 | % 13 | % output A: NxMxP tensor of spatial filters. If x is the Nx1 data vector at time t. 14 | % then A(:,m,p)'*x is the source activity at time t in voxel m in source direction 15 | % p. 16 | % 17 | % code implemented by Guido Nolte 18 | % please cite 19 | % R.D. Pascual-Marqui: Discrete, 3D distributed, linear imaging methods of electric neuronal activity. Part 1: exact, zero 20 | % error localization. arXiv:0710.3341 [math-ph], 2007-October-17, http://arxiv.org/pdf/0710.3341 21 | 22 | if nargin<2;regu=.05;end 23 | 24 | [nchan ng ndum]=size(L); 25 | LL=zeros(nchan,ndum,ng); 26 | for i=1:ndum; 27 | LL(:,i,:)=L(:,:,i); 28 | end 29 | LL=reshape(LL,nchan,ndum*ng); 30 | 31 | u0=eye(nchan); 32 | W=reshape(repmat(eye(ndum),1,ng),ndum,ndum,ng); 33 | Winv=zeros(ndum,ndum,ng); 34 | winvkt=zeros(ng*ndum,nchan); 35 | kont=0; 36 | kk=0; 37 | while kont==0; 38 | kk=kk+1; 39 | for i=1:ng; 40 | Winv(:,:,i)=(inv(W(:,:,i)+trace(W(:,:,i))/(ndum*10^6))); 41 | %if i==ng;disp(W(:,:,i));end 42 | end 43 | for i=1:ng; 44 | %winvkt(i,:,:)=Winv(:,:,i)*(squeeze(LL(:,:,i)))'; 45 | %winvkt(i,:,:)=(squeeze(LL(:,:,i)))'; 46 | winvkt(ndum*(i-1)+1:ndum*i,:)=Winv(:,:,i)*LL(:,ndum*(i-1)+1:ndum*i)'; 47 | end 48 | kwinvkt=LL*winvkt; 49 | %kwinvkt(1:4,1:4) 50 | 51 | alpha=regu*trace(kwinvkt)/nchan; 52 | M=inv(kwinvkt+alpha*u0); 53 | 54 | [ux,sx,vx]=svd(kwinvkt); 55 | %disp(sx(1,1)/alpha) 56 | 57 | for i=1:ng; 58 | Lloc=squeeze(L(:,i,:)); 59 | Wold=W; 60 | W(:,:,i)=sqrtm(Lloc'*M*Lloc); 61 | end 62 | reldef=(norm(reshape(W,[],1)-reshape(Wold,[],1))/norm(reshape(Wold,[],1))); 63 | %disp(reldef) 64 | if kk>20 | reldef< .000001 ; kont=1;end; 65 | end 66 | %disp(kk) 67 | 68 | ktm=LL'*M; 69 | %ktm=reshape(ktm,ng,ndum,nchan); 70 | A=zeros(nchan,ng,ndum); 71 | 72 | for i=1:ng; 73 | A(:,i,:)=(Winv(:,:,i)*ktm(ndum*(i-1)+1:ndum*i,:))'; 74 | end 75 | return 76 | -------------------------------------------------------------------------------- /private/nut_dSPM.m: -------------------------------------------------------------------------------- 1 | function [weight]=nut_dSPM(Lp,data, flags) %--------------------------------------------------------- 2 | % [weight,eta]=nut_dSPM(Lp,data,flags) 3 | % Lp : lead field 4 | % inputs for regularization contant: 5 | % [1] data.Ryy = sample covariance, for data-dependent regularization 6 | % [2] flags.gamma = user defined regularization constant, or 'auto' for 7 | % leadfield-based regularization 8 | 9 | if nargin<3, flags.gamma=[]; end 10 | 11 | L = reshape(Lp,size(Lp,1),size(Lp,2)*size(Lp,3)); 12 | G = L*L'; clear L 13 | 14 | if isfield(flags,'snr') 15 | if ~isfield(data,'C') || isempty(data.C) 16 | data.C = eye(size(data.Ryy)); 17 | end 18 | gamma = trace(G)/(trace(data.C)*flags.snr^2) 19 | InvG = inv(G+gamma*data.C); 20 | elseif ~isfield(flags,'gamma') || isempty(flags.gamma) 21 | gamma = 1e0*max(eig(data.Ryy)) 22 | InvG = inv(G+gamma*eye(size(G))); 23 | elseif isnumeric(flags.gamma) 24 | gamma = flags.gamma %* max(eig(data.Ryy)) 25 | InvG = inv(G+gamma*eye(size(G))); 26 | else 27 | % leadfield-based normalization 28 | doplot=false; 29 | x = [-20:20]; 30 | gamma=10.^x; %.* max(eig(data.Ryy)); 31 | numg = length(gamma); 32 | InvG = zeros([size(G) numg]); 33 | meanuptr = zeros(numg,1); 34 | warning('off','MATLAB:nearlySingularMatrix') 35 | for k=1:numg 36 | InvG(:,:,k) = inv(G+gamma(k)*eye(size(G))); 37 | uptr = abs(triu(InvG(:,:,k),1)); 38 | meanuptr(k) = mean(uptr( find(uptr(:)) )); % mean of matrix without diagonal 39 | end 40 | warning('on','MATLAB:nearlySingularMatrix') 41 | if doplot, figure; plot(x(1:end-2),-diff(diff(log10(meanuptr)))); end 42 | [dum,idx]=findpeaks(-diff(diff(log10(meanuptr))),'MINPEAKHEIGHT',.1); % max of second derivation of InvG across gamma magnitudes 43 | idx = max(idx); 44 | fprintf('Optimal gamma: 1e%d\n',x(idx)); 45 | InvG = InvG(:,:,idx); 46 | end 47 | 48 | InvG2=InvG^2; 49 | 50 | Lp1 = squeeze(Lp(:,1,:)); 51 | w1 = zeros(size(Lp1)); 52 | if size(Lp,2)>1 53 | Lp2 = squeeze(Lp(:,2,:)); 54 | w2 = zeros(size(Lp2)); 55 | end 56 | if size(Lp,2)>2 57 | Lp3 = squeeze(Lp(:,3,:)); 58 | w3 = zeros(size(Lp3)); 59 | end 60 | 61 | for i=1:size(Lp,3) 62 | InvGLp = InvG*Lp1(:,i); 63 | InvG2Lp = InvG2*Lp1(:,i); 64 | J = inv(sqrt(trace(Lp1(:,i)'*InvG2Lp))); 65 | w1(:,i) = InvGLp * J; 66 | 67 | if size(Lp,2)>1 68 | InvGLp = InvG*Lp2(:,i); 69 | InvG2Lp = InvG2*Lp2(:,i); 70 | J = inv(sqrt(trace(Lp2(:,i)'*InvG2Lp))); 71 | w2(:,i) = InvGLp * J; 72 | end 73 | 74 | if size(Lp,2)>2 75 | InvGLp = InvG*Lp3(:,i); 76 | InvG2Lp = InvG2*Lp3(:,i); 77 | J = inv(sqrt(trace(Lp3(:,i)'*InvG2Lp))); 78 | w3(:,i) = InvGLp * J; 79 | end 80 | end 81 | 82 | weight(:,1,:) = w1; 83 | if size(Lp,2)>1 84 | weight(:,2,:) = w2; 85 | end 86 | if size(Lp,2)>2 87 | weight(:,3,:) = w3; 88 | end 89 | disp('done'); 90 | % end 91 | -------------------------------------------------------------------------------- /private/nut_sLORETA.m: -------------------------------------------------------------------------------- 1 | function [weight]=nut_sLORETA(Lp,data,flags) 2 | % weight=nut_sLORETA(Lp,data,flags) 3 | % inputs for regularization contant: 4 | % [1] data.Ryy = sample covariance, for data-dependent regularization 5 | % [2] flags.gamma = user defined regularization constant, or 'auto' for 6 | % leadfield-based regularization 7 | 8 | if nargin<3, flags.gamma=[]; end 9 | 10 | L = reshape(Lp,size(Lp,1),size(Lp,2)*size(Lp,3)); 11 | G = L*L'; clear L 12 | 13 | if isfield(flags,'snr') 14 | if ~isfield(data,'C') || isempty(data.C) 15 | data.C = eye(size(data.Ryy)); 16 | end 17 | gamma = trace(G)/(trace(data.C)*flags.snr^2) 18 | InvG = inv(G+gamma*data.C); 19 | elseif ~isfield(flags,'gamma') || isempty(flags.gamma) 20 | gamma = 1e0*max(eig(data.Ryy)) 21 | InvG = inv(G+gamma*eye(size(G))); 22 | elseif isnumeric(flags.gamma) 23 | gamma = flags.gamma %* max(eig(data.Ryy)) 24 | InvG = inv(G+gamma*eye(size(G))); 25 | else 26 | % leadfield-based normalization 27 | doplot=false; 28 | x = [-20:20]; 29 | gamma=10.^x; %.* max(eig(data.Ryy)); 30 | numg = length(gamma); 31 | InvG = zeros([size(G) numg]); 32 | meanuptr = zeros(numg,1); 33 | warning('off','MATLAB:nearlySingularMatrix') 34 | for k=1:numg 35 | InvG(:,:,k) = inv(G+gamma(k)*eye(size(G))); 36 | uptr = abs(triu(InvG(:,:,k),1)); 37 | meanuptr(k) = mean(uptr( find(uptr(:)) )); % mean of matrix without diagonal 38 | end 39 | warning('on','MATLAB:nearlySingularMatrix') 40 | if doplot, figure; plot(x(1:end-2),-diff(diff(log10(meanuptr)))); end 41 | [dum,idx]=findpeaks(-diff(diff(log10(meanuptr))),'MINPEAKHEIGHT',.1); % max of second derivation of InvG across gamma magnitudes 42 | idx = max(idx); 43 | fprintf('Optimal gamma: 1e%d\n',x(idx)); 44 | InvG = InvG(:,:,idx); 45 | end 46 | 47 | Lp1 = squeeze(Lp(:,1,:)); 48 | w1 = zeros(size(Lp1)); 49 | if size(Lp,2)>1 50 | Lp2 = squeeze(Lp(:,2,:)); 51 | w2 = zeros(size(Lp2)); 52 | end 53 | if size(Lp,2)>2 54 | Lp3 = squeeze(Lp(:,3,:)); 55 | w3 = zeros(size(Lp3)); 56 | end 57 | 58 | for i=1:size(Lp,3) 59 | InvGLp = InvG*Lp1(:,i); 60 | J = inv(sqrt(Lp1(:,i)'*InvGLp)); 61 | w1(:,i) = InvGLp * J; 62 | 63 | if size(Lp,2)>1 64 | InvGLp = InvG*Lp2(:,i); 65 | J = inv(sqrt(Lp2(:,i)'*InvGLp)); 66 | w2(:,i) = InvGLp * J; 67 | end 68 | 69 | if size(Lp,2)>2 70 | InvGLp = InvG*Lp3(:,i); 71 | J = inv(sqrt(Lp3(:,i)'*InvGLp)); 72 | w3(:,i) = InvGLp * J; 73 | end 74 | end 75 | 76 | weight(:,1,:) = w1; 77 | if size(Lp,2)>1 78 | weight(:,2,:) = w2; 79 | end 80 | if size(Lp,2)>2 81 | weight(:,3,:) = w3; 82 | end 83 | disp('done'); 84 | % end 85 | -------------------------------------------------------------------------------- /private/nut_swLORETA.m: -------------------------------------------------------------------------------- 1 | function [weight]=nut_swLORETA(Lp,data,flags) 2 | % [weight,eta]=nut_swLORETA(Lp,data,flags) 3 | % Lp : lead field ( channels X 3 ) 4 | % specify either: 5 | % [1] data.Ryy (sample covariance) normally required (used for data-dependent regularization) 6 | % currently sets gamma = max(eig(data.Ryy)) 7 | % [probably should be set lower for best compromise between stability and blurriness] 8 | % [2] flags.gamma = regularization constant [optional] 9 | 10 | warning('BEWARE: not sure if algorithm is faithfully reproduced here, as paper is a little confusing'); 11 | 12 | L = reshape(Lp,size(Lp,1),size(Lp,2)*size(Lp,3)); 13 | G = L*L'; 14 | 15 | clear L; 16 | 17 | if(isfield(flags,'gamma')) 18 | gamma = flags.gamma; 19 | else 20 | gamma = 1e0*max(eig(data.Ryy)); % data-dependent regularization 21 | end 22 | 23 | 24 | InvG = inv(G+gamma*eye(size(G))); 25 | 26 | % specific to swLORETA 27 | %%%%% Lsig is equivalent to norm(Lp(:,:,i)) !!! 28 | % Lsig = sparse(size(Lp,3),size(Lp,3)); 29 | % for i=1:size(Lp,3) 30 | % [u,s,v]=svd(Lp(:,:,i),'econ'); 31 | % Lsig(i,i) = s(1,1); 32 | % end 33 | % sqrtSj=(kron(inv(sqrt(Lsig)),eye(3))); 34 | % 35 | % weight=zeros(size(Lp)); 36 | % for i=1:size(Lp,3) 37 | % weight(:,:,i) = InvG*Lp(:,1:3,i) * inv(sqrtSj((3*i-2):(3*i),(3*i-2):(3*i))); 38 | % end 39 | 40 | weight=zeros(size(Lp)); 41 | for i=1:size(Lp,3) 42 | invsqrtnormL = (norm(Lp(:,:,i))).^-.5; 43 | weight(:,:,i) = InvG*Lp(:,:,i)*invsqrtnormL; 44 | end 45 | 46 | 47 | 48 | % weight = reshape(w,size(Lp)); 49 | 50 | disp('done'); 51 | % end 52 | -------------------------------------------------------------------------------- /private/output_image_mv_cva.m: -------------------------------------------------------------------------------- 1 | function [chi,BIC,cva] = output_image_mv_cva(X,Y,c,U) 2 | %% cva code to plug into bf_output_image_mv function 3 | %function [chi,cva,t_stat] = bf_output_image_mv_cva(X,Y,c,U) 4 | % CVA. See Chatfield and Collins 5 | 6 | if nargin<4, 7 | U=[]; 8 | end; 9 | 10 | if isempty(U), 11 | U=eye(size(Y,2)); 12 | end; 13 | 14 | X0 = X - X*c*pinv(c); %% make sure X0 is orthogonal to X 15 | Xred = full(X*c); %% reduced design matrix 16 | X0 = spm_svd(X0); %% X0 is null space i.e. everything that is happening in other columns of X 17 | 18 | %-Canonical Variates Analysis 19 | % ========================================================================== 20 | % remove null space of contrast 21 | %-------------------------------------------------------------------------- 22 | Y = Y - X0*(X0'*Y); %% eg remove DC level or drift terms from all of Y 23 | Xred = Xred - X0*(X0'*Xred); 24 | %% Xred=X*c-X0*(X0'*X*c) 25 | 26 | P = pinv(Xred); 27 | 28 | 29 | [n,b] = size(Xred); 30 | [n,m] = size(Y); %% n is number of epochs, m is number of features 31 | b = rank(Xred); 32 | h = min(b,m); %% either number of features or rank of X 33 | f = n - b - size(X0,2); %% number of epochs- rank(X) - number of confounds 34 | 35 | 36 | % generalised eigensolution for treatment and residual sum of squares 37 | %-------------------------------------------------------------------------- 38 | T = Xred*(P*Y); %% predticon of Y based on X (P*Y is the coefficient) 39 | 40 | SST = T'*T; 41 | SSR = Y - T; %% residuals in Y (unexplained by X) 42 | SSR = SSR'*SSR; 43 | 44 | [v,d] = eig(SSR\SST); %% explained/unexplained variance 45 | 46 | [q,r] = sort(-real(diag(d))); 47 | r = r(1:h); 48 | d = real(d(r,r)); 49 | v = real(v(:,r)); 50 | V = U*v; % canonical vectors (data) 51 | v = Y*v; % canonical variates (data) 52 | W = P*v; % canonical vectors (design) 53 | w = Xred*W; % canonical variates (design) 54 | % C = c*W; % canonical contrast (design) 55 | 56 | 57 | 58 | 59 | % inference on dimensionality - p(i) test of D >= i; Wilk's Lambda := p(1) 60 | %-------------------------------------------------------------------------- 61 | 62 | cval = log(diag(d) + 1); 63 | chi=[];df=[];p=[];p05thresh=[]; 64 | for i1 = 1:h 65 | chi(i1) = (f - (m - b + 1)/2)*sum(cval(i1:h)); 66 | df(i1) = (m - i1 + 1)*(b - i1 + 1); % m is the number of features, b is the rank of the design matrix 67 | p(i1) = 1 - spm_Xcdf(chi(i1),df(i1)); 68 | p05thresh(i1) = spm_invXcdf(1-0.05,df(i1)); 69 | end 70 | 71 | 72 | ccorr=(W'*Xred'*Y*V)/sqrt((W'*Xred'*Xred*W)*(V'*Y'*Y*V));%% canonical correlation 73 | ccorr=real(diag(ccorr)); 74 | BIC=n*log(1-ccorr.^2)+(b+m)*log(n); %http://www.sciencedirect.com/science/article/pii/S0167947311002660 75 | % Comparison of penalty functions for sparse canonical correlation 76 | % analysis, Chalise , Brooke , Fridley: Computational Statistics and Data 77 | % Analysis 2012, pp245-254 78 | %% d=p+q, where x=N*p, Y=N*q 79 | 80 | BIC=-0.5*BIC; %% to make this compatible with Model evidence estimates (see penny 2012) 81 | cva.ccorr=ccorr; 82 | cva.r=r; 83 | cva.d=d; 84 | cva.df=df; 85 | 86 | cva.V=V; 87 | cva.v=v; 88 | cva.W=W; 89 | cva.w=w; 90 | % cva.C=C; 91 | cva.p05thresh=p05thresh; 92 | 93 | 94 | end 95 | -------------------------------------------------------------------------------- /private/pinv_plus.m: -------------------------------------------------------------------------------- 1 | 2 | function [X, pca_order] = pinv_plus(A,varargin) 3 | % PINV_PLUS Modified Pseudoinverse which allows a specified 4 | % dimensionality (order) to be passed in. 5 | % 6 | % pinv_plus(A) is the same as pinv(A) 7 | % 8 | % [X, pca_order]=pinv_plus(A,pca_order) uses at most only the top pca_order PCs to compute inverse 9 | % 10 | % pinv_plus(A,pca_order,1) uses precisely the top pca_order PCs to compute inverse 11 | % 12 | % If pca_order=-1 then calls spm_pca_order to compute order to use 13 | % 14 | % Class support for input A: 15 | % float: double, single 16 | % 17 | % Mark Woolrich 18 | 19 | tol=[]; 20 | r=size(A,1); 21 | 22 | if nargin >= 2, 23 | pca_order = varargin{1}; 24 | if(pca_order==-1), 25 | pca_order=spm_pca_order(A); 26 | end; 27 | else 28 | pca_order = size(A,1); 29 | end; 30 | 31 | max_r=pca_order; 32 | 33 | if nargin >= 3, 34 | fix_to_max_r=varargin{2}; 35 | else 36 | fix_to_max_r=0; 37 | end; 38 | 39 | if isempty(A) % quick return 40 | X = zeros(size(A'),class(A)); 41 | return 42 | end 43 | 44 | % [U,S,V] = svd(A,0); s = diag(S); 45 | [m,n] = size(A); 46 | 47 | if n > m 48 | X = pinv(A',varargin{:})'; 49 | else 50 | if(max_r 1, s = diag(S); 60 | elseif m == 1, s = S(1); 61 | else s = 0; 62 | end 63 | 64 | tol=[]; 65 | 66 | if max_r < 0 67 | 68 | diffs=abs(diff(s)./s(1:end-1)); 69 | 70 | for i=2:length(diffs), 71 | if(diffs(i) > 6*mean(diffs(1:i))), 72 | break; 73 | end; 74 | end; 75 | 76 | max_r = i; 77 | 78 | %figure;plot(diffs);ho;plot(r,diffs(r),'*'); 79 | 80 | end; 81 | 82 | % max_r 83 | % fix_to_max_r 84 | 85 | if(fix_to_max_r==1), 86 | r=max_r; 87 | else, 88 | tol=max(m,n) * eps(max(s)); 89 | 90 | %tol=max(size(A)) * norm(A) * eps(class(A)); 91 | 92 | r = sum(s > tol); 93 | 94 | r = min(r,max_r); 95 | end; 96 | 97 | %figure;plot(s); 98 | 99 | s2=s; 100 | 101 | if (r == 0) 102 | X = zeros(size(A'),class(A)); 103 | else 104 | s = diag(ones(r,1)./s(1:r)); 105 | X = V(:,1:r)*s*U(:,1:r)'; 106 | end 107 | 108 | pca_order=r; 109 | 110 | end 111 | -------------------------------------------------------------------------------- /private/spm_pca_order.m: -------------------------------------------------------------------------------- 1 | function [M_opt,log_ev,lambda,var] = spm_pca_order (X, N) 2 | % Model order selection for PCA 3 | % FORMAT [M_opt,log_ev,lambda,var] = spm_pca_order (X, N) 4 | % 5 | % Model order selection for PCA using Minka's approximation to model evidence 6 | % Input can be 7 | % X Data 8 | % or 9 | % 10 | % X Covariance matrix 11 | % N number of samples used for computing X 12 | % 13 | % M_opt Optimum number of sources 14 | % log_ev Log Evidence 15 | % lambda Eigenspectrum 16 | % var Estimated observation noise (at M_opt) 17 | % 18 | % Algorithm: 19 | % 20 | % T.P. Minka. Automatic choice of dimensionality for PCA. Technical Report 21 | % 514, MIT Media Lab, Perceptual Computing Section, 2000. 22 | % 23 | % Evaluation: 24 | % 25 | % W. Penny, S. Roberts and R. Everson (2000) ICA: model order selection 26 | % and dynamic source models. ICA: Principles and Practice, pages 299-314. 27 | % Cambridge University Press. 28 | %___________________________________________________________________________ 29 | % Copyright (C) 2008 Wellcome Department of Imaging Neuroscience 30 | 31 | % Will Penny 32 | % $Id$ 33 | 34 | if nargin == 1 35 | [N,d]=size(X); 36 | if d > N 37 | X=X'; 38 | [N,d]=size(X); 39 | end 40 | X=X-ones(N,1)*mean(X); 41 | S=(1/N)*ctranspose(X)*X; %to also work for complex input 42 | else 43 | d = size(X, 1); 44 | S = X; 45 | end 46 | 47 | [w,lambda] = eig (S); 48 | lambda=diag(lambda); 49 | 50 | % Order eigenvectors/values 51 | lambda = sort(lambda); 52 | lambda = flipud(lambda); 53 | 54 | % Loop over possible number of sources 55 | for M=1:d-1, 56 | % Minka equation 50 57 | i=[1:1:M]; 58 | kk=(d-i+1)/2; 59 | term1=-M*log(2)+sum(gammaln(kk))+sum(-kk*log(pi)); 60 | term2=-0.5*N*sum(log(lambda(i))); 61 | var=mean(lambda(M+1:d)); 62 | term3=-0.5*N*(d-M)*log(var); 63 | little_m=d*M-M*(M+1)/2; 64 | term4=0.5*(little_m+M)*log(2*pi); 65 | 66 | lambda_hat=[lambda(1:M);var*ones(d-M,1)]; 67 | term5=0; 68 | for i=1:M, 69 | for j=i+1:d, 70 | term5=term5+log(1/lambda_hat(j)-1/lambda_hat(i))+log(lambda(i)-lambda(j))+ log(N); 71 | end 72 | end 73 | term5=-0.5*term5; 74 | term6=-0.5*M*log(N); 75 | 76 | % Minka equation 73 77 | log_ev(M)=term1+term2+term3+term4+term5+term6; 78 | end 79 | 80 | [max_ev,M_opt]=max(log_ev); 81 | 82 | var=mean(lambda(M_opt+1:d)); 83 | 84 | -------------------------------------------------------------------------------- /private/vbfa_aug2015.m: -------------------------------------------------------------------------------- 1 | function [Cov]=vbfa(y,nl,nem,fig) 2 | 3 | % Output 4 | % Regularized noise covariance from pre-stimulus data 5 | 6 | % Input 7 | % y(nk,nt) = Baseline or Prestimulus data 8 | % b(nk,nl) = mixing matrix 9 | % lam(nk,1) = sensor noise precision 10 | % bet(nl,1) = hyperparamaeters 11 | % sig(nk,nk) = data covariance matrix = b*b'+1/lam (approx) 12 | % nk = data dimensionality 13 | % nl = factor dimensionality (try 5) 14 | % nt = number of time points 15 | % nem = number of EM iterations (try 50) 16 | % plot = flag for plotting 17 | 18 | % experiment with nl,nem using the plots generated by the code: 19 | % set nem such that the likelihood converges (top plot) 20 | % set nl such that some hyperparameters bet approach infinity, i.e. some 21 | % 1/bet vanish (middle plot) 22 | 23 | 24 | %=============================== 25 | 26 | nk=size(y,1);nt=size(y,2); 27 | 28 | ryy=y*y'; 29 | [p d]=svd(ryy/nt); 30 | d=diag(d); 31 | b=p*diag(sqrt(d)); 32 | b=b(:,1:nl); 33 | lam=1./diag(ryy/nt); 34 | 35 | bet=ones(nl,1); %diff from VBFA 36 | 37 | likeli=zeros(nem,1); 38 | rbb=eye(nl)/nt; 39 | 40 | for iem=1:nem 41 | dbet=diag(bet);ldbet=sum(log(bet)); 42 | dlam=diag(lam);ldlam=sum(log(lam)); 43 | 44 | gam=b'*dlam*b+eye(nl)+nk*rbb*0; %diff from VBFA 45 | igam=inv(gam); 46 | ubar=igam*b'*dlam*y; 47 | ryu=y*ubar'; 48 | ruu=ubar*ubar'+nt*igam; 49 | 50 | [p d q]=svd(gam);ldgam=sum(log(diag(d))); 51 | temp1=-.5*ldgam*ones(1,nt)+.5*sum(ubar.*(gam*ubar),1); 52 | temp2=.5*ldlam*ones(1,nt)-.5*lam'*(y.^2); 53 | f=temp1+temp2; 54 | f3=.5*nl*ldlam+.5*nk*ldbet-.5*trace(b'*dlam*b*dbet); %diff 55 | likeli(iem)=mean(f)+f3/nt; 56 | 57 | betbar=ruu+dbet; 58 | ibetbar=inv(betbar); 59 | b=ryu*ibetbar; 60 | 61 | ilam=diag(ryy-b*ryu')/(nt+nl); % diff 62 | lam=1./ilam; 63 | dlam=diag(lam); 64 | 65 | bet=1./(diag(b'*dlam*b)/nk+diag(ibetbar)); 66 | if nargin>3 67 | figure(fig) 68 | hsub=subplot(3,3,1);plot((1:iem)',likeli(1:iem));title('likelihood') 69 | hsub=subplot(3,3,4);plot((1:nl)',sqrt([mean(b.^2,1)' 1./bet]));title('1/bet'); 70 | hsub=subplot(3,3,7);plot(1./lam);title('1/lam'); 71 | drawnow; 72 | end 73 | 74 | rbb=ibetbar; 75 | end 76 | 77 | weight=b*igam*b'*dlam; 78 | sig=b*b'+diag(1./lam); 79 | yc=b*ubar; 80 | cy=b*ruu*b'+diag(ilam*trace(ruu*ibetbar)); 81 | mlike=likeli(iem); 82 | 83 | if nargin>3 84 | figure(fig) 85 | subplot(3,3,2);imagesc(ryy/nt);title('ryy/nt');colorbar; 86 | subplot(3,3,3);imagesc(cy/nt);title('cy/nt');colorbar; 87 | subplot(3,3,5);imagesc((ryy-cy)/nt);title('(ryy-cy)/nt');colorbar; 88 | subplot(3,3,6);imagesc(b*b');title('b*bT');colorbar; 89 | subplot(3,3,8);imagesc(sig);title('sig');colorbar; 90 | end 91 | 92 | Cov=cy; 93 | 94 | return 95 | 96 | 97 | %=============================== 98 | 99 | 100 | -------------------------------------------------------------------------------- /spm_beamforming.m: -------------------------------------------------------------------------------- 1 | function spm_beamforming 2 | % GUI gateway to Beamforming toolbox 3 | %__________________________________________________________________________ 4 | % Copyright (C) 2012 Wellcome Trust Centre for Neuroimaging 5 | 6 | % Vladimir Litvak 7 | % $Id$ 8 | 9 | pipelines = spm_select('List', fileparts(mfilename('fullpath')), '^bf_pipeline_.*\.m$'); 10 | pipelines = cellstr(pipelines); 11 | pipelines = [cell(length(pipelines), 1), pipelines(:)]; 12 | for i = 1:size(pipelines, 1) 13 | [junk, pipelines{i, 2}] = fileparts(pipelines{i, 2}); 14 | pipelines{i, 1} = strrep(pipelines{i, 2}, 'bf_pipeline_', ''); 15 | pipelines{i, 1} = strrep(pipelines{i, 1}, '_', ' '); 16 | end 17 | 18 | str = sprintf('%s|', pipelines{:, 1}); 19 | str = str(1:(end-1)); 20 | 21 | fun = spm_input('DAiSS',1,'m', str, char(pipelines(:, 2))); 22 | 23 | eval(fun); 24 | 25 | spm_jobman('interactive', matlabbatch); -------------------------------------------------------------------------------- /tbx_cfg_bf.m: -------------------------------------------------------------------------------- 1 | function bf = tbx_cfg_bf 2 | % Configuration file for toolbox 'Beamforming' 3 | %_______________________________________________________________________ 4 | % Copyright (C) 2012 Wellcome Trust Centre for Neuroimaging 5 | 6 | % Vladimir Litvak 7 | % $Id$ 8 | 9 | tbxdir = fileparts(mfilename('fullpath')); 10 | 11 | if ~isdeployed, addpath(tbxdir); end 12 | 13 | components = { 14 | 'bf_group'; 15 | 'bf_data'; 16 | 'bf_copy'; 17 | 'bf_sources' 18 | 'bf_features' 19 | 'bf_inverse' 20 | 'bf_output' 21 | 'bf_write' 22 | }; 23 | 24 | bf = cfg_choice; 25 | bf.tag = 'beamforming'; 26 | bf.name = 'DAiSS (beamforming)'; 27 | bf.help = {'Data analysis in source space toolbox'}; 28 | 29 | for i = 1:numel(components) 30 | bf.values{i} = feval(components{i}); 31 | end 32 | 33 | % Generate the menu function automatically in case of a different directory 34 | % name (might fail if there is no write permission) 35 | [tbx_path, tbx_name] = fileparts(tbxdir); 36 | if ~isdeployed && ~isequal(tbx_name, 'beamforming') 37 | if ~exist(fullfile(tbxdir, ['spm_' tbx_name '.m']), 'file') 38 | try 39 | fid = fopen(fullfile(tbxdir, ['spm_' tbx_name '.m']), 'wt'); 40 | fprintf(fid, 'function spm_%s\n\nspm_beamforming', tbx_name); 41 | fclose(fid); 42 | end 43 | end 44 | end 45 | --------------------------------------------------------------------------------