Skip to content

Latest commit

 

History

History
4524 lines (3396 loc) · 164 KB

supFunSim.org

File metadata and controls

4524 lines (3396 loc) · 164 KB

supFunSim.org

Preliminaries

[i01] Introduction

SYNOPSIS: supFunSim provides a comprehensive simulations framework for solving the forward and the inverse problems in electroencephalography (EEG).

supFunSim (provided as supFunSim.org file) contains both ordinary human language and (discrete) computing machine code that are available in this document in the form of plain text. This text tells a story about the reconstruction of neuronal activity originating from discrete nodes spread among separate brain regions. This reconstruction is based on the EEG signal.

First neuronal activity is realistically simulated (we also refer to that activity as time series in source-space). The solution to a forward problem (FP) is based on (1) the geometry and conductivity of head compartments and (2) the position of electrodes on the scalp. This solution allows for generation of simulated EEG signals (i.e., time-series in sensor-space that result from the activity of neuronal sources).

Later, sensor-space time-series are used as an input for a variety of spatial filtering methods implemented here. This produces reconstruction (OR estimation) of the original activity of the neuronal sources (i.e., each spatial filter constitutes (OR provides) an inverse problem solution). Next, filtering output is compared with the original source-space time-series in order to estimate reconstruction errors of a given spatial filter.

Some of the filters implemented here are known in the literature and some are novel generalizations of the aforementioned. A number of parameters is available for manipulation in our simulations setup, these are, among others:

  • number of considered sources,
  • signal to noise ratios for a number of noise types (described below).

We also provide a number of reconstruction error evaluation methods (that are relevant for the present neuroscience research).

[i02] Acknowledgments

Herein we adapt number of solutions provided in toolboxes developed by others, namely:

Also, please note that creation of this document is an ongoing process as we intend to expand it (therefore we are not seeking for it to be complete in any near future).

DOIN [i03] Technicalities

Introduction to GNU Emacs and org-mode

This document was written using GNU Emacs in plain text exercising advantages of org-mode and (org-)Babel. This Emacs mode allows for the application of a literate approach to programming. Briefly speaking, the source code blocks are interspersed with ordinary human language blocks that provide explanations and some insights into governing dynamics and intrinsic mechanics of the code.

org-mode allows for easy export of whole documents to HTML, \LaTeX, PDF and other formats. Therefore, various versions of this document may also be available, but the plain text version is favorable for studying the simulations setup (as it provides the most interactive encounter with the code). org-mode also allows for latex formatted equations, e.g.,

$ei π + 1 = 0$

GNU Emacs (with org-mode and Babel enabled) provides an environment in which this document can be read and at the same time the code snippets can be executed (evaluated) within the same environment and the code execution results can be incorporated in this document as a plain text, figures or in another form (provided that, apart from GNU Emacs, the given machine can execute MATLAB or GNU Octave scripts).

In order to execute all of the simulations steps in a single run (or multiple runs) please proceed to the section BATCH (or LOOP respectively). Those sections extensively exert on the tangling, a feature of the org-mode that allows for source code blocks content to be written to separate files that can be later executed (e.g., using MATLAB).

For this simulations files that are tangled from this org-mode document are stored in the same directory as the supFunSim.org file and have names that follow the pattern tg_*.

Simulations are hosted on GitHub.com:

Specific software versions

Basic info

We have tested supFunSim using:

  • Lenovo ThinkPad W540:
    • Intel(R) Core(TM) i7-4910MQ CPU @ 2.90GHz,
    • 32768 MB RAM 1600 MHz DDR3,
  • GNU with Linux operating system:
    • SUSE Linux Enterprise Desktop 12 SP2,
    • x86_64-suse-linux-gnu,
    • kernel release 4.4.21-81-default,
  • software:
    • GNU Emacs 25.1.2 (GTK+ Version 3.20.9),
    • MathWorks MATLAB R2017a (9.2.0.538062).

DOIN [i04] Licensing (GPL)

Copyright (c) 2014-2017 Jan Nikadon, Tomasz Piotrowski, Dania Gutiérrez

supFunSim contains both ordinary human language text and discrete computing machine code (both) provided in this document. Ordinary human language text is copyrighted by authors. Digital computing machine code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

supFunSim is provided “AS IS”, WITHOUT WARRANTY of ANY KIND, EXPRESS or IMPLIED, INCLUDING but NOT LIMITED to the WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE and NONINFRINGEMENT. In NO event shall the authors or copyright holders be liable for ANY CLAIM, DAMAGES or OTHER LIABILITY, WHETHER in an ACTION of CONTRACT, TORT or OTHERWISE, arising from, out of or in connection with the software or the use or other dealings in the software.

See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with supFunSim. If not, see http://www.gnu.org/licenses/

Simulations

[s00] Prelude

Description

The following code block prepares MATLAB workspace, adds paths to the necessary toolboxes and ./fun directory containing some additional functions. It also loads initial data:

Additionally we also provide:

  • pre-computed leadfields for the above mentioned source candidates

Contents of the above mentioned files can be checked with:

whos('-file','./mat/sel_atl.mat')
whos('-file','./mat/sel_ele.mat')
whos('-file','./mat/sel_geo_deep_icosahedron642.mat')
whos('-file','./mat/sel_geo_deep_thalami.mat')
whos('-file','./mat/sel_mri00.mat')
whos('-file','./mat/sel_msh.mat')
whos('-file','./mat/sel_src.mat')
whos('-file','./mat/sel_vol.mat')

Load each file separately (mostly for testing and didactic purpose).

load('./mat/sel_atl.mat')
load('./mat/sel_ele.mat')
load('./mat/sel_geo_deep_icosahedron642.mat')
load('./mat/sel_geo_deep_thalami.mat')
load('./mat/sel_mri00.mat')
load('./mat/sel_msh.mat')
load('./mat/sel_src.mat')
load('./mat/sel_vol.mat')

NB: For the sake of backward compatibility and to facilitate bug tracking, it also provides initial settings for the simulations. Pleas remember that ut supra those settings (most likely) need not to be modified. During batch execution of simulations initial settings are overwritten by values defined in sections BATCH and LOOP (the very last sections of this document.)

NB: In the code we make extensive use of a number of acronyms and abbreviations, these include:

SrcActiv
Activity of interest (biological)
IntNoise
Interference (biological) noise
BcgNoise
Background (biological) noise
MesNoise
Measurement noise

We assume that this file is located in (or symbolically linked to) ~/supFunSim on machines running GNU with Linux (or any similar decent operating system). Similarly the necessary toolboxes are expected to be found in sub-directories of the ~/toolboxes directory (or symlinked there). Otherwise the following code might need to be adjusted (e.g., by changing value of the TMP_TBX_PATH variable etc.) Some additional necessary functions are located in the ./fun directory.

Simulation parameters are controlled using SETUP variable. The geometrical arrangement and number of cortical sources in ROIs can be controlled using SRCS field (SETUP.SRCS), which is a 3 column <int> array.

  • Rows of SETUP.SRCS reppresent consequent ROIs.
  • Cols of SETUP.SRCS represent signal types, namely:
    • SrcActiv,
    • IntNoise and
    • BcgNoise,

    respectively.

  • Integers represent a number of sources in the given ROI for the given signal type.

Variable SETUP also contains field DEEP (SETUP.DEEP) which defines number of signals in the brain center (around thalami) that belong to particular signal type (same as for cortical signal types these include: SrcActiv, IntNoise and BcgNoise).

!run Simulations main setup

% Tidy up workspace and change working directory
clc; close all;clearvars('-except','fPath');
if exist('fPath'), cd(fPath); else, try, cd('~/supFunSim/'); catch, warningMessage = 'Problem encoutered while trying to change working directory to ''~/supFunSim/''.'; end; end; disp(['CYBERCRAFT:: pwd is: ',pwd])

% Add path to additional functions
addpath([pwd,'/fun']);

% Add path to toolboxes
if 0, disp('COMMENT: if having problems with toolboxes consider wise use of:'); restoredefaultpath; end
clearvars TMP_TOOLB_PATH; if exist('~/toolboxes/','dir') == 7, TMP_TOOLB_PATH = '~/toolboxes/'; else, warningMessage = sprintf('CYBERCRAFT:: Warning:: toolboxes directory was not found (use ''~/toolboxes/'')'); end; if exist('TMP_TOOLB_PATH','var'), disp(['CYBERCRAFT:: looking for toolboxes in: ',TMP_TOOLB_PATH]), end;
addpath([TMP_TOOLB_PATH,'/arfit']);
addpath([TMP_TOOLB_PATH,'/mvarica']);
addpath([TMP_TOOLB_PATH,'spm12/']);
addpath([TMP_TOOLB_PATH,'spm12/toolbox/aal/']);
addpath([TMP_TOOLB_PATH,'eeglab/']);
addpath([TMP_TOOLB_PATH,'fieldtrip/']); ft_defaults;
if exist([TMP_TOOLB_PATH,'fieldtrip/privatePublic/',filesep]),         addpath([TMP_TOOLB_PATH,'fieldtrip/privatePublic/',filesep]);         else, copyfile([TMP_TOOLB_PATH,'fieldtrip/private/',filesep],        [TMP_TOOLB_PATH,'fieldtrip/privatePublic/',filesep]);         addpath([TMP_TOOLB_PATH,'fieldtrip/privatePublic/',filesep]);         end;
if exist([TMP_TOOLB_PATH,'fieldtrip/forward/privatePublic/',filesep]), addpath([TMP_TOOLB_PATH,'fieldtrip/forward/privatePublic/',filesep]); else, copyfile([TMP_TOOLB_PATH,'fieldtrip/forward/private/',filesep],[TMP_TOOLB_PATH,'fieldtrip/forward/privatePublic/',filesep]); addpath([TMP_TOOLB_PATH,'fieldtrip/forward/privatePublic/',filesep]); end;
addpath([TMP_TOOLB_PATH,'fieldtrip/utilities']);
if exist([TMP_TOOLB_PATH,'fieldtrip/utilities/privatePublic/',filesep]), addpath([TMP_TOOLB_PATH,'fieldtrip/utilities/privatePublic/',filesep]); else, copyfile([TMP_TOOLB_PATH,'fieldtrip/utilities/private/',filesep],[TMP_TOOLB_PATH,'fieldtrip/utilities/privatePublic/',filesep]); addpath([TMP_TOOLB_PATH,'fieldtrip/utilities/privatePublic/',filesep]); end;

% Initialize FieldTrip
ft_defaults;

% Load head geometry, electrode positions and ROIs data.
load('./mat/sel_msh.mat');                     % head compartments geometry (cortex)
load('./mat/sel_geo_deep_thalami.mat');        % mesh containing candidates for lacation of deep sources (based on thalami)
load('./mat/sel_geo_deep_icosahedron642.mat'); % mesh containing candidates for lacation of deep sources (based on icosahedron642)
load('./mat/sel_atl.mat');                     % cortex geometry with (anatomical) ROI parcellation
load('./mat/sel_vol.mat');                     % volume conduction model (head-model)
load('./mat/sel_ele.mat');                     % geometry of electrode positions
load('./mat/sel_src.mat');                     % all cx leadfields

clearvars ii jj kk mm nn tmp* SETUP

% Simulations main setup
SETUP.rROI   = logical(0);       % random (1) or predefined (0) ROIs
SETUP.rPNT   = logical(0);       % random (1) or predefined (0) candidate points for source locations: if 0, 
				       % number of sources as in SETUP.SRCS(1,1) will be fixed and in close locations
SETUP.SRCS   = []; % Cortical sources (avoid placing more than 10 sources in single ROI)
SETUP.SRCS   = [ SETUP.SRCS;  8  0  3 ];
SETUP.SRCS   = [ SETUP.SRCS;  2  0  0 ];
SETUP.SRCS   = [ SETUP.SRCS;  2  1  0 ];
SETUP.SRCS   = [ SETUP.SRCS;  0  4  0 ];
SETUP.SRCS   = [ SETUP.SRCS;  0  4  0 ];
SETUP.SRCS   = [ SETUP.SRCS;  0  4  0 ];
SETUP.SRCS   = [ SETUP.SRCS;  0  4  3 ];
SETUP.SRCS   = [ SETUP.SRCS;  0  0  3 ];
SETUP.SRCS   = [ SETUP.SRCS;  0  0  3 ];
SETUP.SRCS   = [ SETUP.SRCS;  0  0  3 ];
SETUP.DEEP   = [              2  1  6 ]; % deep sources
SETUP.ERPs   = 5;       % Add ERPs (timelocked activity)
SETUP.rROI   = 0;       % random (1) or predefined (0) ROIs
SETUP.ELEC   = size(sel_ele.elecpos,1); % number of electrodes
SETUP.n00    = 500;     % number of time samples per trial
SETUP.K00    = 1;       % number of independent realizations of signal and noise based on generated MVAR model
			      % note: covariance matrix R of observed signal and noise covariance matrix N are estimated from samples originating 
			      % from all realizations of signal and noise 
SETUP.P00    = 6;       % order of the MVAR model used to generate time-courses for signal of interest
SETUP.FRAC   = 0.20;    % proportion of ones to zeros in off-diagonal elements of the MVAR coefficients masking array
SETUP.STAB   = 0.99;    % MVAR stability limit for MVAR eigenvalues (less than 1.0 results in more stable model producing more stationary signals)
SETUP.RNG    = [0,2.8]; % range for pseudo-random sampling of eigenvalues for MVAR coefficients range
SETUP.ITER   = 5e5;     % iterations limit for MVAR pseudo-random sampling and stability verification
SETUP.PDC_RES = [0:0.01:0.5]; % resolution vector for normalized PDC estimation
SETUP.TELL   = 1;       % provide additional comments during code execution ("tell me more")
SETUP.PLOT   = 1;       % plot figures during the intermediate stages
SETUP.SCRN   = get(0,'MonitorPositions'); % get screens positions
SETUP.DISP   = SETUP.SCRN(end,:);        % force figures to be displayed on (3dr) screenscreen
SETUP.FIXED_SEED = 0; % Settings for seed selection
if SETUP.FIXED_SEED, SETUP.SEED = rng(1964);else,SETUP.SEED = rng(round(1e3*randn()^2*sum(clock)));end
SETUP.RANK_EIG = sum(SETUP.SRCS(:,1)); % rank of EIG-LCMV filter: set to number of active sources
SETUP.fltREMOVE = 1; % to keep (0) or remove (1) selected filters
SETUP.SHOWori = 1; % to show (1) or do not show (0) Original and Dummy signals on Figures
SETUP.IntLfgRANK = round(0.3*sum(SETUP.SRCS(:,2))); % rank of patch-constrained reduced-rank leadfield
SETUP.supSwitch = 'loc'; % 'rec': run reconstruction of sources activity, 'loc': find active sources

!opt Checkups

NB: The following code is not executed during simulations, it is left here only to facilitate bug tracking and for explanatory/illustrative purpose.

The above applies to all Checkup sections (usually marked with org-todo-keyword: !opt).

whos
SETUP
chkSim___tg_s01_PRE___001(SETUP);
sel_atl
sel_ele
sel_ele.label
sel_msh
{sel_msh.bnd.inf}'
sel_vol
SETUP

!fun Checkup functions

chkSim___tg_s01_PRE___000_PARSE_SETUP

function chkSim___tg_s01_PRE___000_PARSE_SETUP(SETUP,sel_atl)
% Simulations setup parser

    disp('Checking consistency of ''SETUP'' definitions')

    % check if number of ROIs is smaller than number of cortex parcels
    tmp_MaxROIs = size(sel_atl.Atlas(sel_atl.atl).Scouts,2);
    tmp_ActROIs = size(SETUP.SRCS,1);
    if 0
        disp(SETUP.SRCS)
        tmp_MaxROIs
        tmp_ActROIs
    end
    if tmp_ActROIs > tmp_MaxROIs,
        tmp_msg = ['please avoid putting more than ', num2str(tmp_MaxROIs) ' source ROIs (decrease the number of rows in the ''SETUP.SRCS''.)'];
        error(tmp_msg);
    end

    % check if no roi contains more sources than allowed (allowed number
    % of sources is the number of nodes in the ROI that contains the
    % least nodes)
    tmp_MaxSrc = []; for ii = 1:tmp_MaxROIs, tmp_MaxSrc = [tmp_MaxSrc; size(sel_atl.Atlas(sel_atl.atl).Scouts(ii).Vertices,2)]; end;
    tmp_MaxSrc = min(tmp_MaxSrc);
    [tmp_ActSrcs, tmp_ActColMaxIdx] = max(sum(SETUP.SRCS,2));
    if 0
        SETUP.SRCS
        tmp_MaxSrc
        tmp_ActSrcs
        tmp_ActColMaxIdx
    end
    if tmp_ActSrcs > min(tmp_MaxSrc),
        tmp_msg = ['please avoid putting more than ', num2str(tmp_MaxSrc) ' sources in any of the ROIs (decrease sum of the column number ', num2str(tmp_ActColMaxIdx), ' in the ''SETUP.SRCS''.)'];
        error(tmp_msg);
    end

    % Check if a number of ERPs is not greater than the number of signals
    % of interest.
    tmp_MaxERPs = sum(SETUP.SRCS(:,1));
    tmp_ActERPs = SETUP.ERPs;
    if 0
        SETUP.SRCS
        tmp_MaxERPs
        tmp_ActERPs
    end
    if tmp_ActERPs > tmp_MaxERPs,
        tmp_msg = ['please avoid putting more than ', num2str(tmp_MaxERPs) ' ERPs (this is a number of sources of activity of interest, please change the sum in the 1st column of ''SETUP.SRCS'' or the ''SETUP.ERPs'' value.)'];
        error(tmp_msg);
    end

end

chkSim___tg_s01_PRE___001

function chkSim___tg_s01_PRE___001(SETUP)
    fprintf('     \n');
    fprintf('CYBERCRAFT:: Number of signal types per CORTEX ROI:\n\n');
    disp(array2table([[1:size(SETUP.SRCS,1)]',SETUP.SRCS,sum(SETUP.SRCS,2)],'VariableNames',{'ROI','SrcActiv','IntNoise','BcgNoise','TOTAL'}))
    fprintf('     \n');
    fprintf('CYBERCRAFT:: TOTAL number of signals for CORTEX:\n\n');
    disp(array2table([size(SETUP.SRCS,1);sum(SETUP.SRCS(:,1));sum(SETUP.SRCS(:,2));sum(SETUP.SRCS(:,3));sum(sum(SETUP.SRCS(:,1:3)))]','VariableNames',{'ROI','SrcActiv','IntNoise','BcgNoise','TOTAL'}));
    fprintf('     \n');
    fprintf('CYBERCRAFT:: Number of signals for DEEP sources:\n\n');
    disp(array2table([size(SETUP.SRCS,1)+1;sum(SETUP.DEEP(1,1));sum(SETUP.DEEP(1,2));sum(SETUP.DEEP(1,3));sum(SETUP.DEEP(1,1:3))]','VariableNames',{'ROI','SrcActiv','IntNoise','BcgNoise','TOTAL'}));
    fprintf('     \n');
    fprintf('CYBERCRAFT:: TOTAL number of signals for CORTEX and DEEP sources:\n\n');
    disp(array2table([NaN;sum(SETUP.SRCS(:,1))+sum(SETUP.DEEP(1,1));sum(SETUP.SRCS(:,2))+sum(SETUP.DEEP(1,2));sum(SETUP.SRCS(:,3))+sum(SETUP.DEEP(1,3));sum(sum(SETUP.SRCS(:,1:3)))+sum(SETUP.DEEP(1,1:3))]','VariableNames',{'ROI','SrcActiv','IntNoise','BcgNoise','TOTAL'}));
    fprintf('     \n');
    disp(['CYBERCRAFT:: MesNoise: ',num2str(SETUP.ELEC)])
end

!run SNR adjustment and signal components setup

This section provides further simulation settings.

NB: For the sake of backward compatibility and to facilitate bug tracking, it also provides initial settings for the simulations. Pleas remember that ut supra those settings (most likely) need not to be modified because for execution of simulations in batch they will be overwritten by values defined in sections BATCH and LOOP, the two sections that can be found very close to the end of this document.

SETUP.CUBE           = 20;    % perturbation of the leadfields based on the shift of source position within a cube of given edge length (centered at the original leadfields positions), in [mm]
SETUP.CONE           = pi/32; % perturbation of the leadfields based on the rotation of source orientation (azimuth TH, elevation PHI), in [rad]
SETUP.H_Src_pert     = 0;     % use original (0) or perturbed (1) leadfield for signal reconstruction
SETUP.H_Int_pert     = 0;     % use original (0) or perturbed (1) leadfield for nulling constrains
SETUP.SINR           = 5;     % signal to interference noise power ratio expressed in dB (both measured on electrode level)
SETUP.SBNR           = 10;    % signal to biological noise power ratio expressed in dB (both measured on electrode level)
SETUP.SMNR           = 15;    % signal to measurment noise power ratio expressed in dB (both measured on electrode level)
SETUP.WhtNoiseAddFlg = 1;     % white noise admixture in biological noise interference noise (FLAG)
SETUP.WhtNoiseAddSNR = 3;     % SNR of BcgNoise and WhiNo (dB)
SETUP.SigPre = 0;   SETUP.IntPre = 0;   SETUP.BcgPre = 1;   SETUP.MesPre = 1; % final signal components for pre-interval  (use zero or one for signal, interference noise, biological noise, measurement noise)
SETUP.SigPst = 1;   SETUP.IntPst = 1;   SETUP.BcgPst = 1;   SETUP.MesPst = 1; % final signal components for post-interval (as above)

     % For localization, the default is to consider random locations of ROI with some fixed candidate points such that 
     % SETUP.SRCS(1,1) of them are in close locations; additionally, no interfering sources are considered
     % in the localization model. You may comment out the 'if' section below to experiment with other settings.
     if(SETUP.supSwitch == 'loc') 
	 SETUP.rROI   = logical(1);       % random (1) or predefined (0) ROIs
	 SETUP.rPNT   = logical(0);       % random (1) or predefined (0) candidate points for source locations: if 0, 
					  % number of sources as in SETUP.SRCS(1,1) will be fixed and in close locations
	 SETUP.SigPre = 0;   SETUP.IntPre = 0;   SETUP.BcgPre = 1;   SETUP.MesPre = 1; % final signal components for pre-interval  (use zero or one for signal, interference noise, biological noise, measurement noise)
	 SETUP.SigPst = 1;   SETUP.IntPst = 0;   SETUP.BcgPst = 1;   SETUP.MesPst = 1; % final signal components for post-interval (as above)
     end

if SETUP.rPNT
    disp('CC: using random source locations')
else
    disp('CC: using predefined source locations')
end

!opt Checkups

whos
SETUP
chkSim___tg_s01_PRE___001(SETUP)
chkSim___tg_s02_PRE___001(SETUP)

!fun Checkup functions

chkSim___tg_s02_PRE___001

function chkSim___tg_s02_PRE___001(SETUP)
    fprintf('\n');
    fprintf('CYBERCRAFT:: Perturbation cube:\n\n');
    disp(array2table(SETUP.CUBE,'VariableNames',{'mm'},'RowNames',{'shift distance'}))
    fprintf('\n');
    fprintf('CYBERCRAFT:: Perturbation cone:\n\n');
    disp(array2table([SETUP.CONE,rawRad2Deg(SETUP.CONE)],'VariableNames',{'rad','deg'},'RowNames',{'rotation angle'}));
    fprintf('\n');
    fprintf('CYBERCRAFT:: Ratios for signal to:\n\n');
    disp(array2table([SETUP.SINR;SETUP.SBNR;SETUP.SMNR],'VariableNames',{'SxNR'},'RowNames',{'IntNoise','BcgNoise','MesNoise'}));
    fprintf('\n');
    fprintf('CYBERCRAFT:: Signal components:\n\n');
    disp(array2table([SETUP.SigPre,SETUP.IntPre,SETUP.BcgPre,SETUP.MesPre;SETUP.SigPst,SETUP.IntPst,SETUP.BcgPst,SETUP.MesPst]','VariableNames',{'pre','post'},'RowNames',{'SrcActiv','IntNoise','BcgNoise','MesNoise'}));
    fprintf('\n');
end

[s01] Time series for activity and noise sources

Description

Code in this section produces timeseries for the signals described in the table below.

Variable nameDescription
sim_sig_SrcActivActivity of interest (biological)
sim_sig_IntNoiseInterference (biological) noise
sim_sig_BcgNoiseBackground (biological) noise
sim_sig_MesNoiseMeasurement noise
sim_sig_AdjSNRsAll the above signals combined and adjusted for SNR

MVAR modeling for bioelectrical activity sources

Info

In this section multivariate timeseries are generated for: sim_sig_SrcActiv, sim_sig_IntNoise, sim_sig_BcgNoise.

Timeseries are based on Multivariate Autoregressive (MVAR) model.

MVAR modeling (theory)

MVAR model basics

See:

${{v}ν}=w+\underset{l=1}{\overset{p}{\mathop ∑ }}\,{{A}l}{{v}ν-l}+{{ε}ν}$, where

  • ${{v}ν}$ are the $m$-dimensional state vectors of (stationary)

time series,

  • $p$ is the order of the model,
  • matrices ${{A}1}\ldots{{A}p} ∈ Rm×{m}$ are the

coefficient matrices of the AR model,

  • ${{ε}ν}$ are the $m$-dimensional uncorrelated

random vectors with mean zero and covariance matrix $C ∈ Rm×{m}$

PDC basics
Normalized frequency

See

Generation of timeseries for bioelectrical activity of interest

!run Code
clearvars sim_sig_SrcActiv tmp*
sim_sig_SrcActiv = cccSim___makeSimSig(SETUP,1,'MVAR based signal for sources activity');
clearvars ii jj kk nn tmp*

if SETUP.ERPs > 0

    sim_sig_SrcActiv.sigSRC_pst_orig = sim_sig_SrcActiv.sigSRC_pst;
    sim_sig_SrcActiv.sigSRC_pre_orig = sim_sig_SrcActiv.sigSRC_pre;

    tmp_LB = -5;
    tmp_UB = 7;
    tmp_NN = SETUP.n00;
    tmp_PP = 1;
    for ee = 1:1:SETUP.ERPs
        tmp_PP = mod(ee,3)+1;
        sim_sig_SrcActiv.ERPs(ee,:) = gauswavf(tmp_LB,tmp_UB,tmp_NN,tmp_PP);
    end
    sim_sig_SrcActiv.ERPs_pst = transpose(sim_sig_SrcActiv.ERPs);
    sim_sig_SrcActiv.ERPs_pst(size(sim_sig_SrcActiv.sigSRC_pst,1),size(sim_sig_SrcActiv.sigSRC_pst,2)) = 0;
    sim_sig_SrcActiv.ERPs_pst = cat(3,repmat(sim_sig_SrcActiv.ERPs_pst,[1,1,SETUP.K00]));

    sim_sig_SrcActiv.sigSRC_pst = sim_sig_SrcActiv.sigSRC_pst + 20*sim_sig_SrcActiv.ERPs_pst;

end

NB.: Fields:

  • w01,
  • A01,
  • C01,
  • SBC01,
  • FPE01 and
  • th01

(in general *01) are estimated from the sigMVAR_pst signal.

!fun MVAR timeseries modeling functions
cccSim___makeSimSig
function sim_sig_SrcActiv = cccSim___makeSimSig(SETUP,set_COL,varargin)
    sim_sig_SrcActiv.inf        = '';
    sim_sig_SrcActiv.S00        = [];
    sim_sig_SrcActiv.P00        = [];
    sim_sig_SrcActiv.M00        = [];
    sim_sig_SrcActiv.A00        = zeros([0,1]);
    sim_sig_SrcActiv.mdlStabH   = [];
    sim_sig_SrcActiv.mdlStabM   = [];
    sim_sig_SrcActiv.w00        = [];
    sim_sig_SrcActiv.C00        = [];
    sim_sig_SrcActiv.n00        = [];
    sim_sig_SrcActiv.K00        = [];
    sim_sig_SrcActiv.sigSRC_pre = permute([],[3,2,1]);
    sim_sig_SrcActiv.sigSRC_pst = permute([],[3,2,1]);
    sim_sig_SrcActiv.w01        = [];
    sim_sig_SrcActiv.A01        = zeros([0,1]);
    sim_sig_SrcActiv.C01        = [];
    sim_sig_SrcActiv.SBC01      = [];
    sim_sig_SrcActiv.FPE01      = [];
    sim_sig_SrcActiv.th01       = [];
    if ~isempty(varargin)
        sim_sig_SrcActiv.inf = varargin{end};
    end
    sim_sig_SrcActiv.S00 = sum(SETUP.SRCS(:,set_COL))+SETUP.DEEP(1,set_COL); % number of signals
    if sim_sig_SrcActiv.S00 > 0
        sim_sig_SrcActiv.P00 = SETUP.P00;                     % order of the MVAR model used to generate time-courses
        sim_sig_SrcActiv.M00 = cccSim___diagonMask(sim_sig_SrcActiv.S00,SETUP.FRAC); % MVAR coefficients mask
        sim_sig_SrcActiv.A00 = cccSim___stableMVAR(sim_sig_SrcActiv.S00,sim_sig_SrcActiv.P00,sim_sig_SrcActiv.M00,SETUP.RNG,SETUP.STAB,SETUP.ITER);
        [sim_sig_SrcActiv.mdlStabH,sim_sig_SrcActiv.mdlStabM] = rawIsStableMVAR(sim_sig_SrcActiv.A00,1);
        sim_sig_SrcActiv.w00 = zeros(sim_sig_SrcActiv.S00,1); % expected value for time-courses
        sim_sig_SrcActiv.C00 = eye(sim_sig_SrcActiv.S00);     % covariance of MVAR model's "driving noise"
        sim_sig_SrcActiv.n00 = SETUP.n00;                     % number of time samples
        sim_sig_SrcActiv.K00 = SETUP.K00;                     % number of independent realizations of the driving AR models
        sim_sig_SrcActiv.sigSRC_pre = 10*arsim(sim_sig_SrcActiv.w00,sim_sig_SrcActiv.A00,sim_sig_SrcActiv.C00,[sim_sig_SrcActiv.n00,2*sim_sig_SrcActiv.K00],1e3); % 10e-6; % Current density (10nA*mm)
        sim_sig_SrcActiv.sigSRC_pst = sim_sig_SrcActiv.sigSRC_pre(:,:,[end/2+1:end]);
        sim_sig_SrcActiv.sigSRC_pre = sim_sig_SrcActiv.sigSRC_pre(:,:,[1:end/2]);
        if SETUP.TELL,disp('Fitting MVAR model to generated signal...');end;
        [sim_sig_SrcActiv.w01,sim_sig_SrcActiv.A01,sim_sig_SrcActiv.C01,sim_sig_SrcActiv.SBC01,sim_sig_SrcActiv.FPE01,sim_sig_SrcActiv.th01] = arfit(sim_sig_SrcActiv.sigSRC_pst,sim_sig_SrcActiv.P00-round(sim_sig_SrcActiv.P00/2),sim_sig_SrcActiv.P00+round(sim_sig_SrcActiv.P00/2));
    end
end
cccSim___stableMVAR
function A00 = cccSim___stableMVAR(S00,P00,M00,set_RNG,set_STAB,set_ITER)
% procedure inspired by function stablemvar that is a part of MVARICA Toolbox.
    if 0
        A00 = cccSim___stableMVAR(S00,P00,M00,set_RNG,set_ITER,set_STAB)
    end
    tmp_iterNow = 0;
    tmp_lambda = Inf;
    while any(abs(tmp_lambda)>set_STAB) && tmp_iterNow < set_ITER
        tmp_V = orth(rand(S00*P00,S00*P00));
        tmp_U = orth(rand(S00*P00,S00*P00));
        lambdatmp = set_RNG(1)+(set_RNG(2)-set_RNG(1))*rand(S00*P00,1);
        tmp_A00 = tmp_V*diag(lambdatmp)*tmp_U';
        A00 = tmp_A00(1:S00,:);
        A00 = A00.*repmat(M00,1,P00); % nulling of some coefficients based on mask
        tmp_lambda = eig([A00; eye((P00-1)*S00) zeros((P00-1)*S00,S00)]);
        tmp_iterNow = tmp_iterNow + 1;
    end
    if tmp_iterNow >=set_ITER
        A0=[];
        error('Could not generate stable MVAR model in given number of iterations (set_ITER)');
    end
    if 0
        S00 = sim_sig00.S00
        P00 = sim_sig00.P00
        w00 = sim_sig00.w00
        C00 = sim_sig00.C00
        n00 = sim_sig00.n00
        K00 = sim_sig00.K00
    end
end
cccSim___diagonMask
function M00 = cccSim___diagonMask(S00,M00_frc)
% cccSim___diagonMask produces masking square array M (SxS) whose all diagonal and some off-diagonal elements are ones. All
% othere elements are zeros. The off-diagonal elements are sampled pseudo-randomly and their number is declared by
% second argument of this function which should be a number between zero and one that describes the proportion of ones
% to zeros among all off-diagonal elements of the resulting array.
%
% Usage:
%
%    MSK = cccSim___diagonMask(S,frac)

% Copyright (C) 2000-2015, Jan (CyberCraft) Nikadon (nikadon-AT-SIGN-gmail.com)
%
%    This file is free software and a part of CyberCraft Toolkit.  You can redistribute it and/or modify it under the
%    terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the
%    License, or (at your option) any later version.
%
%    CyberCraft is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with CyberCraft. If not, see <http://www.gnu.org/licenses/>.

    if 0
        % Example useage:
        S00     = 10;
        M00_frc = 0.1;
        M00     = cccSim___diagonMask(S00,M00_frc)
        figure(1);clf;
        imagesc(M00);colorbar;
        (numel(find(M00))-S00) / (numel(M00)-S00)
        imagesc(sim_sig00.M00);colorbar;
    end
    M00     = eye(S00);
    M00_idx = find(~M00);
    M00_smp = datasample(M00_idx,round(M00_frc*numel(M00_idx)),'Replace',false);
    M00(M00_smp) = deal(1);
end
!opt Checkups
!opt Gauss wave
size(sim_sig_SrcActiv.sigSRC_pst_orig)
size(sim_sig_SrcActiv.sigSRC_pst)
size(sim_sig_SrcActiv.ERPs_pst)
size(sim_sig_SrcActiv.ERPs)

figure, imagesc(sim_sig_SrcActiv.sigSRC_pst_orig(:,:,1))
figure, imagesc(sim_sig_SrcActiv.sigSRC_pst(:,:,1))
figure, imagesc(sim_sig_SrcActiv.ERPs_pst(:,:,1))

ee = 0
ee = ee + 1

tmp_LB = -5;
tmp_UB = 7;
tmp_NN = SETUP.n00;
tmp_PP = mod(ee,3)+1;

tmp_PP

[PSI,X] = gauswavf(tmp_LB,tmp_UB,tmp_NN,tmp_PP);

close all
plot(PSI)

size(cat(2,20*repmat(transpose(sim_sig_SrcActiv.ERPs),[1,1,SETUP.K00]),zeros(SETUP.n00,sum(SETUP.SRCS(:,1))-SETUP.ERPs,SETUP.K00)))

close all
figure
plot(sim_sig_SrcActiv.ERPs(3,:))

figure
plot(sim_sig_SrcActiv.sigSRC_pst(:,3,1))

figure
plot(mean(sim_sig_SrcActiv.sigSRC_pst(:,3,:),3))

!opt Basics
whos
chkSim___tg_s01_PRE___001(SETUP)
sim_sig_SrcActiv

tmp_arrC = [rawSize(sim_sig_SrcActiv.sigSRC_pre,[1,2,3]); rawSize(sim_sig_SrcActiv.sigSRC_pst,[1,2,3])];
tmp_varN = {'Timesamples','Signals','Realizations'};
tmp_rowN = {'sim_sig_SrcActiv.sigSRC_pre','sim_sig_SrcActiv.sigSRC_pst'};
disp(' ');disp(array2table(tmp_arrC,'VariableNames',tmp_varN,'RowNames',tmp_rowN))

tmp_arrC = [size(sim_sig_SrcActiv.A00),size(sim_sig_SrcActiv.A00,2)/size(sim_sig_SrcActiv.A00,1);size(sim_sig_SrcActiv.A01),size(sim_sig_SrcActiv.A01,2)/size(sim_sig_SrcActiv.A01,1)];
tmp_varN = {'Signals','Signals_cdot_ModOrd','ModOrd'};
tmp_rowN = {'sim_sig_SrcActiv.A00','sim_sig_SrcActiv.A01'};
disp(' ');disp(array2table(tmp_arrC,'VariableNames',tmp_varN,'RowNames',tmp_rowN))

~isequal(sim_sig_SrcActiv.sigSRC_pre,sim_sig_SrcActiv.sigSRC_pst)
~isequal(sim_sig_SrcActiv.A00,sim_sig_SrcActiv.A01)
!fig MVAR zeroing matrix (M00)

Matrix produced by cccSim___diagonMask (mask for nulling of some MVAR coefficients).

figure(101);clf;set(gcf,'Position',SETUP.DISP);imagesc(sim_sig_SrcActiv.M00);colormap(rawHotColdColorMap(10));colorbar;
set(gcf,'color','w');
!fig MVAR model coefficient matrix (A00)

Plotted are:

  • A00 the original coefficient matrix used for timeseries generation and
  • A01 coefficient matrix obtained by fitting to the generated timeseries.
figure(105);clf;set(gcf,'Position',SETUP.DISP);subplot(2,1,1);cccSim___rawDispA00(sim_sig_SrcActiv.A00);title('A00');subplot(2,1,2);cccSim___rawDispA00(sim_sig_SrcActiv.A01);title('A01');
set(gcf,'color','w');
!fig PDC
figure(120);clf;set(gcf,'Position',SETUP.DISP);cccSim___rawPlotA00(sim_sig_SrcActiv.A00);
set(gcf,'color','w');

figure(121);clf;set(gcf,'Position',SETUP.DISP);cccSim___rawPlotA00(sim_sig_SrcActiv.A01);
set(gcf,'color','w');
!fun Checkup functions
cccSim___rawDispA00
function cccSim___rawDispA00(A00)
    rawImgSC(A00,8);
    tmp_base = 255;
    tmp_colorMapMat = rawHotColdColorMap(tmp_base);
    caxis([-max(abs(min(min(A00))),abs(max(max(A00)))) max(abs(min(min(A00))),abs(max(max(A00))))]);
    colormap(tmp_colorMapMat);
    colorbar;
    hold on;
    tmp_stem = 0.5+size(A00,1):size(A00,1):size(A00,2)-0.5;
    tmp_vals = size(A00,1)+0.5*ones(size(tmp_stem));
    stem(tmp_stem,tmp_vals,'Color','k','LineWidth',0.5,'Marker', 'none');
    set(gca,'XTick',[0:size(A00,1):size(A00,2)])
end
cccSim___rawPlotA00
function cccSim___rawPlotA00(A00)
    rawPlotPDC(abs(PDC(A00,SETUP.PDC_RES)),SETUP.PDC_RES);
end

Generation of timeseries for bioelectrical interference noise

In general this signal is intended to be highly correlated (or anti-correlated) with the signal of interest. Also some white noise can be added.

!run Code
clearvars sim_sig_IntNoise tmp*
sim_sig_IntNoise = sim_sig_SrcActiv;

sim_sig_IntNoise.inf        = 'MVAR based signal for interference (biological) noise activity sources';
tmp_IntNoiseCol = 2;

if SETUP.TELL,disp('Getting base for IntNoise...');end;
sim_sig_IntNoise.sigSRC_pre = -sim_sig_IntNoise.sigSRC_pre;
sim_sig_IntNoise.sigSRC_pst = -sim_sig_IntNoise.sigSRC_pst;
[sim_sig_IntNoise.w01,sim_sig_IntNoise.A01,sim_sig_IntNoise.C01,sim_sig_IntNoise.SBC01,sim_sig_IntNoise.FPE01,sim_sig_IntNoise.th01] = deal([]);

if SETUP.TELL,disp('Populating signals for IntNoise...');end;
sim_sig_IntNoise.sigSRC_pre = repmat(sim_sig_IntNoise.sigSRC_pre,1,ceil( (sum(SETUP.SRCS(:,tmp_IntNoiseCol))+SETUP.DEEP(1,tmp_IntNoiseCol))/size(sim_sig_IntNoise.sigSRC_pre,2)),1);
sim_sig_IntNoise.sigSRC_pst = repmat(sim_sig_IntNoise.sigSRC_pst,1,ceil( (sum(SETUP.SRCS(:,tmp_IntNoiseCol))+SETUP.DEEP(1,tmp_IntNoiseCol))/size(sim_sig_IntNoise.sigSRC_pst,2)),1);

if SETUP.TELL,disp('Reducing dimensionality of IntNoise...');end;
sim_sig_IntNoise.sigSRC_pre = sim_sig_IntNoise.sigSRC_pre(:,1:(sum(SETUP.SRCS(:,tmp_IntNoiseCol))+SETUP.DEEP(1,tmp_IntNoiseCol)),:);
sim_sig_IntNoise.sigSRC_pst = sim_sig_IntNoise.sigSRC_pst(:,1:(sum(SETUP.SRCS(:,tmp_IntNoiseCol))+SETUP.DEEP(1,tmp_IntNoiseCol)),:);

if SETUP.TELL,disp('Backing-up IntNoise before white noise admixture...');end;
sim_sig_IntNoise.sigSRC_pre_b4admix = sim_sig_IntNoise.sigSRC_pre;
sim_sig_IntNoise.sigSRC_pst_b4admix = sim_sig_IntNoise.sigSRC_pst;

if SETUP.WhtNoiseAddFlg
    if SETUP.TELL,disp('Adding some white noise to the biological noise activity...');end;
    sim_sig_IntNoise.noiseAdmix_pre = randn(size(sim_sig_IntNoise.sigSRC_pre));
    sim_sig_IntNoise.noiseAdmix_pst = randn(size(sim_sig_IntNoise.sigSRC_pst));
    for kk = 1:SETUP.K00
        sim_sig_IntNoise.noiseAdmix_pre(:,:,kk) = rawAdjTotSNRdB(sim_sig_IntNoise.sigSRC_pre(:,:,kk),sim_sig_IntNoise.noiseAdmix_pre(:,:,kk),SETUP.WhtNoiseAddSNR);
        sim_sig_IntNoise.noiseAdmix_pst(:,:,kk) = rawAdjTotSNRdB(sim_sig_IntNoise.sigSRC_pst(:,:,kk),sim_sig_IntNoise.noiseAdmix_pst(:,:,kk),SETUP.WhtNoiseAddSNR);
    end
    sim_sig_IntNoise.sigSRC_pre = sim_sig_IntNoise.sigSRC_pre+sim_sig_IntNoise.noiseAdmix_pre;
    sim_sig_IntNoise.sigSRC_pst = sim_sig_IntNoise.sigSRC_pst+sim_sig_IntNoise.noiseAdmix_pst;
end

if SETUP.TELL,disp('Fitting MVAR model to generated signal...');end;
[sim_sig_IntNoise.w01,sim_sig_IntNoise.A01,sim_sig_IntNoise.C01,sim_sig_IntNoise.SBC01,sim_sig_IntNoise.FPE01,sim_sig_IntNoise.th01] = arfit(sim_sig_IntNoise.sigSRC_pst,sim_sig_IntNoise.P00-round(sim_sig_IntNoise.P00/2),sim_sig_IntNoise.P00+round(sim_sig_IntNoise.P00/2));

if 0
    sim_sig_IntNoise = rmfield(sim_sig_IntNoise,{'sigSRC_pre_b4admix','sigSRC_pst_b4admix','noiseAdmix_pre','noiseAdmix_pst'})
end

clearvars ii jj kk nn tmp*
!opt Checkups
!opt Basics 1
whos
sim_sig_SrcActiv
sim_sig_IntNoise

chkSim___tg_s01_PRE___001(SETUP)

kk = 1;
jj = 1:min(size(sim_sig_SrcActiv.sigSRC_pre,2),size(sim_sig_IntNoise.sigSRC_pre,2));

tmp_arrC = [rawSNRdB(sim_sig_IntNoise.sigSRC_pre_b4admix(:,:,kk),sim_sig_IntNoise.noiseAdmix_pre(:,:,kk));rawSNRdB(sim_sig_IntNoise.sigSRC_pst_b4admix(:,:,kk),sim_sig_IntNoise.noiseAdmix_pst(:,:,kk))];
tmp_varN = {'SNR'};
tmp_rowN = {'sim_sig_IntNoise.sigSRC_pre_b4admix','sim_sig_IntNoise.sigSRC_pst_b4admix'};
disp(' ');disp(array2table(tmp_arrC,'VariableNames',tmp_varN,'RowNames',tmp_rowN))

tmp_arrC = corrcoef(sim_sig_SrcActiv.sigSRC_pre(:,jj,kk),sim_sig_IntNoise.sigSRC_pre(:,jj,kk));
tmp_varN = {'sim_sig_SrcActiv_a','sim_sig_IntNoise_a'};
tmp_rowN = tmp_varN;
disp(' ');disp(array2table(tmp_arrC,'VariableNames',tmp_varN,'RowNames',tmp_rowN))

tmp_arrC = corrcoef(sim_sig_SrcActiv.sigSRC_pst(:,jj,kk),sim_sig_IntNoise.sigSRC_pst(:,jj,kk));
tmp_varN = {'sim_sig_SrcActiv_b','sim_sig_IntNoise_b'};
tmp_rowN = tmp_varN;
disp(' ');disp(array2table(tmp_arrC,'VariableNames',tmp_varN,'RowNames',tmp_rowN))

tmp_arrC = corrcoef(sim_sig_SrcActiv.sigSRC_pre(:,jj,kk),sim_sig_IntNoise.sigSRC_pst(:,jj,kk));
tmp_varN = {'sim_sig_SrcActiv_a','sim_sig_IntNoise_b'};
tmp_rowN = tmp_varN;
disp(' ');disp(array2table(tmp_arrC,'VariableNames',tmp_varN,'RowNames',tmp_rowN));disp('CYBERCRAFT:: This should be negligible')

tmp_arrC = corrcoef(sim_sig_SrcActiv.sigSRC_pst(:,jj,kk),sim_sig_IntNoise.sigSRC_pre(:,jj,kk));
tmp_varN = {'sim_sig_SrcActiv_b','sim_sig_IntNoise_a'};
tmp_rowN = tmp_varN;
disp(' ');disp(array2table(tmp_arrC,'VariableNames',tmp_varN,'RowNames',tmp_rowN));disp('CYBERCRAFT:: This should be negligible')

clearvars ii jj kk nn tmp*
!opt Basics 2
whos
sim_sig_SrcActiv
sim_sig_IntNoise

disp(~isequal(sim_sig_SrcActiv.sigSRC_pre,sim_sig_SrcActiv.sigSRC_pst))
disp(~isequal(sim_sig_SrcActiv.sigSRC_pre,sim_sig_IntNoise.sigSRC_pre))
disp(~isequal(sim_sig_SrcActiv.sigSRC_pre,sim_sig_IntNoise.sigSRC_pst))

tmp_arrC = [rawSize(sim_sig_SrcActiv.sigSRC_pre,[1,2,3]); rawSize(sim_sig_SrcActiv.sigSRC_pst,[1,2,3]); rawSize(sim_sig_IntNoise.sigSRC_pre,[1,2,3]); rawSize(sim_sig_IntNoise.sigSRC_pst,[1,2,3])];
tmp_varN = {'Timesamples','Signals','Realizations'};
tmp_rowN = {'sim_sig_SrcActiv.sigSRC_pre','sim_sig_SrcActiv.sigSRC_pst','sim_sig_IntNoise.sigSRC_pre','sim_sig_IntNoise.sigSRC_pst'};
disp(' ');disp(array2table(tmp_arrC,'VariableNames',tmp_varN,'RowNames',tmp_rowN));

tmp_arrC = [size(sim_sig_SrcActiv.A00),size(sim_sig_SrcActiv.A00,2)/size(sim_sig_SrcActiv.A00,1);size(sim_sig_SrcActiv.A01),size(sim_sig_SrcActiv.A01,2)/size(sim_sig_SrcActiv.A01,1);size(sim_sig_IntNoise.A00),size(sim_sig_IntNoise.A00,2)/size(sim_sig_IntNoise.A00,1);size(sim_sig_IntNoise.A01),size(sim_sig_IntNoise.A01,2)/size(sim_sig_IntNoise.A01,1)];
tmp_varN = {'Signals','Signals_cdot_ModOrd','ModOrd'};
tmp_rowN = {'sim_sig_SrcActiv.A00','sim_sig_SrcActiv.A01','sim_sig_IntNoise.A00','sim_sig_IntNoise.A01'};
disp(' ');disp(array2table(tmp_arrC,'VariableNames',tmp_varN,'RowNames',tmp_rowN));

clearvars ii jj kk nn tmp*
!fig MVAR model coefficient matrix (A00)
close all

figure(55);clf;set(gcf, 'Position', SETUP.DISP);
subplot(4,1,1);cccSim___rawDispA00(sim_sig_SrcActiv.A00);title('sim\_sig00.A00');
subplot(4,1,2);cccSim___rawDispA00(sim_sig_SrcActiv.A01);title('sim\_sig00.A01');
subplot(4,1,3);cccSim___rawDispA00(sim_sig_IntNoise.A00);title('sim\_sig30.A00');
subplot(4,1,4);cccSim___rawDispA00(sim_sig_IntNoise.A01);title('sim\_sig30.A01');
set(gcf,'color','w');
!fig PDC
close all

figure(100);clf;set(gcf, 'Position', SETUP.DISP);cccSim___rawPlotA00(sim_sig_SrcActiv.A00);
set(gcf,'color','w');
figure(101);clf;set(gcf, 'Position', SETUP.DISP);cccSim___rawPlotA00(sim_sig_SrcActiv.A01);
set(gcf,'color','w');
figure(130);clf;set(gcf, 'Position', SETUP.DISP);cccSim___rawPlotA00(sim_sig_IntNoise.A00);
set(gcf,'color','w');
figure(131);clf;set(gcf, 'Position', SETUP.DISP);cccSim___rawPlotA00(sim_sig_IntNoise.A01);
set(gcf,'color','w');

Generation of timeseries for bio-electrical background noise

!run Code
clearvars sim_sig_BcgNoise tmp*
sim_sig_BcgNoise = cccSim___makeSimSig(SETUP,3,'MVAR based signal for background (biological) noise activity sources');
clearvars ii jj kk nn tmp*
!opt Checkups
!opt Basics 1
whos
sim_sig_SrcActiv
sim_sig_IntNoise
sim_sig_BcgNoise

chkSim___tg_s01_PRE___001(SETUP)

% Check size of signals generated
tmp_arrC = [rawSize(sim_sig_SrcActiv.sigSRC_pre,[1,2,3]); rawSize(sim_sig_SrcActiv.sigSRC_pst,[1,2,3]); rawSize(sim_sig_IntNoise.sigSRC_pre,[1,2,3]); rawSize(sim_sig_IntNoise.sigSRC_pst,[1,2,3]); rawSize(sim_sig_BcgNoise.sigSRC_pre,[1,2,3]); rawSize(sim_sig_BcgNoise.sigSRC_pst,[1,2,3])];
tmp_varN = {'Timesamples','Signals','Realizations'};
tmp_rowN = {'sim_sig_SrcActiv.sigSRC_pre','sim_sig_SrcActiv.sigSRC_pst','sim_sig_IntNoise.sigSRC_pre','sim_sig_IntNoise.sigSRC_pst','sim_sig_BcgNoise.sigSRC_pre','sim_sig_BcgNoise.sigSRC_pst'};
disp(' ');disp(array2table(tmp_arrC,'VariableNames',tmp_varN,'RowNames',tmp_rowN));
!opt Basics 2
jj = 1
kk = 1

tmp_arrC = corrcoef(sim_sig_SrcActiv.sigSRC_pre(:,jj,kk),sim_sig_BcgNoise.sigSRC_pre(:,jj,kk));
tmp_varN = {'sim_sig_SrcActiv_a','sim_sig_BcgNoise_a'};
tmp_rowN = tmp_varN;
disp(' ');disp(array2table(tmp_arrC,'VariableNames',tmp_varN,'RowNames',tmp_rowN));disp('CYBERCRAFT:: This should be negligible')
!fig MVAR model coefficient matrix (A00)
close all

figure(105);clf;set(gcf,'Position',SETUP.DISP);subplot(2,1,1);cccSim___rawDispA00(sim_sig_BcgNoise.A00);title('A00');subplot(2,1,2);cccSim___rawDispA00(sim_sig_BcgNoise.A01);title('A01');
set(gcf,'color','w');
figure(100);clf;set(gcf,'Position',SETUP.DISP);cccSim___rawPlotA00(sim_sig_SrcActiv.A01);
set(gcf,'color','w');
figure(130);clf;set(gcf,'Position',SETUP.DISP);cccSim___rawPlotA00(sim_sig_IntNoise.A01);
set(gcf,'color','w');
figure(140);clf;set(gcf,'Position',SETUP.DISP);cccSim___rawPlotA00(sim_sig_BcgNoise.A01);
set(gcf,'color','w');
!fig PDC
close all

figure(55);clf;set(gcf, 'Position', SETUP.DISP);

subplot(6,1,1);cccSim___rawDispA00(sim_sig_SrcActiv.A00);title('sim\_sig\_SrcActiv.A00')
subplot(6,1,2);cccSim___rawDispA00(sim_sig_SrcActiv.A01);title('sim\_sig\_SrcActiv.A01')
subplot(6,1,3);cccSim___rawDispA00(sim_sig_IntNoise.A00);title('sim\_sig\_IntNoise.A00')
subplot(6,1,4);cccSim___rawDispA00(sim_sig_IntNoise.A01);title('sim\_sig\_IntNoise.A01')
subplot(6,1,5);cccSim___rawDispA00(sim_sig_BcgNoise.A00);title('sim\_sig\_BcgNoise.A00')
subplot(6,1,6);cccSim___rawDispA00(sim_sig_BcgNoise.A01);title('sim\_sig\_BcgNoise.A01')

Measurement noise generation

!run Code

clearvars sim_sig_MesNoise tmp*
sim_sig_MesNoise.inf = 'RANDN based signal for measurment noise';
sim_sig_MesNoise.sigSNS_pre = randn([SETUP.n00,size(sel_ele.chanpos,1),SETUP.K00]);
sim_sig_MesNoise.sigSNS_pst = randn([SETUP.n00,size(sel_ele.chanpos,1),SETUP.K00]);

!opt Checkups

whos
sim_sig_SrcActiv
sim_sig_IntNoise
sim_sig_BcgNoise
sim_sig_MesNoise
tmp_arrC = [rawSize(sim_sig_SrcActiv.sigSRC_pre,[1,2,3]); rawSize(sim_sig_SrcActiv.sigSRC_pst,[1,2,3]); rawSize(sim_sig_IntNoise.sigSRC_pre,[1,2,3]); rawSize(sim_sig_IntNoise.sigSRC_pst,[1,2,3]); rawSize(sim_sig_BcgNoise.sigSRC_pre,[1,2,3]); rawSize(sim_sig_BcgNoise.sigSRC_pst,[1,2,3]); rawSize(sim_sig_MesNoise.sigSNS_pre,[1,2,3]); rawSize(sim_sig_MesNoise.sigSNS_pst,[1,2,3])];
tmp_varN = {'Timesamples','Signals','Realizations'};
tmp_rowN = {'sim_sig_SrcActiv.sigSRC_pre','sim_sig_SrcActiv.sigSRC_pst','sim_sig_IntNoise.sigSRC_pre','sim_sig_IntNoise.sigSRC_pst','sim_sig_BcgNoise.sigSRC_pre','sim_sig_BcgNoise.sigSRC_pst','sim_sig_BcgNoise.sigSNS_pre','sim_sig_BcgNoise.sigSNS_pst'};
disp(' ');disp(array2table(tmp_arrC,'VariableNames',tmp_varN,'RowNames',tmp_rowN));disp('NB: measurement noise should be already in electrode space not in the source space.')

chkSim___tg_s01_PRE___001(SETUP)
chkSim___tg_s02_PRE___001(SETUP)

[s02] Geometry of head compartments, ROIs, source locations and leadfields

!opt Initial checkups

!fig Deep sources as icosahedron642

close all
figure('Color',[1,1,1]);clf;
sel_geo_deep_icosahedron642
trisurf(                   ...
    sel_geo_deep_icosahedron642.tri,      ...
    sel_geo_deep_icosahedron642.pnt(:,1), ...
    sel_geo_deep_icosahedron642.pnt(:,2), ...
    sel_geo_deep_icosahedron642.pnt(:,3), ...
    'facealpha',0.2,       ...
    'facecolor','m',       ...
    'edgecolor','m',       ...
    'edgealpha',0.4);
hold on
ccrender([-150,150],'finish','matte')

!fig Deep sources as thalami (L+R)

close all
figure('Color',[1,1,1]);clf;
sel_geo_deep_thalami
trisurf(                   ...
    sel_geo_deep_thalami.tri,      ...
    sel_geo_deep_thalami.pnt(:,1), ...
    sel_geo_deep_thalami.pnt(:,2), ...
    sel_geo_deep_thalami.pnt(:,3), ...
    'facealpha',0.05,       ...
    'facecolor','m',       ...
    'edgecolor','m',       ...
    'edgealpha',0.1);
hold on
ccrender([-50,50],'finish','matte')

!fig Cortex mesh

ft_plot_mesh(                  ...
    sel_atl,                   ...
    'facecolor',[0.9 0.9 0.9], ...
    'facealpha',0.0,           ...
    'edgecolor',[0.7 0.7 0.7], ...
    'edgealpha',0.2);
hold on
ccrender([-160,160],'finish','matte')
view(0,90)
view(90,0)
view(180,0)

!fig Brain outer mesh

close all
figure('Color',[1,1,1]);clf;
ft_plot_mesh(        ...
    sel_msh.bnd(1),  ...
    'facecolor','m', ...
    'facealpha',0.1, ...
    'edgecolor','m', ...
    'edgealpha',0.05);
ccrender([-160,160],'finish','matte')

!fig Skull outer mesh

ft_plot_mesh(        ...
    sel_msh.bnd(2),  ...
    'facecolor','c', ...
    'facealpha',0.1, ...
    'edgecolor','c', ...
    'edgealpha',0.1);
ccrender([-160,160],'finish','matte')

!fig Scalp outer mesh

ft_plot_mesh(           ...
    sel_msh.bnd(3),     ...
    'facecolor','skin', ...
    'facealpha',0.1,    ...
    'edgecolor','red',  ...
    'edgealpha',0.2);
ccrender([-160,160],'finish','matte')

!fig Electrode positioning

stem3( sel_ele.elecpos(:,1), ...
       sel_ele.elecpos(:,2), ...
       sel_ele.elecpos(:,3), ...
       '.m','filled','LineStyle','none','MarkerSize',12);

!fig Electrode labels

% for ii=1:size(tmp_elecpos,1),sel_elec00.label{ii,1} = sprintf('Ch%02d',ii);end

text(  sel_ele.elecpos(:,1) * 1.2, ...
       sel_ele.elecpos(:,2) * 1.2, ...
       sel_ele.elecpos(:,3) * 1.2, ...
       sel_ele.label,'Color',[0.5 0.3 0.5],'FontSize',10);

!fig View control

view(0,90)
view(90,0)
view(180,0)
view(225,60)

!run ROI random sampling

!run Code

clearvars sim_geo_cort ii jj kk nn tmp*
sim_geo_cort.numROIs = size(sel_atl.Atlas(sel_atl.atl).Scouts,2);

if SETUP.rROI
    disp('CC: using random ROI locations')
    sim_geo_cort.lstROIs = randsample([1:sim_geo_cort.numROIs],size(SETUP.SRCS,1));
else
    disp('CC: using predefined ROI locations')
    sim_geo_cort.lstROIs = [31 30 34 29 56 51 84 53 83 58 57];
    sim_geo_cort.lstROIs = sim_geo_cort.lstROIs(1:size(SETUP.SRCS,1));
end


if SETUP.rPNT
    disp('CC: using random source locations')
else
    disp('CC: using predefined source locations')
    sim_geo_cort.lstROIs(1) = 31;
end

!opt Checkups

SETUP.rROI
SETUP.rPNT

sim_geo_cort
sim_geo_cort.lstROIs

chkSim___tg_s01_PRE___001(SETUP)
chkSim___tg_s02_Geometry___01_RandSamp(sim_geo_cort,sel_atl)

!fun Checkup functions

chkSim___tg_s02_Geometry___01_RandSamp
function chkSim___tg_s02_Geometry___01_RandSamp(sim_geo_cort,sel_atl)
    fprintf('\n');
    disp(cell2table([num2cell(sim_geo_cort.lstROIs)',{sel_atl.Atlas(sel_atl.atl).Scouts(sim_geo_cort.lstROIs).Label}'],'VariableNames',{'ROI_number','ROI_name'}));
    fprintf('\n');
end

!run Indices for ROI vertices and triangles ON CORTEX

!run Code

Select all vertices and all triangles for each ROI.

sim_geo_cort.indROIs = [];
for ii = 1:length(sim_geo_cort.lstROIs)
    tmp_roi = sim_geo_cort.lstROIs(ii);
    sim_geo_cort.indROIs(ii).pntNum00 = sel_atl.Atlas(sel_atl.atl).Scouts(tmp_roi).Vertices';
    sim_geo_cort.indROIs(ii).triNum00 = find(all(ismember(sel_atl.tri,sim_geo_cort.indROIs(ii).pntNum00),2));
end
clearvars ii jj kk nn tmp*

!opt Checkups

sim_geo_cort
sim_geo_cort.indROIs
ii = 1
sim_geo_cort.indROIs(ii)
sim_geo_cort.indROIs(ii).pntNum00
sim_geo_cort.indROIs(ii).triNum00

!opt ROI visualization functions

[num-000] Whole cortex
function chkSim___tg_s02_Geometry___02_Indices___Plot_000(sel_atl)
    ft_plot_mesh(                   ...
        sel_atl,                  ...
        'facecolor',[0.95 0.95 0.95],  ...
        'facealpha',0.1,            ...
        'edgecolor',[0.85 0.85 0.85],  ...
        'edgealpha',0.2);
    hold on
    ccrender([-160,160],'finish','matte')
end
[num-001] ROIs
function chkSim___tg_s02_Geometry___02_Indices___Plot_001(sel_atl,sim_geo_cort)
    hold on
    tmp_colorBar = lines(length(sim_geo_cort.lstROIs));
    for ii = 1:length(sim_geo_cort.lstROIs)
        trisurf(                      ...
            sel_atl.tri(sim_geo_cort.indROIs(ii).triNum00,:),...
            sel_atl.pnt(:,1)-0.1*sel_atl.vn1(:,1),  ...
            sel_atl.pnt(:,2)-0.1*sel_atl.vn1(:,2),  ...
            sel_atl.pnt(:,3)-0.1*sel_atl.vn1(:,3),  ...
            'facealpha',0.2,                            ...
            'facecolor',tmp_colorBar(ii,:),             ...
            'edgecolor',tmp_colorBar(ii,:),             ...
            'edgealpha',0.4);
        hold on
    end
    ccrender([-160,160],'finish','matte')

%    caxis([1 length(sim_geo_cort.lstROIs)]);
%    colormap(tmp_colorBar)
%    colorbar
end
[num-002] Cortex sources
function chkSim___tg_s02_Geometry___02_Indices___Plot_002(sim_geo_cort)
    hold on
    ii = 1
    qh = quiver3(...
        sim_geo_cort.pos_orig{ii}(:,1),sim_geo_cort.pos_orig{ii}(:,2),sim_geo_cort.pos_orig{ii}(:,3),...
        sim_geo_cort.ori_orig{ii}(:,1),sim_geo_cort.ori_orig{ii}(:,2),sim_geo_cort.ori_orig{ii}(:,3),...
        1,...
        'color','k');
    set(qh,'linewidth',1);
    qh = quiver3(...
        sim_geo_cort.pos_pert{ii}(:,1),sim_geo_cort.pos_pert{ii}(:,2),sim_geo_cort.pos_pert{ii}(:,3),...
        sim_geo_cort.ori_pert{ii}(:,1),sim_geo_cort.ori_pert{ii}(:,2),sim_geo_cort.ori_pert{ii}(:,3),...
        1,':',...
        'color','k');
    set(qh,'linewidth',1);
    ii = 2
    qh = quiver3(...
        sim_geo_cort.pos_orig{ii}(:,1),sim_geo_cort.pos_orig{ii}(:,2),sim_geo_cort.pos_orig{ii}(:,3),...
        sim_geo_cort.ori_orig{ii}(:,1),sim_geo_cort.ori_orig{ii}(:,2),sim_geo_cort.ori_orig{ii}(:,3),...
        1,...
        'color','r');
    set(qh,'linewidth',1);
    qh = quiver3(...
        sim_geo_cort.pos_pert{ii}(:,1),sim_geo_cort.pos_pert{ii}(:,2),sim_geo_cort.pos_pert{ii}(:,3),...
        sim_geo_cort.ori_pert{ii}(:,1),sim_geo_cort.ori_pert{ii}(:,2),sim_geo_cort.ori_pert{ii}(:,3),...
        1,':',...
        'color','r');
    set(qh,'linewidth',1);
    ii = 3
    qh = quiver3(...
        sim_geo_cort.pos_orig{ii}(:,1),sim_geo_cort.pos_orig{ii}(:,2),sim_geo_cort.pos_orig{ii}(:,3),...
        sim_geo_cort.ori_orig{ii}(:,1),sim_geo_cort.ori_orig{ii}(:,2),sim_geo_cort.ori_orig{ii}(:,3),...
        1,...
        'color','b');
    set(qh,'linewidth',1);
    qh = quiver3(...
        sim_geo_cort.pos_pert{ii}(:,1),sim_geo_cort.pos_pert{ii}(:,2),sim_geo_cort.pos_pert{ii}(:,3),...
        sim_geo_cort.ori_pert{ii}(:,1),sim_geo_cort.ori_pert{ii}(:,2),sim_geo_cort.ori_pert{ii}(:,3),...
        1,':',...
        'color','b');
    set(qh,'linewidth',1);
    ccrender([-160,160],'finish','matte')
end

!opt ROI visualization

Figure giving ultimate situation view.

close all
chkSim___tg_s01_PRE___001(SETUP)
chkSim___tg_s02_Geometry___01_RandSamp(sim_geo_cort,sel_atl)

chkSim___tg_s02_Geometry___02_Indices___Plot_000(sel_atl)
chkSim___tg_s02_Geometry___02_Indices___Plot_001(sel_atl,sim_geo_cort)

view(-115,55)
view(-115,-55)
view(0,60)
view(45,60)
view(90,60)
view(135,60)
view(180,60)
view(225,60)
view(270,60)
view(315,60)
view(315,-20)
view(135,45)

!run Coordinates for source position and orientation

!run Code

sim_geo_cort.distrROIs    = SETUP.SRCS;
sim_geo_cort.distrROIsSum = sum(SETUP.SRCS,2);
sim_geo_cort.bulkSRC = {};
for ii = 1:length(sim_geo_cort.distrROIsSum)
    sim_geo_cort.bulkSRC{ii,1} = randsample(sim_geo_cort.indROIs(ii).pntNum00,sim_geo_cort.distrROIsSum(ii));
end
sim_geo_cort.splitSRC = {};
for ii = 1:length(sim_geo_cort.distrROIsSum)
    sim_geo_cort.splitSRC(ii,:) = mat2cell(sim_geo_cort.bulkSRC{ii},sim_geo_cort.distrROIs(ii,:),1)';
end

if 0
    sim_geo_cort.splitSRC(1,1)
    sim_geo_cort.splitSRC{1,1}
end

if SETUP.rPNT
    disp('CC: using random source locations')
else
    disp('CC: using predefined source locations')
    sim_geo_cort.splitSRC{1,1} = [5441;5506;5481;5283;5144;5063;5823;5987;6154;6065;6166;6346;6087;6446;6367;6726;6859;6829;6613;6698;6966;7162;7227;6949;6996;7365;7247;7480];
    sim_geo_cort.splitSRC{1,1} = sim_geo_cort.splitSRC{1,1}(1:SETUP.SRCS(1,1));
    if 0
        sim_geo_cort.splitSRC{1,1}
    end
end

sim_geo_cort.mergeSRC = {};
for ii = 1:3
    sim_geo_cort.mergeSRC{ii} = cat(1,sim_geo_cort.splitSRC{:,ii});
end
sim_geo_cort.pos_orig = {};
sim_geo_cort.ori_orig = {};
sim_geo_cort.pos_pert = {};
sim_geo_cort.ori_pert = {};
for ii = 1:3
    sim_geo_cort.pos_orig{ii} = sel_atl.pnt(sim_geo_cort.mergeSRC{ii},:);
    sim_geo_cort.ori_orig{ii} = sel_atl.vn1(sim_geo_cort.mergeSRC{ii},:);
    sim_geo_cort.pos_pert{ii} = sim_geo_cort.pos_orig{ii};
    sim_geo_cort.ori_pert{ii} = sim_geo_cort.ori_orig{ii};
end
clearvars ii jj kk nn tmp*

!opt Checkups

SETUP.SRCS
SETUP.DEEP

sim_geo_cort
sim_geo_cort.distrROIs
sim_geo_cort.distrROIsSum
sim_geo_cort.bulkSRC
sim_geo_cort.splitSRC
sim_geo_cort.distrROIs
sim_geo_cort.mergeSRC
sim_geo_cort.mergeSRC{1}

chkSim___tg_s02_Geometry___01_RandSamp(sim_geo_cort,sel_atl)
chkSim___tg_s01_PRE___001(SETUP)
sim_geo_cort.mergeSRC

sim_geo_cort.pos_orig
sim_geo_cort.ori_orig
sim_geo_cort.pos_pert
sim_geo_cort.ori_pert

!run Deep sources

!run Code

clearvars sel_geo_deep ii jj kk ll nn tmp*

sim_geo_deep = sel_geo_deep_icosahedron642;
sim_geo_deep = sel_geo_deep_thalami;

sim_geo_deep.bulkSRC =  randsample(1:size(sim_geo_deep.pnt,1),sum(SETUP.DEEP))';


[sim_geo_deep.mergeSRC{1},sim_geo_deep.mergeSRC{2},sim_geo_deep.mergeSRC{3}] = deal([]);


sim_geo_deep.mergeSRC{1,1} = sim_geo_deep.bulkSRC(1:SETUP.DEEP(1));
sim_geo_deep.mergeSRC{1,2} = sim_geo_deep.bulkSRC(1+SETUP.DEEP(1):SETUP.DEEP(1)+SETUP.DEEP(2));
sim_geo_deep.mergeSRC{1,3} = sim_geo_deep.bulkSRC(1+SETUP.DEEP(1)+SETUP.DEEP(2):SETUP.DEEP(1)+SETUP.DEEP(2)+SETUP.DEEP(3));



sim_geo_deep.pos_orig = {};
sim_geo_deep.ori_orig = {};
sim_geo_deep.pos_pert = {};
sim_geo_deep.ori_pert = {};

for ii = 1:3
    sim_geo_deep.pos_orig{ii} = sim_geo_deep.pnt(sim_geo_deep.mergeSRC{ii},:);
    sim_geo_deep.ori_orig{ii} = sim_geo_deep.vn1(sim_geo_deep.mergeSRC{ii},:);
    sim_geo_deep.pos_pert{ii} = sim_geo_deep.pos_orig{ii};
    sim_geo_deep.ori_pert{ii} = sim_geo_deep.ori_orig{ii};
end

clearvars ii jj kk nn tmp*

!opt Checkups

sim_geo_deep
trisurf(                   ...
    sim_geo_deep.tri,      ...
    sim_geo_deep.pnt(:,1), ...
    sim_geo_deep.pnt(:,2), ...
    sim_geo_deep.pnt(:,3), ...
    'facealpha',0.2,       ...
    'facecolor','m',       ...
    'edgecolor','m',       ...
    'edgealpha',0.4);
ccrender([-150,150],'finish','matte')
whos sel_*
whos sim_*
whos sim_geo*
chkSim___tg_s01_PRE___001(SETUP)
disp(SETUP.DEEP)
[sim_geo_deep.bulkSRC,[sim_geo_deep.mergeSRC{1}; sim_geo_deep.mergeSRC{2};sim_geo_deep.mergeSRC{3}]]
sim_geo_deep
sim_geo_cort

!run Merge cortex and deep sources

!run Code

sim_geo = sim_geo_cort;
for ii = 1:3,
    sim_geo.pos_orig{ii} = [sim_geo.pos_orig{ii};sim_geo_deep.pos_orig{ii}];
    sim_geo.ori_orig{ii} = [sim_geo.ori_orig{ii};sim_geo_deep.ori_orig{ii}];
    sim_geo.pos_pert{ii} = [sim_geo.pos_pert{ii};sim_geo_deep.pos_pert{ii}];
    sim_geo.ori_pert{ii} = [sim_geo.ori_pert{ii};sim_geo_deep.ori_pert{ii}];
end;

!opt Checkups

whos sim* sel*
sim_geo
sim_geo_deep
sim_geo_cort

!run Perturbation for source position and orientation

!opt Modify perturbation parameters here

To facilitate bug tracking and for explanatory/illustrative purpose it might be plausible to modify the perturbation parameters here.

SETUP.CUBE
SETUP.CUBE = 30
SETUP.CUBE
SETUP.CONE
SETUP.CONE = pi/16
SETUP.CONE

!run Code

for ii = 1:3
    sim_geo.ori_pert{ii} = normr(rawSphToCart(rawCartToSph(sim_geo.ori_orig{ii}) + [SETUP.CONE*0.5*(2*rand(size(sim_geo.ori_pert{ii},1),2)-1),zeros(size(sim_geo.ori_pert{ii},1),1)]));
end
tmp_count = 0;
for ii = 1:3
    for jj = 1:size(sim_geo.pos_pert{ii},1)
        tmp_srcInside = false;
        while ~tmp_srcInside
            tmp_count = tmp_count+1;
            sim_geo.pos_pert{ii}(jj,:) = sim_geo.pos_orig{ii}(jj,:)+SETUP.CUBE*0.5*(2*rand([1,3])-1);
            tmp_srcInside = bounding_mesh(sim_geo.pos_pert{ii}(jj,:),sel_msh.bnd(1).pnt,sel_msh.bnd(1).tri);
        end
    end
end
if SETUP.TELL
    disp(['CYBERCRAFT:: Perturbation took ',tmp_count,' iterations'])
end
clearvars ii jj kk nn tmp*

NOTE 1: The following procedure is applied to the orientation vectors of activity sources: in order to achieve their random perturbation:

  1. Original orientations are vertex vormal vectors of the triangulation mesh;
  2. Coordinates are transformed to spherical;
  3. SETUP.CONE is the max perturbation (angle of max rotation) considered
  4. Multiplied here by random number ∈ [-1,1];
  5. Azimuth [TH] and elevation [PHI] are modified by adding the above random numbers;
  6. Radius is not changed (the added matrix has last column padded with zeros);
  7. Coordinates are transformed back to the cartesian system.

!opt Checkups

ii = 1

SETUP.CUBE
min(sim_geo.pos_orig{ii}-sim_geo.pos_pert{ii})
max(sim_geo.pos_orig{ii}-sim_geo.pos_pert{ii})

SETUP.CONE
min(rawCartToSph(sim_geo.ori_orig{ii})-rawCartToSph(sim_geo.ori_pert{ii}))
max(rawCartToSph(sim_geo.ori_orig{ii})-rawCartToSph(sim_geo.ori_pert{ii}))

sim_geo
whos

!opt Source visualization

close all
% figure(1)
figure('Color',[1 1 1]);
clf

chkSim___tg_s01_PRE___001(SETUP)
chkSim___tg_s02_Geometry___01_RandSamp(sim_geo,sel_atl)

% mesh for ROIs on cortex
chkSim___tg_s02_Geometry___02_Indices___Plot_001(sel_atl,sim_geo)

% mesh for deep sources ROI
chkSim___tg_s02_Geometry___02_Indices___Plot_003(sim_geo_deep)

% sources
chkSim___tg_s02_Geometry___02_Indices___Plot_002(sim_geo)
legend('SrcActiv\_orig','SrcActiv\_pert','IntNoise\_orig','IntNoise\_pert','BcgNoise\_orig','BcgNoise\_pert')

% chkSim___tg_s02_Geometry___02_Indices___Plot_000(sel_atl)

view(0,90)
view(90,0)
view(180,0)

view(-115,55)
view(-115,-55)
view(0,60)
view(45,60)
view(90,60)
view(135,60)
view(180,60)
view(225,60)
view(270,60)
view(315,60)
view(315,-20)
view(135,45)

!fun Source visualization functions

[num-003] Deep sources

This one works for deep sources!!!

function chkSim___tg_s02_Geometry___02_Indices___Plot_003(sim_geo_deep)
    hold on
    trisurf(                   ...
        sim_geo_deep.tri,      ...
        sim_geo_deep.pnt(:,1), ...
        sim_geo_deep.pnt(:,2), ...
        sim_geo_deep.pnt(:,3), ...
        'facealpha',0.1,       ...
        'facecolor','m',       ...
        'edgecolor','m',       ...
        'edgealpha',0.2);
    ccrender([-150,150],'finish','matte')
end

!run Leadfields computation

Please note that if meshes for brain, skull and scalp change the headmodel also needs to be recalculated

Leadfields are named with reference to signals.

Variable nameDescription
sim_lfg_SrcActiv_origOriginal activity of interest (biological)
sim_lfg_IntNoise_origOriginal interference (biological) noise
sim_lfg_BcgNoise_origOriginal background (biological) noise
sim_lfg_SrcActiv_pertPerturbed activity of interest (biological)
sim_lfg_IntNoise_pertPerturbed interference (biological) noise
sim_lfg_BcgNoise_pertPerturbed background (biological) noise
% WARNING:: suppress warning about MATLAB version and CFG tracking
if 0
    TMP_S = warning('off','all');
end

tmp_cfg            = [];
tmp_cfg.grid.unit  = 'mm';
tmp_cfg.reducerank = 'no';
tmp_cfg.normalize  = 'no';
tmp_cfg.elec       = sel_ele;
tmp_cfg.vol        = sel_vol;

ii = 1;
tmp_cfg.grid.pos          = sim_geo.pos_orig{ii};
tmp_cfg.grid.mom          = transpose(sim_geo.ori_orig{ii});
sim_lfg_SrcActiv_orig.lfg = ft_prepare_leadfield(tmp_cfg);
sim_lfg_SrcActiv_orig.LFG = cat(2,sim_lfg_SrcActiv_orig.lfg.leadfield{:});

tmp_cfg.grid.pos          = sim_geo.pos_pert{ii};
tmp_cfg.grid.mom          = transpose(sim_geo.ori_pert{ii});
sim_lfg_SrcActiv_pert.lfg = ft_prepare_leadfield(tmp_cfg);
sim_lfg_SrcActiv_pert.LFG = cat(2,sim_lfg_SrcActiv_pert.lfg.leadfield{:});

ii = 2;
tmp_cfg.grid.pos          = sim_geo.pos_orig{ii};
tmp_cfg.grid.mom          = transpose(sim_geo.pos_orig{ii});
sim_lfg_IntNoise_orig.lfg = ft_prepare_leadfield(tmp_cfg);
sim_lfg_IntNoise_orig.LFG = cat(2,sim_lfg_IntNoise_orig.lfg.leadfield{:});

tmp_cfg.grid.pos          = sim_geo.pos_pert{ii};
tmp_cfg.grid.mom          = transpose(sim_geo.pos_pert{ii});
sim_lfg_IntNoise_pert.lfg = ft_prepare_leadfield(tmp_cfg);
sim_lfg_IntNoise_pert.LFG = cat(2,sim_lfg_IntNoise_pert.lfg.leadfield{:});

ii = 3;
tmp_cfg.grid.pos          = sim_geo.pos_orig{ii};
tmp_cfg.grid.mom          = transpose(sim_geo.pos_orig{ii});
sim_lfg_BcgNoise_orig.lfg = ft_prepare_leadfield(tmp_cfg);
sim_lfg_BcgNoise_orig.LFG = cat(2,sim_lfg_BcgNoise_orig.lfg.leadfield{:});

tmp_cfg.grid.pos          = sim_geo.pos_pert{ii};
tmp_cfg.grid.mom          = transpose(sim_geo.pos_pert{ii});
sim_lfg_BcgNoise_pert.lfg = ft_prepare_leadfield(tmp_cfg);
sim_lfg_BcgNoise_pert.LFG = cat(2,sim_lfg_BcgNoise_pert.lfg.leadfield{:});

clearvars ii jj kk nn tmp*

[s03] Forward modeling

!run Code

clearvars ii jj kk nn tmp*
for kk = 1:SETUP.K00
    sim_sig_SrcActiv.sigSNS_pre(:,:,kk) = (sim_lfg_SrcActiv_orig.LFG*sim_sig_SrcActiv.sigSRC_pre(:,:,kk)')';
    sim_sig_SrcActiv.sigSNS_pst(:,:,kk) = (sim_lfg_SrcActiv_orig.LFG*sim_sig_SrcActiv.sigSRC_pst(:,:,kk)')';
    sim_sig_IntNoise.sigSNS_pre(:,:,kk) = (sim_lfg_IntNoise_orig.LFG*sim_sig_IntNoise.sigSRC_pre(:,:,kk)')';
    sim_sig_IntNoise.sigSNS_pst(:,:,kk) = (sim_lfg_IntNoise_orig.LFG*sim_sig_IntNoise.sigSRC_pst(:,:,kk)')';
    sim_sig_BcgNoise.sigSNS_pre(:,:,kk) = (sim_lfg_BcgNoise_orig.LFG*sim_sig_BcgNoise.sigSRC_pre(:,:,kk)')';
    sim_sig_BcgNoise.sigSNS_pst(:,:,kk) = (sim_lfg_BcgNoise_orig.LFG*sim_sig_BcgNoise.sigSRC_pst(:,:,kk)')';
end
clearvars ii jj kk nn tmp*

[s04] Preparations for both reconstruction and localization

SNRs adjustments

!opt Comments

We introduced desired SNR by adjusting power for:

  • biological interference,
  • background biological activity,
  • measurement noise. In order to allow for evaluation of:
    • reconstruction accuracy, and
    • functional dependencies estimation (PDC, DTF, dDTF etc.)

    we did not change the power of the sources signal!

!run Code

clearvars ii jj kk nn tmp*

sim_sig_AdjSNRs.SrcActivPre = sim_sig_SrcActiv.sigSNS_pre;
sim_sig_AdjSNRs.SrcActivPst = sim_sig_SrcActiv.sigSNS_pst;
sim_sig_AdjSNRs.IntNoisePre = sim_sig_IntNoise.sigSNS_pre;
sim_sig_AdjSNRs.IntNoisePst = sim_sig_IntNoise.sigSNS_pst;
sim_sig_AdjSNRs.BcgNoisePre = sim_sig_BcgNoise.sigSNS_pre;
sim_sig_AdjSNRs.BcgNoisePst = sim_sig_BcgNoise.sigSNS_pst;
sim_sig_AdjSNRs.MesNoisePre = sim_sig_MesNoise.sigSNS_pre;
sim_sig_AdjSNRs.MesNoisePst = sim_sig_MesNoise.sigSNS_pst;
for kk = 1:SETUP.K00
    sim_sig_AdjSNRs.IntNoisePre(:,:,kk) = rawAdjTotSNRdB(sim_sig_AdjSNRs.SrcActivPre(:,:,kk),sim_sig_AdjSNRs.IntNoisePre(:,:,kk),SETUP.SINR);
    sim_sig_AdjSNRs.IntNoisePst(:,:,kk) = rawAdjTotSNRdB(sim_sig_AdjSNRs.SrcActivPst(:,:,kk),sim_sig_AdjSNRs.IntNoisePst(:,:,kk),SETUP.SINR);
    sim_sig_AdjSNRs.BcgNoisePre(:,:,kk) = rawAdjTotSNRdB(sim_sig_AdjSNRs.SrcActivPre(:,:,kk),sim_sig_AdjSNRs.BcgNoisePre(:,:,kk),SETUP.SBNR);
    sim_sig_AdjSNRs.BcgNoisePst(:,:,kk) = rawAdjTotSNRdB(sim_sig_AdjSNRs.SrcActivPst(:,:,kk),sim_sig_AdjSNRs.BcgNoisePst(:,:,kk),SETUP.SBNR);
    sim_sig_AdjSNRs.MesNoisePre(:,:,kk) = rawAdjTotSNRdB(sim_sig_AdjSNRs.SrcActivPre(:,:,kk),sim_sig_AdjSNRs.MesNoisePre(:,:,kk),SETUP.SMNR);
    sim_sig_AdjSNRs.MesNoisePst(:,:,kk) = rawAdjTotSNRdB(sim_sig_AdjSNRs.SrcActivPst(:,:,kk),sim_sig_AdjSNRs.MesNoisePst(:,:,kk),SETUP.SMNR);
end

clearvars ii jj kk nn tmp*

!opt Checkups

whos

SETUP

sim_sig_SrcActiv % signal
sim_sig_IntNoise % interference
sim_sig_BcgNoise % background
sim_sig_MesNoise % measurment
sim_sig_AdjSNRs % merged signals (bulk) with SNR adjusted
kk = 1
2*pow2db(rawNrm(sim_sig_AdjSNRs.SrcActivPre(:,:,kk)))
2*pow2db(rawNrm(sim_sig_AdjSNRs.SrcActivPst(:,:,kk)))
rawSNRdB(sim_sig_AdjSNRs.SrcActivPre(:,:,kk),sim_sig_AdjSNRs.IntNoisePre(:,:,kk))
rawSNRdB(sim_sig_AdjSNRs.SrcActivPst(:,:,kk),sim_sig_AdjSNRs.IntNoisePst(:,:,kk))
rawSNRdB(sim_sig_AdjSNRs.SrcActivPre(:,:,kk),sim_sig_AdjSNRs.BcgNoisePre(:,:,kk))
rawSNRdB(sim_sig_AdjSNRs.SrcActivPst(:,:,kk),sim_sig_AdjSNRs.BcgNoisePst(:,:,kk))
rawSNRdB(sim_sig_AdjSNRs.SrcActivPre(:,:,kk),sim_sig_AdjSNRs.MesNoisePre(:,:,kk))
rawSNRdB(sim_sig_AdjSNRs.SrcActivPst(:,:,kk),sim_sig_AdjSNRs.MesNoisePst(:,:,kk))

% sim_sig_SrcActiv.sigSNS_pre should remain unchanged after SNR adjustments
isequal(sim_sig_AdjSNRs.SrcActivPre,sim_sig_SrcActiv.sigSNS_pre)
% sim_sig_SrcActiv.sigSNS_pre should remain unchanged after SNR adjustments
isequal(sim_sig_AdjSNRs.SrcActivPst,sim_sig_SrcActiv.sigSNS_pst)

Measured signal and covariance matrices

!opt Initial checkups

whos

!run Code

Initialization
!run Code
clearvars ii jj kk nn tmp*
Computation
!run Code
% clearvars ii jj kk nn tmp*

% Note: in this and subsequent subsections we aim at following closely notation from the paper.

if SETUP.H_Src_pert
    H_Src = sim_lfg_SrcActiv_pert.LFG;
else
    H_Src = sim_lfg_SrcActiv_orig.LFG;
end

if SETUP.H_Int_pert
    H_Int = sim_lfg_IntNoise_pert.LFG;
else
    H_Int = sim_lfg_IntNoise_orig.LFG;
end

% reduced-rank leadfield for patch constraints
[U_H_Int Si_H_Int V_H_Int] = svd(H_Int);

for ii = SETUP.IntLfgRANK+1:size(H_Int,2)
    Si_H_Int(ii,ii)=0;
end

H_Int = U_H_Int*Si_H_Int*V_H_Int';

y_Pre =     SETUP.SigPre*sim_sig_AdjSNRs.SrcActivPre ...
    + SETUP.IntPre*sim_sig_AdjSNRs.IntNoisePre ...
    + SETUP.BcgPre*sim_sig_AdjSNRs.BcgNoisePre ...
    + SETUP.MesPre*sim_sig_AdjSNRs.MesNoisePre;

y_Pst =     SETUP.SigPst*sim_sig_AdjSNRs.SrcActivPst ...
    + SETUP.IntPst*sim_sig_AdjSNRs.IntNoisePst ...
    + SETUP.BcgPst*sim_sig_AdjSNRs.BcgNoisePst ...
    + SETUP.MesPst*sim_sig_AdjSNRs.MesNoisePst;

% background activity (as in Pre segment) in Pst segment
y_PstNoise =     SETUP.SigPre*sim_sig_AdjSNRs.SrcActivPst ...
    + SETUP.IntPre*sim_sig_AdjSNRs.IntNoisePst ...
    + SETUP.BcgPre*sim_sig_AdjSNRs.BcgNoisePst ...
    + SETUP.MesPre*sim_sig_AdjSNRs.MesNoisePst;

N = cov(reshape(permute(y_Pre,[1 3 2]),[],size(y_Pre,2),1));
% N = cov(reshape(permute(y_PstNoise,[1 3 2]),[],size(y_PstNoise,2),1));
R = cov(reshape(permute(y_Pst,[1 3 2]),[],size(y_Pst,2),1));

G = H_Src'*pinv(N)*H_Src;
S = H_Src'*pinv(R)*H_Src;

G_SrcInt = [H_Src H_Int]'*pinv(N)*[H_Src H_Int];
S_SrcInt = [H_Src H_Int]'*pinv(R)*[H_Src H_Int];
C_SrcInt = pinv(S_SrcInt) - pinv(G_SrcInt);

% Estimated C for both regular and nulling filters
C_NL = C_SrcInt(1:size(H_Src,2),1:size(H_Src,2));
C = pinv(S)-pinv(G);

clear U_H_Int Si_H_Int V_H_Int G_SrcInt S_SrcInt;
!opt Checkups 1
whos
size(H_Src)
size(H_Int)
size(y_Pre)
size(y_Pst)
size(N)
size(R)
size(G)
size(S)
size(C)

% mean values of signals
y_Pst_RSH = reshape(permute(y_Pst,[1 3 2]),[],size(y_Pst,2),1);
max(abs(mean(y_Pst_RSH)))

clear y_Pst_RSH;

SrcPst = reshape(permute(sim_sig_AdjSNRs.SrcActivPst,[1 3 2]),[],size(sim_sig_AdjSNRs.SrcActivPst,2),1);
max(abs(mean(SrcPst)))

clear SrcPst;

IntPst = reshape(permute(sim_sig_AdjSNRs.IntNoisePst,[1 3 2]),[],size(sim_sig_AdjSNRs.IntNoisePst,2),1);
max(abs(mean(IntPst)))

clear IntPst;

BcgPst = reshape(permute(sim_sig_AdjSNRs.BcgNoisePst,[1 3 2]),[],size(sim_sig_AdjSNRs.BcgNoisePst,2),1);
max(abs(mean(BcgPst)))

clear BcgPst;

BcgPre = reshape(permute(sim_sig_AdjSNRs.BcgNoisePre,[1 3 2]),[],size(sim_sig_AdjSNRs.BcgNoisePre,2),1);
% note: max and min values vector across electrodes
max(abs(BcgPre))'
min(abs(BcgPre))'

clear BcgPre;

MesPst = reshape(permute(sim_sig_AdjSNRs.MesNoisePst,[1 3 2]),[],size(sim_sig_AdjSNRs.MesNoisePst,2),1);
max(abs(mean(MesPst)))

clear MesPst;

% correlation between signals check and # of highly correlated electrodes for Src, Bcg, Mes signals
SrcPst = reshape(permute(sim_sig_AdjSNRs.SrcActivPst,[1 3 2]),[],size(sim_sig_AdjSNRs.SrcActivPst,2),1);
BcgPst = reshape(permute(sim_sig_AdjSNRs.BcgNoisePst,[1 3 2]),[],size(sim_sig_AdjSNRs.BcgNoisePst,2),1);
Corr_SrcPst = corrcoef(SrcPst);

for ii = 1:length(Corr_SrcPst)
    [a k]=find(Corr_SrcPst(:,ii)>.9);
    x(ii)=sum(k);
end

x
x=[];
Corr_BcgPst = corrcoef(BcgPst);

for ii = 1:length(Corr_BcgPst)
    [a k]=find(Corr_BcgPst(:,ii)>.9);
    x(ii)=sum(k);
end

x
x=[];
Corr_SrcBcgPst = corrcoef([SrcPst BcgPst]);
Cross_SrcBcgPst = Corr_SrcBcgPst(length(Corr_SrcPst)+1:end,1:length(Corr_SrcPst));
max([max(Cross_SrcBcgPst) abs(min(Cross_SrcBcgPst))])

clear Corr_SrcPst Corr_BcgPst Corr_SrcBcgPst Cross_SrcBcgPst x;

MesPst = reshape(permute(sim_sig_AdjSNRs.MesNoisePst,[1 3 2]),[],size(sim_sig_AdjSNRs.MesNoisePst,2),1);
Corr_SrcPst = corrcoef(SrcPst);

for ii = 1:length(Corr_SrcPst)
    [a k]=find(Corr_SrcPst(:,ii)>.9);
    x(ii)=sum(k);
end

x
x=[];
Corr_MesPst = corrcoef(MesPst);

for ii = 1:length(Corr_MesPst)
    [a k]=find(Corr_MesPst(:,ii)>.9);
    x(ii)=sum(k);
end

x
x=[];
Corr_SrcMesPst = corrcoef([SrcPst MesPst]);
Cross_SrcMesPst = Corr_SrcMesPst(length(Corr_SrcPst)+1:end,1:length(Corr_SrcPst));
max([max(Cross_SrcMesPst) abs(min(Cross_SrcMesPst))])

clear Corr_MesPst Corr_SrcMesPst Cross_SrcMesPst x;

Corr_BcgMesPst = corrcoef([BcgPst MesPst]);
Cross_BcgMesPst = Corr_BcgMesPst(length(Corr_SrcPst)+1:end,1:length(Corr_SrcPst));
max([max(Cross_BcgMesPst) abs(min(Cross_BcgMesPst))])

clear BcgPst MesPst Corr_BcgMesPst Cross_BcgMesPst;

IntPst = reshape(permute(sim_sig_AdjSNRs.IntNoisePst,[1 3 2]),[],size(sim_sig_AdjSNRs.IntNoisePst,2),1);
Corr_SrcIntPst = corrcoef([SrcPst IntPst]);
Cross_SrcIntPst = Corr_SrcIntPst(length(Corr_SrcPst)+1:end,1:length(Corr_SrcPst));
max([max(Cross_SrcIntPst) abs(min(Cross_SrcIntPst))])

clear ii a k SrcPst Corr_SrcPst IntPst Corr_SrcIntPst Cross_SrcIntPst;

!opt Checkups

rec_opt
whos

[s05] Spatial filtering

Filter preparations

NL
%  NL filter as proposed in Hui & Leahy 2010
H_SrcInt = [H_Src H_Int];
P_NL = [eye(size(H_Src,2)) zeros(size(H_Src,2),size(H_Int,2))];
EIG-LCMV
%  EIG-LCMV filter
[UR, SiR, ~] = svd(R);
P_EIG = UR(:,1:SETUP.RANK_EIG)*UR(:,1:SETUP.RANK_EIG)';

clear UR SiR;
sMVP
Initialization
%  sMVP filters
H_Src_R = pinv(sqrtm(R))*H_Src;
H_Src_N = pinv(sqrtm(N))*H_Src;
sMVP_MSE
%  sMVP_MSE filter
% note: S and G use only H_Src, as we want to recover only activity of interest, not interference
% note: pinv(H_Src_R)*pinv(H_Src_R)' = pinv(S)
K_MSE = pinv(S)-2*C;
[U_K_MSE, W_K_MSE] = eig(K_MSE);
[~, p_K_MSE] = sort(diag(W_K_MSE));
% note: for selecting optimal rank, Theobald's Th. can be used without evaluation of the cost function as is done here
U_K_MSE = U_K_MSE(:,p_K_MSE);
sMVP_MSE_ranks = zeros(1,size(H_Src,2));

for jj = 1:size(H_Src,2)
    sMVP_MSE_ranks(jj) = trace(U_K_MSE(:,1:jj)*U_K_MSE(:,1:jj)'*K_MSE);
end

[~, sMVP_MSE_rank_opt] = min(sMVP_MSE_ranks);
P_sMVP_MSE_opt = U_K_MSE(:,1:sMVP_MSE_rank_opt)*U_K_MSE(:,1:sMVP_MSE_rank_opt)';

rec_opt.ranks.sMVP_MSE = sMVP_MSE_rank_opt;
clear K_MSE U_K_MSE W_K_MSE p_K_MSE sMVP_MSE_ranks sMVP_MSE_rank_opt;
sMVP_R
%  sMVP_R filter
% note: S and G use only H_Src, as we want to recover only activity of interest, not interference
% note: pinv(H_Src_R)*pinv(H_Src_R)' = pinv(S)
K_MSE = pinv(S)-2*C;

K_R = K_MSE+2*C;
[U_K_R, W_K_R] = eig(K_R);
[~, p_K_R] = sort(diag(W_K_R));
U_K_R = U_K_R(:,p_K_R);
sMVP_R_ranks = zeros(1,size(H_Src,2));

for jj = 1:size(H_Src,2)
    sMVP_R_ranks(jj) = trace(U_K_R(:,1:jj)*U_K_R(:,1:jj)'*K_MSE);
end

[~, sMVP_R_rank_opt] = min(sMVP_R_ranks);
P_sMVP_R_opt = U_K_R(:,1:sMVP_R_rank_opt)*U_K_R(:,1:sMVP_R_rank_opt)';

rec_opt.ranks.sMVP_R = sMVP_R_rank_opt;
clear K_MSE K_R U_K_R W_K_R p_K_R sMVP_R_ranks;
sMVP_N
%  sMVP_N filter
% note: S and G use only H_Src, as we want to recover only activity of interest, not interference
% note: pinv(H_Src_N)*pinv(H_Src_N)' = pinv(G)
K_MSE_N = pinv(G)-C;

K_N = K_MSE_N+C;
[U_K_N, W_K_N] = eig(K_N);
[~, p_K_N] = sort(diag(W_K_N));
U_K_N = U_K_N(:,p_K_N);
sMVP_N_ranks = zeros(1,size(H_Src,2));

for jj = 1:size(H_Src,2)
    sMVP_N_ranks(jj) = trace(U_K_N(:,1:jj)*U_K_N(:,1:jj)'*K_MSE_N);
end

[~, sMVP_N_rank_opt] = min(sMVP_N_ranks);
P_sMVP_N_opt = U_K_N(:,1:sMVP_N_rank_opt)*U_K_N(:,1:sMVP_N_rank_opt)';

rec_opt.ranks.sMVP_N = sMVP_N_rank_opt;
clear K_MSE_N K_N U_K_N W_K_N p_K_N sMVP_N_ranks;
Cleanup
%  sMVP filters
clear H_Src_R H_Src_N;
sMVP_NL
Initialization
%  sMVP-NL filters
H_Src_R = pinv(sqrtm(R))*H_Src;
H_Src_N = pinv(sqrtm(N))*H_Src;

H_Int_R = pinv(sqrtm(R))*H_Int;
H_Int_N = pinv(sqrtm(N))*H_Int;

P_sMVP_NL_R = eye(size(H_Int_R,1))-H_Int_R*pinv(H_Int_R);
P_sMVP_NL_N = eye(size(H_Int_N,1))-H_Int_N*pinv(H_Int_N);
sMVP_NL_MSE
%  sMVP_NL_MSE filter
K_NL_MSE = pinv(P_sMVP_NL_R*H_Src_R)*P_sMVP_NL_R*(pinv(P_sMVP_NL_R*H_Src_R))'-2*C_NL;
[U_K_NL_MSE, W_K_NL_MSE] = eig(K_NL_MSE);
[~, p_K_NL_MSE] = sort(diag(W_K_NL_MSE));
% note: for selecting optimal rank, Theobald's Th. can be used without evaluation of the cost function as is done here
U_K_NL_MSE = U_K_NL_MSE(:,p_K_NL_MSE);
sMVP_NL_MSE_ranks = zeros(1,size(H_Src,2));

for jj = 1:size(H_Src,2)
    sMVP_NL_MSE_ranks(jj) = trace(U_K_NL_MSE(:,1:jj)*U_K_NL_MSE(:,1:jj)'*K_NL_MSE);
end

[~, sMVP_NL_MSE_rank_opt] = min(sMVP_NL_MSE_ranks);
P_sMVP_NL_MSE_opt = U_K_NL_MSE(:,1:sMVP_NL_MSE_rank_opt)*U_K_NL_MSE(:,1:sMVP_NL_MSE_rank_opt)';

rec_opt.ranks.sMVP_NL_MSE = sMVP_NL_MSE_rank_opt;
clear K_NL_MSE U_K_NL_MSE W_K_NL_MSE p_K_NL_MSE sMVP_NL_MSE_ranks sMVP_NL_MSE_rank_opt;
sMVP_NL_R
%  sMVP_NL_R filter
K_NL_MSE = pinv(P_sMVP_NL_R*H_Src_R)*P_sMVP_NL_R*(pinv(P_sMVP_NL_R*H_Src_R))'-2*C_NL;

%K_NL_R = pinv(P_sMVP_NL_R*H_Src_R)*P_sMVP_NL_R*(pinv(P_sMVP_NL_R*H_Src_R))';
K_NL_R = K_NL_MSE+2*C_NL;
[U_K_NL_R, W_K_NL_R] = eig(K_NL_R);
[~, p_K_NL_R] = sort(diag(W_K_NL_R));
U_K_NL_R = U_K_NL_R(:,p_K_NL_R);
sMVP_NL_R_ranks = zeros(1,size(H_Src,2));

for jj = 1:size(H_Src,2)
    sMVP_NL_R_ranks(jj) = trace(U_K_NL_R(:,1:jj)*U_K_NL_R(:,1:jj)'*K_NL_MSE);
end

[~, sMVP_NL_R_rank_opt] = min(sMVP_NL_R_ranks);
P_sMVP_NL_R_opt = U_K_NL_R(:,1:sMVP_NL_R_rank_opt)*U_K_NL_R(:,1:sMVP_NL_R_rank_opt)';

rec_opt.ranks.sMVP_NL_R = sMVP_NL_R_rank_opt;
clear K_NL_MSE K_NL_R U_K_NL_R W_K_NL_R p_K_NL_R sMVP_NL_R_ranks sMVP_NL_R_rank_opt;
sMVP_NL_N
%  sMVP_NL_N filter
K_NL_MSE_N = pinv(P_sMVP_NL_N*H_Src_N)*P_sMVP_NL_N*(pinv(P_sMVP_NL_N*H_Src_N))'-C_NL;

%K_NL_N = pinv(P_sMVP_NL_N*H_Src_N)*P_sMVP_NL_N*(pinv(P_sMVP_NL_N*H_Src_N))';
K_NL_N = K_NL_MSE_N+C_NL;
[U_K_NL_N, W_K_NL_N] = eig(K_NL_N);
[~, p_K_NL_N] = sort(diag(W_K_NL_N));
U_K_NL_N = U_K_NL_N(:,p_K_NL_N);
sMVP_NL_N_ranks = zeros(1,size(H_Src,2));

for jj = 1:size(H_Src,2)
    sMVP_NL_N_ranks(jj) = trace(U_K_NL_N(:,1:jj)*U_K_NL_N(:,1:jj)'*K_NL_MSE_N);
end

[~, sMVP_NL_N_rank_opt] = min(sMVP_NL_N_ranks);
% note the simplified notation for P_N_opt
P_sMVP_NL_N_opt = U_K_NL_N(:,1:sMVP_NL_N_rank_opt)*U_K_NL_N(:,1:sMVP_NL_N_rank_opt)';

rec_opt.ranks.sMVP_NL_N = sMVP_NL_N_rank_opt;
clear K_NL_MSE_N K_NL_N U_K_NL_N W_K_NL_N p_K_NL_N sMVP_NL_N_ranks sMVP_NL_N_rank_opt;
Cleanup
%  sMVP-NL filters
clear H_Int_R H_Int_N;

Filter definitions

!run Code

LCMV
% note: S and G use only H_Src, as we want to recover only activity of interest, not interference 
rec_flt.LCMV_R = pinv(S)*H_Src'*pinv(R);
rec_flt.LCMV_N = pinv(G)*H_Src'*pinv(N);
NL
% As proposed in Hui & Leahy 2010
rec_flt.NL = P_NL*pinv(H_SrcInt'*pinv(R)*H_SrcInt)*H_SrcInt'*pinv(R);
MMSE
rec_flt.MMSE = C*H_Src'*pinv(R);
MMSE_INT
rec_flt.MMSE_INT = C_SrcInt(1:size(H_Src,2),:)*H_SrcInt'*pinv(R);
ZF
rec_flt.ZF = pinv(H_Src);
RANDN
rec_flt.RANDN = randn(size(H_Src'));
ZEROS
rec_flt.ZEROS = zeros(size(H_Src'));
EIG-LCMV
rec_flt.EIG_LCMV_R = rec_flt.LCMV_R*P_EIG;
rec_flt.EIG_LCMV_N = rec_flt.LCMV_N*P_EIG;
PREWHITENED-LCMV
% not applicable in our case as it assumes access to covariance matrix of interference + background noise + measurement noise, whereas in our case N does not contain interference
sMVP
rec_flt.sMVP_MSE = P_sMVP_MSE_opt*rec_flt.LCMV_R;
rec_flt.sMVP_R = P_sMVP_R_opt*rec_flt.LCMV_R;
rec_flt.sMVP_N = P_sMVP_N_opt*rec_flt.LCMV_N;
sMVP_NL
rec_flt.sMVP_NL_MSE = P_sMVP_NL_MSE_opt*pinv(P_sMVP_NL_R*H_Src_R)*P_sMVP_NL_R*pinv(sqrtm(R));
rec_flt.sMVP_NL_R = P_sMVP_NL_R_opt*pinv(P_sMVP_NL_R*H_Src_R)*P_sMVP_NL_R*pinv(sqrtm(R));
rec_flt.sMVP_NL_N = P_sMVP_NL_N_opt*pinv(P_sMVP_NL_N*H_Src_N)*P_sMVP_NL_N*pinv(sqrtm(N));
Optional clearing of selected filters
if(SETUP.fltREMOVE)
    rec_flt = rmfield(rec_flt,'RANDN');
    rec_flt = rmfield(rec_flt,'ZEROS');
end
Cleanup
rawFixStrJoin

clearvars R N C C_NL S G P_* H_* jj;

!opt Checkups

whos
rec_flt
rec_opt.ranks

Execution

!run Signal reconstruction

Reconstruct signal in the sources using previously prepared spatial filters.

clearvars rec_sig ii jj kk nn tmp*
rec_sig.Original = sim_sig_SrcActiv.sigSRC_pst;
rec_sig.Dummy    = sim_sig_SrcActiv.sigSRC_pre;
tmp_fltFields    = fieldnames(rec_flt);

for nn = 1:length(tmp_fltFields),
    for kk = 1:SETUP.K00,
        rec_sig.(tmp_fltFields{nn})(:,:,kk) = (rec_flt.(tmp_fltFields{nn}) * y_Pst(:,:,kk)')';
    end,
end

clearvars ii jj kk nn tmp*
!opt Checkups
whos
rec_flt
rec_opt
rec_sig
whos

!run Functional dependencies

Calculate MVAR model coefficients and PDC.

NB: Keep in mind that P00 is restricted to single value, i.e. the actual order of the MVAR model used to generate time-courses for signal of interest (it is not being estimated here).

clearvars ii jj kk nn rec_funDep_A00 rec_funDep_PDC
rec_funDep_A00.Original = sim_sig_SrcActiv.A00;

[~,rec_funDep_A00.Dummy,~,~,~,~] = arfit(sim_sig_SrcActiv.sigSRC_pre,sim_sig_SrcActiv.P00,sim_sig_SrcActiv.P00);

tmp_fltFields    = fieldnames(rec_flt);
for nn = 1:length(tmp_fltFields),[~,rec_funDep_A00.(tmp_fltFields{nn}),~,~,~,~] = arfit(rec_sig.(tmp_fltFields{nn}),SETUP.P00,SETUP.P00);end

tmp_allFields    = fieldnames(rec_funDep_A00);
for nn = 1:length(tmp_allFields),rec_funDep_PDC.(tmp_allFields{nn}) = abs(PDC(rec_funDep_A00.(tmp_allFields{nn}),SETUP.PDC_RES));end
!opt Checkups
whos
whos rec*
rec_flt
rec_opt
rec_opt.ranks
rec_sig
rec_funDep_A00
rec_funDep_PDC

[s05] Localization

Locallizers preparations

!run Preparations

% pre-computed leadfields for source candidates
load('./mat/sel_src.mat');    

Locallizers definitions

!run MAI and MPZ Locallizers

structure = sel_src.lfg;
% lf is the array of cells containing all leafields within ROI
lf = structure.leadfield; 
% position of sources
pos_Src = sim_lfg_SrcActiv_orig.lfg.pos;
[~, pos_Src_ind]=ismember(pos_Src,structure.pos,'rows');

% Results will be stored in structs with fields: 
% leadfield, source positions, localization error, rank selected
% 1 = MAI(2011), 2 = MAI(2013), 3 = MPZ(2011), 4 = MPZ(2013)
% 5 = MAI_RR_I, 6 = MAI_RR_C, 7 = MPZ_RR_I, 8 = MPZ_RR_C
RES = repmat(struct('H',[],'sources',[]),8,1);

% to be used for the proposed heuristic rank-selection criterion 
% leading eigenvalues of R*pinv(N) are equal to those of C*G0+1
x = sort(eig(R*pinv(N)),'descend');
x = x(1:sum(SETUP.SRCS(:,1)));
% percentage of variance explained
y = x./sum(x);
% percent of explained variance
rs_opt = min(find(cumsum(y)>0.8));

clear x y;      

for i = 1:sum(SETUP.SRCS(:,1))
    tic
    i
    % for REAL WORLD APPLICABLE activity indices, rank is fixed
    RES_tmp = repmat({zeros(length(lf),1)}, 1, 8);
    rs = min([i rs_opt]);
    
    for k = 1:8
        
        for j = 1:length(lf)
            
            h_curr = lf{j};
            
            % we use H obtained for a given index at previous iteration with respect to i, 
            % starting with null matrix
            h = [RES(k).H h_curr];

            G = h'*pinv(N)*h;
            S = h'*pinv(R)*h;
            T = h'*pinv(R)*N*pinv(R)*h;
            
            [U D ~] = svd(S);            
            
            MAI_eigenv = sort(real(eig(G*pinv(S))),'descend');
            MPZ_eigenv = sort(real(eig(S*pinv(T))),'descend');

            if ismember(k,[6 8]) & i>rs_opt
                % Csq is rank-deficient if h = lf{j} matches previously found sources
                Csq = real(sqrtm(pinv(S)-pinv(G)));            
                h2 = h*Csq;
                
                G2 = h2'*pinv(N)*h2;
                S2 = h2'*pinv(R)*h2;
                T2 = h2'*pinv(R)*N*pinv(R)*h2;
                
                [U2 D2 ~] = svd(S2);
            end
            
            % REAL-WORLD APPLICABLE family of indices
            switch k
              case 1
                % MAI(2011) index
                RES_tmp{k}(j) = sum(MAI_eigenv);
              case 2             
                % MAI(2013) index
                RES_tmp{k}(j) = sum(MAI_eigenv(1:rs));
              case 3
                % MPZ(2011) index
                RES_tmp{k}(j) = sum(MPZ_eigenv);    
              case 4
                % MPZ(2013) index
                RES_tmp{k}(j) = sum(MPZ_eigenv(1:rs));
              case 5
                % MAI_RR_I index
                P = U(:,1:rs)*U(:,1:rs)';
                RES_tmp{k}(j) = trace(G*pinv(S)*P);
                clear P;
              case 6
                % MAI_RR_C index
                if i<=rs_opt
                    RES_tmp{k}(j) = RES_tmp{k-1}(j);
                elseif i>rs_opt % in this case rs=rs_opt    
                    P2 = U2(:,1:rs_opt)*U2(:,1:rs_opt)';
                    RES_tmp{k}(j) = trace(G2*pinv(S2)*P2);
                    clear P2;
                end
              case 7
                % MPZ_RR_I index
                P = U(:,1:rs)*U(:,1:rs)';
                RES_tmp{k}(j) = trace(S*pinv(T)*P);
                clear P;                       
              case 8
                % MPZ_RR_C index
                if i<=rs_opt
                    RES_tmp{k}(j) = RES_tmp{k-1}(j);
                elseif i>rs_opt % in this case rs=rs_opt        
                    P2 = U2(:,1:rs_opt)*U2(:,1:rs_opt)';
                    RES_tmp{k}(j) = trace(S2*pinv(T2)*P2);
                    clear P2;
                end
            end
            
            % explicit clear to emphasize that all matrices 
            % are created anew at each iteration for each j and k
            clear h_curr h G S T Csq h2 G2 S2 T2 U D U2 D2 P P2;
            
            % below: end of j = 1:length(lf) loop    
        end

        [~, w]=max(RES_tmp{k});
        [dis dis_ind] = pdist2(pos_Src,structure.pos(w,:),'chebychev','Smallest',1);

        % store results
        RES(k).H = [RES(k).H lf{w}];
        RES(k).sources(i).candidate_number = w;
        RES(k).sources(i).rank_opt = rs;
        RES(k).sources(i).source_discovered = dis_ind;
        RES(k).sources(i).distance = dis;

        % below: end of k = 1:8 loop
    end
    
    % below: end of i = 1:SETUP.RANK_EIG loop            
    toc
end

clear structure lf pos_Src;

[s06] Reconstruction error evaluation

!opt Code for testing of source reconstruction error evaluation

Replace original signal with sine and the reconstructed signals with waves that produce easy to predict error values…

if 0
    clearvars rec* ii jj kk nn tmp*

    tmp_arg = linspace(0,8*pi,SETUP.n00)';
    size(tmp_arg)

    rec_sig.Original = repmat(sin(tmp_arg),[1,sum(SETUP.SRCS(:,1)),SETUP.K00]);
    rec_sig.Dummy    = repmat(cos(tmp_arg),[1,sum(SETUP.SRCS(:,1)),SETUP.K00]);

    rec_sig.Test00   = rec_sig.Original
    rec_sig.Test01   = -rec_sig.Original
    rec_sig.Test02   = rec_sig.Original+0.2*randn(size(rec_sig.Original))
    rec_sig.Test03   = -rec_sig.Original+0.2*randn(size(rec_sig.Original))
    rec_sig.Test04   = zeros(size(rec_sig.Original))
end

clearvars ii jj kk nn tmp*
whos
whos rec*
rec_sig

Preparation

     clearvars ii jj kk nn tmp* 
     tmp_allFields  = fieldnames(rec_sig);

     for nn = 1:length(tmp_allFields)
         for ii = 1:SETUP.n00
             for jj = 1:SETUP.K00
rec_sig.(tmp_allFields{nn})(ii,:,jj)=rec_sig.(tmp_allFields{nn})(ii,:,jj)/norm(rec_sig.(tmp_allFields{nn})(ii,:,jj));
             end
         end
     end

Euclid for signal

clearvars ii jj kk nn tmp* rec_sigAmp_ErrEuclid
tmp_allFields  = fieldnames(rec_sig);

for nn = 1:length(tmp_allFields)
    tmp_error = zeros(SETUP.n00,SETUP.K00);
    for ii = 1:SETUP.n00
        for jj = 1:SETUP.K00
            tmp_error(ii,jj)=norm(rec_sig.(tmp_allFields{1})(ii,:,jj)-rec_sig.(tmp_allFields{nn})(ii,:,jj))^2;                  
        end
    end
    rec_sigAmp_ErrEuclid.(tmp_allFields{nn})=mean(mean(tmp_error));
end

!opt Checkups

tmp_allFields  = fieldnames(rec_sig);
disp(tmp_allFields{1})

isequal(rec_sig.(tmp_allFields{1}),sim_sig_SrcActiv.sigSRC_pst)
norm(rec_sig.(tmp_allFields{1})(:)-sim_sig_SrcActiv.sigSRC_pst(:))

size(rec_sig.(tmp_allFields{1}))
size(sim_sig_SrcActiv.sigSRC_pre)
size(sim_sig_AdjSNRs.SrcActivPre)

CorrCf for signal

clearvars ii jj kk nn tmp* rec_sigAmp_ErrCorrCf
tmp_allFields  = fieldnames(rec_sig);

for nn = 1:length(tmp_allFields)
    tmp_error = zeros(sum(SETUP.SRCS(:,1)),SETUP.K00);
    for kk = 1:sum(SETUP.SRCS(:,1))
        for jj = 1:SETUP.K00
            tmp_x=corrcoef(rec_sig.(tmp_allFields{1})(:,kk,jj),rec_sig.(tmp_allFields{nn})(:,kk,jj));
            tmp_error(kk,jj)=tmp_x(1,end);
        end
    end
    rec_sigAmp_ErrCorrCf.(tmp_allFields{nn}) = mean(mean(tmp_error));
end

Euclid for MVAR coefficients matrix

  
clearvars ii jj kk nn tmp* rec_funDep_A00_ErrMonday rec_funDep_A00_ErrEuclid
tmp_allFields  = fieldnames(rec_sig);

for nn = 1:length(tmp_allFields)
    rec_funDep_A00_ErrEuclid.(tmp_allFields{nn}) = (norm(rec_funDep_A00.(tmp_allFields{1}) - rec_funDep_A00.(tmp_allFields{nn}),'fro')^2);
end

CorrCf for MVAR coefficient matrix

clearvars ii jj kk nn tmp* rec_funDep_A00_ErrCorrCf
tmp_allFields  = fieldnames(rec_sig);

for nn = 1:length(tmp_allFields)
    tmp_error = zeros(sum(SETUP.SRCS(:,1)),1);
    for kk = 1:sum(SETUP.SRCS(:,1))
        tmp_x=corrcoef(rec_funDep_A00.(tmp_allFields{1})(kk,:),rec_funDep_A00.(tmp_allFields{nn})(kk,:));
        tmp_error(kk)=tmp_x(1,end);
    end
    rec_funDep_A00_ErrCorrCf.(tmp_allFields{nn}) = mean(tmp_error);
end

Euclid for PDC coefficient matrix

clearvars ii jj kk nn tmp* rec_funDep_PDC_err rec_funDep_PDC_ErrEuclid
tmp_allFields  = fieldnames(rec_sig);

for nn = 1:length(tmp_allFields)
    tmp_error = zeros(sum(SETUP.SRCS(:,1)),1);
    for ii = 1:sum(SETUP.SRCS(:,1))
        tmp_error(ii) = norm(squeeze(rec_funDep_PDC.(tmp_allFields{1})(ii,:,:)) - squeeze(rec_funDep_PDC.(tmp_allFields{nn})(ii,:,:)),'fro')^2;
    end
    rec_funDep_PDC_ErrEuclid.(tmp_allFields{nn}) = mean(tmp_error);
end

CorrCf for PDC coefficient matrix

clearvars ii jj kk nn tmp*  rec_funDep_PDC_ErrCorrCf
tmp_allFields  = fieldnames(rec_sig);

for nn = 1:length(tmp_allFields)
    tmp_error = zeros(sum(SETUP.SRCS(:,1)),1);
    for ii = 1:sum(SETUP.SRCS(:,1))
        tmp_x=corrcoef(reshape(squeeze(rec_funDep_PDC.(tmp_allFields{1})(ii,:,:)),[],1),reshape(squeeze(rec_funDep_PDC.(tmp_allFields{nn})(ii,:,:)),[],1));
        tmp_error(ii)=tmp_x(1,end);
    end
    rec_funDep_PDC_ErrCorrCf.(tmp_allFields{nn}) = mean(tmp_error);
end

Vectorize results

clearvars ii jj kk nn tmp* rec*vec

rec_sigAmp_ErrEuclid_vec = cellfun(@(fn) rec_sigAmp_ErrEuclid.(fn), fieldnames(rec_sigAmp_ErrEuclid), 'UniformOutput', false);
rec_sigAmp_ErrEuclid_vec = squeeze(vertcat(rec_sigAmp_ErrEuclid_vec{:}));

rec_sigAmp_ErrCorrCf_vec = cellfun(@(fn) rec_sigAmp_ErrCorrCf.(fn), fieldnames(rec_sigAmp_ErrCorrCf), 'UniformOutput', false);
rec_sigAmp_ErrCorrCf_vec = squeeze(vertcat(rec_sigAmp_ErrCorrCf_vec{:}));

rec_funDep_A00_ErrEuclid_vec = cellfun(@(fn) rec_funDep_A00_ErrEuclid.(fn), fieldnames(rec_funDep_A00_ErrEuclid), 'UniformOutput', false);
rec_funDep_A00_ErrEuclid_vec = squeeze(vertcat(rec_funDep_A00_ErrEuclid_vec{:}));

rec_funDep_A00_ErrCorrCf_vec = cellfun(@(fn) rec_funDep_A00_ErrCorrCf.(fn), fieldnames(rec_funDep_A00_ErrCorrCf), 'UniformOutput', false);
rec_funDep_A00_ErrCorrCf_vec = squeeze(vertcat(rec_funDep_A00_ErrCorrCf_vec{:}));

rec_funDep_PDC_ErrEuclid_vec = cellfun(@(fn) rec_funDep_PDC_ErrEuclid.(fn), fieldnames(rec_funDep_PDC_ErrEuclid), 'UniformOutput', false);
rec_funDep_PDC_ErrEuclid_vec = squeeze(vertcat(rec_funDep_PDC_ErrEuclid_vec{:}));

rec_funDep_PDC_ErrCorrCf_vec = cellfun(@(fn) rec_funDep_PDC_ErrCorrCf.(fn), fieldnames(rec_funDep_PDC_ErrCorrCf), 'UniformOutput', false);
rec_funDep_PDC_ErrCorrCf_vec = squeeze(vertcat(rec_funDep_PDC_ErrCorrCf_vec{:}));

Combine results in single array

clearvars ii jj kk nn tmp* rec_res

if     ~isequal(fieldnames(rec_sigAmp_ErrEuclid),fieldnames(rec_sigAmp_ErrCorrCf))
    error('check fieldnames')
elseif ~isequal(fieldnames(rec_sigAmp_ErrEuclid),fieldnames(rec_funDep_A00_ErrEuclid))
    error('check fieldnames')
elseif ~isequal(fieldnames(rec_sigAmp_ErrEuclid),fieldnames(rec_funDep_A00_ErrCorrCf))
    error('check fieldnames')
elseif ~isequal(fieldnames(rec_sigAmp_ErrEuclid),fieldnames(rec_funDep_PDC_ErrEuclid))
    error('check fieldnames')
elseif ~isequal(fieldnames(rec_sigAmp_ErrEuclid),fieldnames(rec_funDep_PDC_ErrCorrCf))
    error('check fieldnames')
else
    rec_res.table_arrC = [ rec_sigAmp_ErrEuclid_vec,  rec_sigAmp_ErrCorrCf_vec,  rec_funDep_A00_ErrEuclid_vec,  rec_funDep_A00_ErrCorrCf_vec,  rec_funDep_PDC_ErrEuclid_vec,  rec_funDep_PDC_ErrCorrCf_vec];
    rec_res.table_varN = {'rec_sigAmp_ErrEuclid_vec','rec_sigAmp_ErrCorrCf_vec','rec_funDep_A00_ErrEuclid_vec','rec_funDep_A00_ErrCorrCf_vec','rec_funDep_PDC_ErrEuclid_vec','rec_funDep_PDC_ErrCorrCf_vec'};
    rec_res.table_rowN = fieldnames(rec_sigAmp_ErrEuclid);
    rec_res.table = array2table(rec_res.table_arrC,'VariableNames',rec_res.table_varN,'RowNames',rec_res.table_rowN);
end

Checkups

rec_res.table_arrC = [ rec_sigAmp_ErrEuclid_vec,  rec_sigAmp_ErrCorrCf_vec ];
rec_res.table_varN = {'rec_sigAmp_ErrEuclid_vec','rec_sigAmp_ErrCorrCf_vec'};
rec_res.table_rowN = fieldnames(rec_sigAmp_ErrEuclid);
rec_res.table = array2table(rec_res.table_arrC,'VariableNames',rec_res.table_varN,'RowNames',rec_res.table_rowN);

!opt Checkups (RESULTS CAN BE CHECKED HERE)

whos rec*
whos rec*vec

rec_res

sortrows(rec_res.table,'rec_sigAmp_ErrEuclid_vec')
sortrows(rec_res.table,'rec_sigAmp_ErrCorrCf_vec','descend')

sortrows(rec_res.table,'rec_funDep_A00_ErrEuclid_vec')
sortrows(rec_res.table,'rec_funDep_A00_ErrCorrCf_vec','descend')
sortrows(rec_res.table,'rec_funDep_PDC_ErrEuclid_vec')
sortrows(rec_res.table,'rec_funDep_PDC_ErrCorrCf_vec','descend')

!opt Checkups

whos rec*
whos rec*vec

rec_sigAmp_ErrEuclid
rec_sigAmp_ErrCorrCf
rec_funDep_A00_ErrEuclid
rec_funDep_A00_ErrMonday
rec_funDep_PDC_ErrEuclid
rec_funDep_PDC_ErrMonday

!opt Checkups

rec_sig
rec_sigAmp_ErrEuclid
[r_opt2,r_opt3,size(vSRC_pst,2)]




TMP_COV = cov(sim_sig_SrcActiv.sigSRC_pst(:,:,1));
TMP_COR = corrcoef(sim_sig_SrcActiv.sigSRC_pst(:,:,1));

figure(1);clf;
rawImgSC(TMP_COV);
tmp_colorMapMat = rawHotColdColorMap(2048);
caxis([-max(abs(min(min(TMP_COV))),abs(max(max(TMP_COV)))) max(abs(min(min(TMP_COV))),abs(max(max(TMP_COV))))]);
colormap(tmp_colorMapMat);
colorbar;

figure(2);clf;
rawImgSC(TMP_COR);
tmp_colorMapMat = rawHotColdColorMap(2048);
caxis([-max(abs(min(min(TMP_COR))),abs(max(max(TMP_COR)))) max(abs(min(min(TMP_COR))),abs(max(max(TMP_COR))))]);
colormap(tmp_colorMapMat);
colorbar;





sort(eig(K))
figure(501);clf;set(gcf, 'Position', SETUP.DISP);rawImgSC(sort(eig(K)));colorbar;
rank(Hp)
svd(Hp)
svd(S1)
R



rec_sig
rec_sigAmp_ErrEuclid
[r_opt2,r_opt3,size(vSRC_pst,2)]
rec_funDep_A00
rec_funDep_A00_ErrEuclid
rec_funDep_PDC
rec_funDep_PDC_ErrEuclid
rec_funDep_PDC_ErrMonday



figure(100000)
set(gcf, 'Position', SETUP.DISP);
subplot(2,1,1)
plot(rec_funDep_PDC_ErrEuclid);colorbar;
subplot(2,1,2)
plot(rec_funDep_PDC_ErrMonday);colorbar;



figure(30000);clf;
set(gcf, 'Position', SETUP.DISP);
for nn = 1:length(tmp_allFields)
    subplot(length(tmp_allFields),1,nn)
    imagesc(rec_funDep_A00.(tmp_allFields{nn}));
    tmp_colorMapMat = jet(255);
    tmp_colorMapMat(128,:) = [1 1 1];
    caxis([-max(abs(min(min(rec_funDep_A00.(tmp_allFields{nn})))),abs(max(max(rec_funDep_A00.(tmp_allFields{nn}))))) max(abs(min(min(rec_funDep_A00.(tmp_allFields{nn})))),abs(max(max(rec_funDep_A00.(tmp_allFields{nn})))))]);
    colormap(tmp_colorMapMat);
    colorbar;
    hold on;
    tmp_stem = 0.5+sim_sig_SrcActiv.S00:sim_sig_SrcActiv.S00:sim_sig_SrcActiv.S00*(sim_sig_SrcActiv.P00-1)+0.5;
    tmp_vals = sim_sig_SrcActiv.S00+0.5*ones(size(tmp_stem));
    stem(tmp_stem,tmp_vals,'Color','k','LineWidth',0.5,'Marker', 'none');
    set(gca,'XTick',[1:sim_sig_SrcActiv.S00*sim_sig_SrcActiv.P00])
    title(tmp_allFields{nn})
end



rec_sigAmp_ErrEuclid
[r_opt2,r_opt3,size(vSRC_pst,2)]
rec_funDep_PDC_ErrEuclid
rec_funDep_PDC_ErrMonday



for nn = 1:length(tmp_allFields)
    figure(40000+nn);clf;
    set(gcf, 'Position', SETUP.DISP);
    rawPlotPDC(rec_funDep_PDC.(tmp_allFields{nn}),SETUP.PDC_RES)
    title(tmp_allFields{nn})
end

[s07] BATCH

Single run for tangled matlab-scripts.

[p00] RUN (this is the one for single simulations run)

The below code block can be used to test simulations single run.

NB: before running the code below remember to tangle code blocks after any modifications !!!

% if exist('fPath'), cd(fPath); else, try, cd('~/supFunSim/'); catch, warningMessage = 'Problem encoutered while trying to change working directory to ''~/supFunSim/''.'; end; end; disp(['CYBERCRAFT:: pwd is: ',pwd])

run('./tg_s07_BATCH___01_Prelude.m'); whos
SETUP
chkSim___tg_s01_PRE___001(SETUP);
chkSim___tg_s01_PRE___000_PARSE_SETUP(SETUP,sel_atl);
run('./tg_s07_BATCH___02_Signals.m'); whos
run('./tg_s07_BATCH___03_Leadfields.m'); whos

% if BcgNoise (biological background  noise) is to be white Gaussian,
% then please uncomment the following two lines. 
% sim_sig_BcgNoise.sigSRC_pre = randn(size(sim_sig_BcgNoise.sigSRC_pre));
% sim_sig_BcgNoise.sigSRC_pst = randn(size(sim_sig_BcgNoise.sigSRC_pst));
% if one wishes the biological noise on sensors to be white Gaussian
% sim_sig_BcgNoise.sigSNS_pre = randn(size(sim_sig_BcgNoise.sigSNS_pre));
% sim_sig_BcgNoise.sigSNS_pst = randn(size(sim_sig_BcgNoise.sigSNS_pst));

% rawImgSC(squareform(pdist(sim_lfg_SrcActiv_orig.lfg.pos,'euclidean')))

run('./tg_s07_BATCH___04_Preparations.m');    whos

switch SETUP.supSwitch
  case {'rec'}

    % Reconstruction
    disp('Reconstruction')
    run('./tg_s07_BATCH___05_Filters.m'); whos

    % Check the results
    sortrows(rec_res.table,'rec_sigAmp_ErrEuclid_vec')
    sortrows(rec_res.table,'rec_sigAmp_ErrCorrCf_vec','descend')
    sortrows(rec_res.table,'rec_funDep_A00_ErrEuclid_vec')
    sortrows(rec_res.table,'rec_funDep_A00_ErrCorrCf_vec','descend')
    sortrows(rec_res.table,'rec_funDep_PDC_ErrEuclid_vec')
    sortrows(rec_res.table,'rec_funDep_PDC_ErrCorrCf_vec','descend')
    rec_opt.ranks

  case {'loc'}

    % Localization
    disp('Localization')
    run('./tg_s07_BATCH___05_Localizers.m'); whos

  otherwise
    warning('Unexpected supSwitch value. No action taken, only data generated.')
end

!opt Checkups

After execution of tg_s07_BATCH___02_Signals.m the generated timeseries can be swapped for simple waveforms (used for to facilitate bug tracking and for explanatory/illustrative purpose).

% (just trying simple signals over here)

tmp_arg = linspace(0,8*pi,SETUP.n00)';
size(tmp_arg)

sim_sig_SrcActiv.sigSRC_pre = repmat(sin(tmp_arg),    [1,sum(SETUP.SRCS(:,1)),SETUP.K00]);
sim_sig_SrcActiv.sigSRC_pst = repmat(sin(tmp_arg),    [1,sum(SETUP.SRCS(:,1)),SETUP.K00]);
sim_sig_IntNoise.sigSRC_pre = repmat(sin(tmp_arg*100),[1,sum(SETUP.SRCS(:,2)),SETUP.K00]);
sim_sig_IntNoise.sigSRC_pst = repmat(sin(tmp_arg*100),[1,sum(SETUP.SRCS(:,2)),SETUP.K00]);
sim_sig_BcgNoise.sigSRC_pre = repmat(sin(tmp_arg*10), [1,sum(SETUP.SRCS(:,3)),SETUP.K00]);
sim_sig_BcgNoise.sigSRC_pst = repmat(sin(tmp_arg*10), [1,sum(SETUP.SRCS(:,3)),SETUP.K00]);

size(sim_sig_SrcActiv.sigSRC_pre)
size(sim_sig_SrcActiv.sigSRC_pst)
size(sim_sig_BcgNoise.sigSRC_pre)
size(sim_sig_BcgNoise.sigSRC_pst)

close all
jj = 1
kk = 1
figure('Name','sim_sig_SrcActiv.sigSRC_pre'); plot(sim_sig_SrcActiv.sigSRC_pre(:,jj,kk))
figure('Name','sim_sig_BcgNoise.sigSRC_pre'); plot(sim_sig_BcgNoise.sigSRC_pre(:,jj,kk))

figure('Name','sim_sig_SrcActiv.sigSNS_pre'); plot(sim_sig_SrcActiv.sigSNS_pre(:,jj,kk))
figure('Name','sim_sig_SrcActiv.sigSNS_pst'); plot(sim_sig_SrcActiv.sigSNS_pst(:,jj,kk))

figure('Name','sim_sig_BcgNoise.sigSRC_pre'); plot(sim_sig_BcgNoise.sigSRC_pre(:,jj,kk))
figure('Name','sim_sig_BcgNoise.sigSRC_pst'); plot(sim_sig_BcgNoise.sigSRC_pst(:,jj,kk))

figure('Name','sim_sig_BcgNoise.sigSNS_pre'); plot(sim_sig_BcgNoise.sigSNS_pre(:,jj,kk))
figure('Name','sim_sig_BcgNoise.sigSNS_pst'); plot(sim_sig_BcgNoise.sigSNS_pst(:,jj,kk))

size(y_Pre)
size(y_Pst)

figure('Name','y_Pre'); plot(y_Pre(:,jj,kk))
figure('Name','y_Pst'); plot(y_Pst(:,jj,kk))
% (just trying simple signals over here)

sim_sig_BcgNoise.sigSRC_pre = randn(size(sim_sig_BcgNoise.sigSRC_pre))
sim_sig_BcgNoise.sigSRC_pst = sim_sig_BcgNoise.sigSRC_pre
% (just trying simple signals over here)

sim_sig_BcgNoise.sigSRC_pst = sim_sig_BcgNoise.sigSRC_pre

[p01] Prelude (with optional settings overwrite)

The following settings will overwritte simulation default settings. The devault settings are optimized for bug tracking and for explanatory/illustrative purpose. Please modify simulation settings only in this section.

   % Tidy up and change working directory.
   clc; close all;clearvars('-except','fPath');
   if exist('fPath'),cd(fPath);else,try,cd('~/cc_overkill/git/supFunSim');catch,cd('~/supFunSim');end;end;
   clear all;
   close all;
   clc;

   run('./tg_s00_Prelude___01_Simulations_main_setup.m')
   run('./tg_s00_Prelude___02_SNR_Adjustments.m')

   % Rows of SETUP.SRCS reppresent ROIs.
   % Cols of SETUP.SRCS represent SrcActiv, IntNoise and BcgNoise, respectively.
   SETUP.rROI   = logical(1);       % random (1) or predefined (0) ROIs
   SETUP.rPNT   = logical(1);       % random (1) or predefined (0) candidate points for source locations: if 0, 
				       % number of sources as in SETUP.SRCS(1,1) will be fixed and in close locations
   SETUP.SRCS   = []; % Cortical sources (avoid placing more than 10 sources in single ROI)
   SETUP.SRCS   = [ SETUP.SRCS;  3  3  0 ];
   SETUP.SRCS   = [ SETUP.SRCS;  3  3  0 ];
   SETUP.SRCS   = [ SETUP.SRCS;  3  3  0 ];
   SETUP.SRCS   = [ SETUP.SRCS;  4  3  0 ];
   SETUP.SRCS   = [ SETUP.SRCS;  0  3  0 ];
   SETUP.SRCS   = [ SETUP.SRCS;  0  3  0 ];
   SETUP.SRCS   = [ SETUP.SRCS;  0  3  0 ];
   SETUP.SRCS   = [ SETUP.SRCS;  0  3  0 ];
   SETUP.SRCS   = [ SETUP.SRCS;  0  3  3 ];
   SETUP.SRCS   = [ SETUP.SRCS;  0  0  4 ];
   SETUP.DEEP   = [              0  0  20 ]; % deep sources

   SETUP.ERPs   = 0;       % Add ERPs (timelocked activity)

   % Basic setting s for sources and noise.
   SETUP.n00    = 500;     % number of time samples per trial
   SETUP.K00    = 1;       % number of independent realizations of signal and noise based on generated MVAR model
			      % note: covariance matrix R of observed signal and noise covariance matrix N are
			      % estimated from samples originating from all realizations of signal and noise
   SETUP.FIXED_SEED = 1; % Settings for seed selection
   if SETUP.FIXED_SEED, SETUP.SEED = rng(1964);else,SETUP.SEED = rng(round(1e3*randn()^2*sum(clock)));end
   SETUP.RANK_EIG = sum(SETUP.SRCS(:,1)); % rank of EIG-LCMV filter: set to number of active sources
   SETUP.fltREMOVE = 1;    % to keep (0) or remove (1) selected filters
   SETUP.SHOWori = 0; % to show (1) or do not show (0) Original and Dummy signals on Figures
   SETUP.IntLfgRANK = round(0.3*sum(SETUP.SRCS(:,2))); % rank of patch-constrained reduced-rank leadfield
   SETUP.supSwitch = 'rec'; % 'rec': run reconstruction of sources activity, 'loc': find active sources

   SETUP.CUBE           = 20;    % perturbation of the leadfields based on the shift of source position within a cube of given edge length (centered at the original leadfields positions), in [mm]
   SETUP.CONE           = pi/32; % perturbation of the leadfields based on the rotation of source orientation (azimuth TH, elevation PHI), in [rad]
   SETUP.H_Src_pert     = 1;     % use original (0) or perturbed (1) leadfield for signal reconstruction
   SETUP.H_Int_pert     = 0;     % use original (0) or perturbed (1) leadfield for nulling constrains
   SETUP.SINR           = 0;     % signal to interference noise power ratio expressed in dB (both measured on electrode level)
   SETUP.SBNR           = 0;    % signal to biological noise power ratio expressed in dB (both measured on electrode level)
   SETUP.SMNR           = 0;    % signal to measurment noise power ratio expressed in dB (both measured on electrode level)
   SETUP.WhtNoiseAddFlg = 1;     % white noise admixture in biological noise interference noise (FLAG)
   SETUP.WhtNoiseAddSNR = 3;     % SNR of BcgNoise and WhiNo (dB)
   SETUP.SigPre = 0;   SETUP.IntPre = 0;   SETUP.BcgPre = 1;   SETUP.MesPre = 1; % final signal components for pre-interval  (use zero or one for signal, interference noise, biological noise, measurement noise)
   SETUP.SigPst = 1;   SETUP.IntPst = 1;   SETUP.BcgPst = 1;   SETUP.MesPst = 1; % final signal components for post-interval (as above)

   % For localization, the default is to consider random locations of ROI with some fixed candidate points such that 
   % SETUP.SRCS(1,1) of them are in close locations; additionally, no interfering sources are considered
   % in the localization model. You may comment out the 'if' section below to experiment with other settings.
   if(SETUP.supSwitch == 'loc') 
	  SETUP.rROI   = logical(1);       % random (1) or predefined (0) ROIs
	  SETUP.rPNT   = logical(0);       % random (1) or predefined (0) candidate points for source locations: if 0, 
					   % number of sources as in SETUP.SRCS(1,1) will be fixed and in close locations
	  SETUP.SigPre = 0;   SETUP.IntPre = 0;   SETUP.BcgPre = 1;   SETUP.MesPre = 1; % final signal components for pre-interval  (use zero or one for signal, interference noise, biological noise, measurement noise)
	  SETUP.SigPst = 1;   SETUP.IntPst = 0;   SETUP.BcgPst = 1;   SETUP.MesPst = 1; % final signal components for post-interval (as above)
   end

   if SETUP.rPNT
	  disp('CC: using random source locations')
   else
	  disp('CC: using predefined source locations')
   end

[p02] Signals

disp('CYBERCRAFT:: Generation of timeseries for bioelectrical activity of interest')
run('./tg_s01_Timeseries___01_SrcActiv.m')

disp('CYBERCRAFT:: Generation of timeseries for bioelectrical interference noise')
run('./tg_s01_Timeseries___02_IntNoise.m')

disp('CYBERCRAFT:: Generation of timeseries for bioelectrical background noise')
run('./tg_s01_Timeseries___03_BcgNoise.m')

disp('CYBERCRAFT:: Measurement noise generation')
run('./tg_s01_Timeseries___04_MesNoise.m')

[p03] Leadfields

run('./tg_s02_Geometry___01_RandSamp.m')
run('./tg_s02_Geometry___02_Indices.m')
run('./tg_s02_Geometry___03_Coordinates.m')
run('./tg_s02_Geometry___04_DeepSrc.m')
run('./tg_s02_Geometry___05_Perturbation.m')
run('./tg_s02_Geometry___06_lfg.m')
run('./tg_s03_Forward_modeling.m')

[p04] Preparations

run('./tg_s04_Preparation___00_SNRs_Adjustment.m')
run('./tg_s04_Preparation___01_Signal_Covariances.m')

[p05] Filters

run('./tg_s05_Spatial_filtering___01_Preparation.m')
run('./tg_s05_Spatial_filtering___02_Definitions.m')
run('./tg_s05_Spatial_filtering___03_Execution.m')
run('./tg_s06_Error_evaluation.m')

[p05] Localizers

run('./tg_s05_Localization___00_Preparations.m')
run('./tg_s05_Localization___01_MAI_and_MPZ_Locallizers.m')

[s08] LOOP

Multiple runs for tangled matlab-scripts.

[p00] RUN All

Execute loop

  • Simulation settings can be modified in:
  • {s00} Prelude
  • Prelude (with optional settings overwrite), above
  • the code block below
   if exist('fPath'), cd(fPath); else, try, cd('~/supFunSim/'); catch, warningMessage = 'Problem encoutered while trying to change working directory to ''~/supFunSim/''.'; end; end; disp(['CYBERCRAFT:: pwd is: ',pwd])

   clearvars ii jj kk nn tmp* LOOP* Loop*;
   run('./tg_s07_BATCH___01_Prelude.m');
   SETUP

   % Get some details for simulation output filename (*.mat file)
   LOOP.DATE = datestr(now,'yyyymmdd_HHMMSS');
   LOOP.NAME = tempname; [~, LOOP.NAME] = fileparts(LOOP.NAME); % simulation unique name

   % Number of simulation runs for each SNRs combination
   LOOP.totSimCount = 1000;
   LOOP.rngSimCount = 1:LOOP.totSimCount;

   % Range of SNRs 
   LOOP.rngMesNoise = 10;
   LOOP.rngBcgNoise = 0;
   LOOP.rngIntNoise = [0:5:10];

   LOOP
   SETUP

   run('./tg_s08_LOOP___01_Main_LOOP.m'); whos

   switch SETUP.supSwitch
     case {'rec'}

	run('./tg_s08_Loop_Reconstruction_Plot___02_.m')

     case {'loc'}

	run('./tg_s08_Loop_Localization_Plot___02_.m')

     otherwise
	warning('Unexpected supSwitch value. No action taken, only data generated.')
   end

Extract and visualize errors

Reconstruction
LOOP
LOOP.table_varN'
LOOP.table_rowN
size(LOOP.table_arrC)

% avg and std arrays #filters x #error_measures x #SXNR_levels 
LOOP.table_arrC_avgSimCount = squeeze(mean(LOOP.table_arrC,3))
LOOP.table_arrC_stdSimCount = squeeze(std(LOOP.table_arrC,[],3))
size(LOOP.table_arrC_avgSimCount)

% SAVE THE RESULTS
mySave = ['./res___',LOOP.DATE,'___',LOOP.NAME,'___',datestr(now,'yyyymmdd_HHMMSS')];
save(mySave)
LOOP

close all
for ii = 1:length(LOOP.table_varN)
    LOOP.table_varN'
    tmp_pickVar = ii;
    disp(LOOP.table_varN(tmp_pickVar))

    TMP_res.table_arrC = squeeze(LOOP.table_arrC_avgSimCount(:,tmp_pickVar,:))
    TMP_res.table_varN = strrep(strrep(strsplit(num2str(LOOP.(LOOP.NamNoise),'%+d ')),'-','n'),'+','p')
    TMP_res.table_rowN = LOOP.table_rowN
    TMP_res.table = array2table(TMP_res.table_arrC,'VariableNames',TMP_res.table_varN,'RowNames',TMP_res.table_rowN);
    sortrows(TMP_res.table,1)

    figure('Name',[LOOP.table_varN{tmp_pickVar},' for ',LOOP.NamNoise,' in ',num2str(LOOP.(LOOP.NamNoise),'%+d ')])
    bar(TMP_res.table_arrC)
    set(gca, 'XTick', 1:length(TMP_res.table_rowN), 'XTickLabel', strrep(TMP_res.table_rowN,'_','\_'));
    h1 = legend(strsplit(num2str(LOOP.(LOOP.NamNoise),'%+d ')))
    myTitle = strrep([LOOP.table_varN{tmp_pickVar},' for ',LOOP.NamNoise,' in ',num2str(LOOP.(LOOP.NamNoise),'%+d ')],'_','\_');
    % title(myTitle)
    myName = ['./fig/',LOOP.DATE,'___',LOOP.NAME,'___fig_',num2str(ii),'___',strrep(strrep(myTitle,'\',''),' ','_')];

    v1 = get(h1,'title')

    % fix me: it does not have to be SINR
    set(v1,'string','SINR')

    set(gcf, 'PaperUnits', 'centimeters')
    set(gcf, 'PaperOrientation', 'portrait')
    set(gcf, 'PaperSize', [20, 20])
    set(gcf, 'Position', [100, 100, 800, 750])
    legend('Location','northeastoutside')
    xtickangle(45)

    savefig(gcf,myName,'compact')
    savefig(gcf,myName)
    saveas(gcf,myName,'pdf')
end
Localization
	LOOP

	% USED FOR SAVING FIGURES
	myName = ['./fig___',LOOP.DATE,'___',LOOP.NAME,'___',datestr(now,'yyyymmdd_HHMMSS')];

	% use LOOP.RES.ITERATION{x}{y}(z) to access results struct for 
	% z-th activity index (z=1,2,...,8 with z=1 for MAI(2011) etc., as defined in !run MAI and MPZ Locallizers) 
	% y-th level of SNR of type considered (interference, biological, measurement)
	% x-th iteration of the experiment

	% XRANK is an array of size |x| by |y|, representing ranks selected for reduced-rank indices
	XRANK=zeros(LOOP.totSimCount,length(LOOP.(LOOP.NamNoise)));

	% number of simulation runs
	for i=1:LOOP.totSimCount
	    % number of levels of SNR
	    for j=1:length(LOOP.(LOOP.NamNoise))
		XRANK(i,j)=max([LOOP.RES.ITERATION{i}{j}(1).sources.rank_opt]);
	    end
	end

	% XRES is an array of size |x| by |y| by |z| by |#sources|, representing errors for each source
	% found using iterative procedure
	XRES=zeros(LOOP.totSimCount,length(LOOP.(LOOP.NamNoise)),8,sum(SETUP.SRCS(:,1)));

	% number of simulation runs
	for i=1:LOOP.totSimCount
	    % number of levels of SNR
	    for j=1:length(LOOP.(LOOP.NamNoise))
		% number of activity indices
		for k=1:8
		    XRES(i,j,k,:)=[LOOP.RES.ITERATION{i}{j}(k).sources.distance]';
		end 
	    end 
	end

	% RRES is same like XRES, with the trailing few sources considered
	RRES=XRES(:,:,:,end-1:end);

	% |x| by |y| by |z| array, with last dimension representing mean of errors across sources discovered
	XRES_s = mean(XRES,4);
	RRES_s = mean(RRES,4);

	% |y| by |z| matrix, with entries representing averaged mean error and its std across experiment repetitions
	XRES_sa = squeeze(mean(XRES_s,1));
	XRES_sstd = squeeze(std(XRES_s,1));
	RRES_sa = squeeze(mean(RRES_s,1));
	RRES_sstd = squeeze(std(RRES_s,1));

	% change order of and remove some activity indices as:
	% 1 = MAI(2011), 2 = MAI(2013), 3 = MAI_RR_I
	% 4 = MPZ(2011), 5 = MPZ(2013), 6 = MPZ_RR_I
	XRES_s = XRES_s(:,:,[1 2 5 3 4 7]);
	RRES_s = RRES_s(:,:,[1 2 5 3 4 7]);

	XRES_sa = XRES_sa(:,[1 2 5 3 4 7]);
	XRES_sstd = XRES_sstd(:,[1 2 5 3 4 7]);

	RRES_sa = RRES_sa(:,[1 2 5 3 4 7]);
	RRES_sstd = RRES_sstd(:,[1 2 5 3 4 7]);

	% Mann-Whitney U-test to check whether proposed activity indices achieve 
	% significantly lower average localization error

	% XRES_U and RRES_U are |y| by 4 (# of comparisons) storing resulting p-values of performed Mann-Whitney U test
	XRES_U=zeros(length(LOOP.(LOOP.NamNoise)),4);
	RRES_U=zeros(length(LOOP.(LOOP.NamNoise)),4);

	for j=1:length(LOOP.(LOOP.NamNoise))
	    XRES_U(j,1)=ranksum(XRES_s(:,j,1),XRES_s(:,j,3),'tail','right');
	    XRES_U(j,2)=ranksum(XRES_s(:,j,2),XRES_s(:,j,3),'tail','right');
	    XRES_U(j,3)=ranksum(XRES_s(:,j,4),XRES_s(:,j,6),'tail','right');
	    XRES_U(j,4)=ranksum(XRES_s(:,j,5),XRES_s(:,j,6),'tail','right');
	end

	for j=1:length(LOOP.(LOOP.NamNoise))
	    RRES_U(j,1)=ranksum(RRES_s(:,j,1),RRES_s(:,j,3),'tail','right');
	    RRES_U(j,2)=ranksum(RRES_s(:,j,2),RRES_s(:,j,3),'tail','right');
	    RRES_U(j,3)=ranksum(RRES_s(:,j,4),RRES_s(:,j,6),'tail','right');
	    RRES_U(j,4)=ranksum(RRES_s(:,j,5),RRES_s(:,j,6),'tail','right');
	end

	% pad with zero vectors to increase spacing between bar groups
	XRES_sa = [XRES_sa; zeros(2,6)];
	XRES_sstd = [XRES_sstd; zeros(2,6)];

	RRES_sa = [RRES_sa; zeros(2,6)];
	RRES_sstd = [RRES_sstd; zeros(2,6)];

	clear gca;      
	figure
	name = {'MAI';'MAI_{ext}';'MAI_{RR-I}';'MPZ';'MPZ_{ext}';'MPZ_{RR-I}'};
	bar(XRES_sa',1.2);
	hold on
	bar(XRES_sstd',1.2,'FaceColor',[0 0 0])
	hold off
	f=get(gca,'Children');
	f=flipud(f(3:end));
	lgd=strsplit(num2str(LOOP.(LOOP.NamNoise),'%d '));
	% need to skip items in legend
	for i=1:length(lgd)
	    legendInfo{i} = ['SNR = ', lgd{i}, ' dB']; 
	end
	l=legend(f,legendInfo);	
	l.Location='northwest';
	set(gca,'XTickLabel',name);
	ylabel('Average localization error [mm]')
	% ax = findobj(gcf,'type','axes'); 
	print(gcf,[fullfile(pwd,filesep), strcat(myName,'_XRES_')],'-depsc')

	figure
	bar(RRES_sa',1.2);
	hold on
	bar(RRES_sstd',1.2,'FaceColor',[0 0 0])
	hold off
	f=get(gca,'Children');
	f=flipud(f(3:end));
	l=legend(f,legendInfo);
	l.Location='northwest';
	set(gca,'XTickLabel',name);
	ylabel('Average localization error [mm]')
	print(gcf,[fullfile(pwd,filesep), strcat(myName,'_RRES_')],'-depsc')

	clear gca;
	figure
	plot(XRANK,'-o','MarkerIndices',1:LOOP.totSimCount,'LineWidth',2);
	f=get(gca,'Children');
	f=flipud(f);
	l=legend(f,legendInfo);
	l.Location='northwest';
	axis([1 LOOP.totSimCount 1 sum(SETUP.SRCS(:,1))])
	xlabel('Simulation run')
	xticks([1:LOOP.totSimCount])
	ylabel('Rank selected')
	yticks([1:sum(SETUP.SRCS(:,1))])
	print(gcf,[fullfile(pwd,filesep), strcat(myName,'_XRANK_')],'-depsc')

[p01] Main LOOP

     [LOOP.c01RR,LOOP.c02MM,LOOP.c03BB,LOOP.c04II] = ndgrid(LOOP.rngSimCount,LOOP.rngMesNoise,LOOP.rngBcgNoise,LOOP.rngIntNoise);
     LOOP.coords = [LOOP.c01RR(:),LOOP.c02MM(:),LOOP.c03BB(:),LOOP.c04II(:)];

     2 == length(size(squeeze(double.empty([[length(LOOP.rngMesNoise),length(LOOP.rngBcgNoise),length(LOOP.rngIntNoise)],0]))))
     if 2 == length(size(squeeze(double.empty([[length(LOOP.rngMesNoise),length(LOOP.rngBcgNoise),length(LOOP.rngIntNoise)],0]))))
	  if max([length(LOOP.rngMesNoise),length(LOOP.rngBcgNoise),length(LOOP.rngIntNoise)]) == min([length(LOOP.rngMesNoise),length(LOOP.rngBcgNoise),length(LOOP.rngIntNoise)]),
	      LOOP.IdxNoise = 0;
	  else,
	      [~,LOOP.IdxNoise] = max([length(LOOP.rngMesNoise),length(LOOP.rngBcgNoise),length(LOOP.rngIntNoise)]);
	  end;
	  if LOOP.IdxNoise == 1,
	      LOOP.NamNoise = 'rngMesNoise';
	  elseif LOOP.IdxNoise == 2,
	      LOOP.NamNoise = 'rngBcgNoise';
	  elseif LOOP.IdxNoise == 3,
	      LOOP.NamNoise = 'rngIntNoise';
	  else,
	      LOOP.NamNoise = 'AnyNoise';
	  end;
     else,
	  error('CYBERCRAFT:: ensure that only one noise type is vector and the remaining are scalars');
     end;
     LOOP.progress = []; LOOP.table_arrC = []; LOOP.table_varN = {}; LOOP.table_rowN = {};

     for LoopSimCount = 1:LOOP.totSimCount
	  LoopIterCount = [];      
	  run('./tg_s07_BATCH___02_Signals.m');
	  run('./tg_s07_BATCH___03_Leadfields.m');
	  for LoopIntNoise = 1:length(LOOP.rngIntNoise)
	      for LoopBcgNoise = 1:length(LOOP.rngBcgNoise)
		  for LoopMesNoise = 1:length(LOOP.rngMesNoise)

		      % used by localization
		      LoopIterCount = [LoopIterCount;LoopMesNoise,LoopBcgNoise,LoopIntNoise];
		      % used by reconstruction 
		      LOOP.progress   = [LOOP.progress;LoopSimCount,LOOP.rngMesNoise(LoopMesNoise),LOOP.rngBcgNoise(LoopBcgNoise),LOOP.rngIntNoise(LoopIntNoise)];
		      fprintf('\n');
		      disp('============================')
		      disp(['CurrIter: ',num2str(size(LOOP.progress,1)),' of ',num2str(length(LOOP.coords))])
		      disp('----------------------------')
		      disp(['SimCount: ',num2str(LoopSimCount),' of ',num2str(LOOP.totSimCount)])
		      disp(['MesNoise: ',num2str(LoopMesNoise),' of ',num2str(length(LOOP.rngMesNoise)),' (',num2str(LOOP.rngMesNoise(LoopMesNoise)),' dB in ' ,'[ ',num2str(LOOP.rngMesNoise),' ])'])
		      disp(['BcgNoise: ',num2str(LoopBcgNoise),' of ',num2str(length(LOOP.rngBcgNoise)),' (',num2str(LOOP.rngBcgNoise(LoopBcgNoise)),' dB in ' ,'[ ',num2str(LOOP.rngBcgNoise),' ])'])
		      disp(['IntNoise: ',num2str(LoopIntNoise),' of ',num2str(length(LOOP.rngIntNoise)),' (',num2str(LOOP.rngIntNoise(LoopIntNoise)),' dB in ' ,'[ ',num2str(LOOP.rngIntNoise),' ])'])
		      disp('----------------------------')
		      disp(['SETUP.n00: ',num2str(SETUP.n00)])
		      disp(['SETUP.K00: ',num2str(SETUP.K00)])
		      % chkSim___tg_s01_PRE___001(SETUP)
		      disp('============================')
		      SETUP.SINR    = LOOP.rngIntNoise(LoopIntNoise);
		      SETUP.SBNR    = LOOP.rngBcgNoise(LoopBcgNoise);
		      SETUP.SMNR    = LOOP.rngMesNoise(LoopMesNoise);

		      run('./tg_s07_BATCH___04_Preparations.m');

		      switch SETUP.supSwitch
			case {'rec'}

			  % Reconstruction
			  disp('Reconstruction')

			  run('./tg_s07_BATCH___05_Filters.m');

			  % removes Original and Dummy signals from Figures
			  if(SETUP.SHOWori==0)
			      rec_res.table_rowN = rec_res.table_rowN(3:end);
			      rec_res.table_arrC = rec_res.table_arrC(3:end,:);
			  end

			  LOOP.table_rowN{size(LOOP.progress,1)} = rec_res.table_rowN;
			  LOOP.table_varN{size(LOOP.progress,1)} = rec_res.table_varN;
			  LOOP.table_arrC(:,:,LoopSimCount,LoopMesNoise,LoopBcgNoise,LoopIntNoise) = rec_res.table_arrC;

			case {'loc'}

			  % Localization
			  disp('Localization')

			  run('tg_s07_BATCH___05_Localizers.m');

			  % use LOOP.RES.ITERATION{x}{y}(z) to access results struct for 
			  % z-th activity index (z=1,2,...,8 with z=1 for MAI(2011) etc., as defined in !run MAI and MPZ Locallizers) 
			  % y-th level of SNR of type considered (interference, biological, measurement)
			  % x-th iteration of the experiment
			  LOOP.RES.ITERATION{LoopSimCount}{size(LoopIterCount,1)} = RES;

			  % temporary helper code
			  % save(['RES__','ITERATION_',num2str(LoopSimCount),'__SINR_',num2str(SETUP.SINR),'__SBNR_',num2str(SETUP.SBNR),'__SMNR_',num2str(SETUP.SMNR)],'RES')

			otherwise
			  warning('Unexpected supSwitch value. No action taken, only data generated.')
		      end
		  end
	      end
	  end
     end

     switch SETUP.supSwitch
	case {'rec'}

	  if isequal(LOOP.table_rowN{:}), LOOP.table_rowN = LOOP.table_rowN{1}; else, error('CYBERCRAFT:: row names are inconsistent'); end;
	  if isequal(LOOP.table_varN{:}), LOOP.table_varN = LOOP.table_varN{1}; else, error('CYBERCRAFT:: var names are inconsistent'); end;

	case {'loc'}

	otherwise
	  warning('Unexpected supSwitch value. No action taken, only data generated.')
     end

Supplementaries

DOIN [z00] Auxiliary functions

rawTimeSeries3d2d

function y = rawTimeSeries3d2d(x)

% y = rawTimeSeries3d2d(x)
% NB.: this function asumes that trials are along third dimention.

    y = reshape(permute(x,[1,3,2]),[],size(x,2),1);

end

rawRad2Deg

Convert angles from radians to degrees.

function angDeg = rawRad2Deg(angRad)
% Convert angs from radians to degrees
angDeg = (180/pi) * angRad;

rawIsStableMVAR

Check whether the MVAR model is stable.

function [H,varargout] = rawIsStableMVAR(A00,varargin)
    if isempty(varargin)
        STAB = 1;
        disp(['Checking if eigenvalues are inside unit circle.']);
    elseif length(varargin) == 1
        STAB = varargin{1};
        disp(['Checking if eigenvalues are inside circle with radius of ',num2str(STAB) ,'.']);
    else
        error('Too many input arguments');
    end
    S00          = size(A00,1);                  % dimension of state vectors
    P00          = size(A00,2)/S00;                % order of process
    tmp_lambda   = eig([A00; eye((P00-1)*S00) zeros((P00-1)*S00,S00)]);
    H            = ~any(abs(tmp_lambda)>STAB);
    varargout{1} = max(abs(tmp_lambda));
end

rawSize

Get size of an array (plain).

function [s] = rawSize(x,varargin)
    if isempty(varargin)
        s = size(x);
    else
       s = [];
       for ii = 1:length(varargin{1})
           s = [s,size(x,ii)];
       end
    end
end

rawImgSC

Pretty table made from 2d array.

function [h1,h2] = rawImgSC(mat,varargin)
    h1 = imagesc(mat);
    [x,y] = ndgrid(1:size(mat,2),1:size(mat,1));
    mat = mat';
    if ~isempty(varargin)
        fSize = varargin{1};
    else
       fSize = 18;
    end
    h2 = text(x(:),y(:),strtrim(cellstr(num2str(mat(:),'%.2f'))),'HorizontalAlignment','center','FontSize',fSize);
    if 0
        mat = [reshape(-12:12,5,5);reshape(-12:12,5,5);reshape(-12:12,5,5)]
        figure(17);clf;rawImgSC(mat);colorbar;
    end
end

rawHotColdColorMap

Pretty color-map for MATLAB figures.

function [y] = rawHotColdColorMap(x)
% [y] = rawHotColdColorMap(x)
% Suggested rationalization: base/2
    if 0
        x = 255
        y = rawHotColdColorMap(x)
    end
    y = [linspace(0,1,x)',linspace(0,1,x)',linspace(1,1,x)'];
    y = [y;fliplr(flipud(y))];
    % imagesc(permute(y,[1,3,2]))
end

rawPlotPDC

Plot PDC values.

function rawPlotPDC(pdcData,accf)
    tmp_row  = size(pdcData,1);
    tmp_col  = size(pdcData,2);
    tmp_cnt  = 0;
    for i = 1:tmp_row
        for j = 1:tmp_col
            tmp_cnt = tmp_cnt+1;
            subplot(tmp_row,tmp_col,tmp_cnt)
            area(accf,squeeze(pdcData(i,j,:)))
            axis tight
            ylim([0,1])
        end
    end
end

rawAdjTotSNRdB

Adjust the SNR by changing the amplitude of the noise time-series.

function [y] = rawAdjTotSNRdB(x01,x02,newSNR)
    y = ((x02 / rawNrm(x02)) * rawNrm(x01)) / (db2pow(0.5*newSNR));
end

rawNrm

Compute norm of the random vector.

function [y] = rawNrm(x)
 % Compute norm of the random vector
     y = sqrt(sum(rawMom(x,2),2));
 end

rawMom

Compute raw moment of the k-th order for the random vector.

function [M] = rawMom(x01,k)
% Compute raw moment of the k-th order for the random vector
    M = mean(x01.^k, 1);
end

rawSNRdB

Compute raw moment of the k-th order for the random vector.

function [y] = rawSNRdB(x1,x2)
% Compute SNR in dB for two random vectors (signal and noise)
    y = 20.*log10(norm(x1,'fro')./norm(x2,'fro'));
end

ccrender

Prettify 3d MATLAB figures.

function [] = ccrender(varargin)

%%
% CCRENDER --- figure rendering settings, usage:
%
% ccrender( axisLimits, finish, origin, originLimits )
%
%  - axisLimits [optional]:
%      limits display to specified range defined using either:
%        - vector of length 2 (all axes have same limits)
%          [ xyzLim_1, xyzLim_2 ],
%        - vector of length 6 (each axis has its own limits)
%          [ xLim_1, xLim_2, yLim_1, yLim_2, zLim_1, zLim_2 ];
%  - finish [optional]:
%      changes rendering scheme;
%  - origin [optional]:
%      true/false;
%  - originLim [optional]:
%      a number.
%
% Questions and comments: [email protected]
%
% TODO:
% - add "try" envelopes for major blocks
%
%

%%

p = inputParser;

defAxisLimits = [];
%   chkAxisLimits = @(x) validateattributes(x,{'numeric'},{'vector','numel',2});
chkAxisLimits = @(x) isnumeric(x) && isvector(x) && ( length(x) == 2 || length(x) == 6 );
addOptional(p,'axisLimits',defAxisLimits,chkAxisLimits)

defOriginLimits = [];
chkOriginLimits = @(x) isnumeric(x) && isvector(x) && ( length(x) == 2 || length(x) == 6 );
addOptional(p,'originLimits',defOriginLimits,chkOriginLimits)

defEqualize = false;
chkEqualize = @(x) validateattributes(x,{'logical'},{});
addParameter(p,'equalize',defEqualize,chkEqualize)

defOrigin = true;
chkOrigin = @(x) validateattributes(x,{'logical'},{});
addParameter(p,'origin',defOrigin,chkOrigin)

defLabels = true;
chkLabels = @(x) validateattributes(x,{'logical'},{});
addParameter(p,'labels',defLabels,chkLabels)

defFinish = 'matte';
vldFinish = {'glossy','matte'};
chkFinish = @(x) any(validatestring(x,vldFinish));
addParameter(p,'finish',defFinish,chkFinish)




s = dbstack;


p.KeepUnmatched = true;


parse(p,varargin{:})

tmp_gcf = gcf

ccdisp('INIT: ccrender')
ccdisp(['Updating figure: ',num2str(tmp_gcf.Number),'...'])




if ~isempty(p.UsingDefaults)
    ccdisp([ s(1).name,': Using defaults:'])
    disp(p.UsingDefaults')
end
if ~isempty(p.Results)
    ccdisp([ s(1).name,': Results:'])
    disp(p.Results')
end
if ~isempty(fieldnames(p.Unmatched))
    ccdisp([ s(1).name,': Extra (unmatched) inputs:'])
    disp(p.Unmatched')
end





%%

if length(p.Results.axisLimits) == 2
    if p.Results.axisLimits(1) >= p.Results.axisLimits(2)
        help ccrender;
        error('CYBERCRAFT: axis limits [xyzLim_1,xyzLim_2] must be increasing.');
    else
        axis([ p.Results.axisLimits(1) p.Results.axisLimits(2) p.Results.axisLimits(1) p.Results.axisLimits(2) p.Results.axisLimits(1) p.Results.axisLimits(2) ]);
    end
elseif length(p.Results.axisLimits) == 6
    if p.Results.axisLimits(1) >= p.Results.axisLimits(2)  ||  p.Results.axisLimits(3) >= p.Results.axisLimits(4)  ||  p.Results.axisLimits(5) >= p.Results.axisLimits(6)
        help ccrender;
        error('CYBERCRAFT: axis limits [xLim_1,xLim_2,yLim_1,yLim_2,zLim_1,zLim_2] must be increasing for each axis.');
    else
        axis([ p.Results.axisLimits(1) p.Results.axisLimits(2) p.Results.axisLimits(3) p.Results.axisLimits(4) p.Results.axisLimits(5) p.Results.axisLimits(6) ]);
    end
end
%{
xlim([-15,15])
ylim([-15,15])
zlim([-15,15])
axis square
axis equal
axis auto
%}

if p.Results.equalize == true
    xMin = min(xlim);
    xMax = max(xlim);
    yMin = min(ylim);
    yMax = max(ylim);
    zMin = min(zlim);
    zMax = max(zlim);
    xyzMin = min( [ xMin yMin zMin ] );
    xyzMax = max( [ xMax yMax zMax ] );
    axis([ xyzMin xyzMax xyzMin xyzMax xyzMin xyzMax ]);
end


if p.Results.labels == true
    xlabel('X-axis')
    ylabel('Y-axis')
    zlabel('Z-axis')
end

set(gca,'DataAspectRatio',   [1 1 1])
set(gca,'PlotBoxAspectRatio',[1 1 1])

camproj('perspective'); % perspective | ortographic

%{
set(gca,'Projection','ortographic') % problem here?
                                    %}

set(gca,'CameraViewAngle',10)

az = 60;
el = 30;
view(az, el);

if strcmp(p.Results.finish,'glossy')
    lighting gouraud;
    material shiny;
    camlight;
    %{
    shading interp;
    light;
    lighting phong;
    %}
end

axis on;
box on;

%%
if p.Results.origin
    if length(p.Results.originLimits) == 2
        if p.Results.originLimits(1) > 0
            help ccrender;
            error('CYBERCRAFT: origin axis low limit must be negative number.')
        elseif p.Results.originLimits(2) < 0
            help ccrender;
            error('CYBERCRAFT: origin axis higher limit must be positive number.')
        else
            xMin = p.Results.originLimits(1);
            xMax = p.Results.originLimits(2);
            yMin = p.Results.originLimits(1);
            yMax = p.Results.originLimits(2);
            zMin = p.Results.originLimits(1);
            zMax = p.Results.originLimits(2);
        end
    elseif length(p.Results.originLimits) == 6
        if p.Results.originLimits(1) > 0  ||  p.Results.originLimits(3) > 0  || p.Results.originLimits(5) > 0
            help ccrender;
            error('CYBERCRAFT: origin axis low limit must be negative number.')
        elseif p.Results.originLimits(2) < 0  ||  p.Results.originLimits(4) < 0  ||  p.Results.originLimits(6) < 0
            help ccrender;
            error('CYBERCRAFT: origin axis higher limit must be positive number.')
        else
            xMin = p.Results.originLimits(1);
            xMax = p.Results.originLimits(2);
            yMin = p.Results.originLimits(3);
            yMax = p.Results.originLimits(4);
            zMin = p.Results.originLimits(5);
            zMax = p.Results.originLimits(6);
        end
    else
        xMin = min(xlim);
        xMax = max(xlim);
        yMin = min(ylim);
        yMax = max(ylim);
        zMin = min(zlim);
        zMax = max(zlim);
    end


    hold on




    try
        ccfgFigH = evalin( 'base', 'ccfgFigH' );
    catch
        ccfgFigH = [];
    end



    try
        tmp_fields = fieldnames(ccfgFigH(tmp_gcf.Number).origin);
        for ii = 1:length(tmp_fields)
            try
                delete(ccfgFigH(tmp_gcf.Number).origin.(tmp_fields{ii}));
            catch tmp_catched_2
                fprintf('\n\nPSEUDO-WARNING[2]: %s\n\n',tmp_catched_2.message);
            end
        end
    catch tmp_catched_1
        fprintf('\n\nPSEUDO-WARNING [1]: %s\n\n',tmp_catched_1.message);
    end


    ccfgFigH(tmp_gcf.Number).origin.xp = quiver3( 0, 0, 0, 1.1*xMax, 0,    0,    'color', [1 0 0], 'LineWidth', 1.0, 'LineStyle', '-' ); hold on;
    ccfgFigH(tmp_gcf.Number).origin.yp = quiver3( 0, 0, 0, 0,    1.1*yMax, 0,    'color', [0 1 0], 'LineWidth', 1.0, 'LineStyle', '-' ); hold on;
    ccfgFigH(tmp_gcf.Number).origin.zp = quiver3( 0, 0, 0, 0,    0,    1.1*zMax, 'color', [0 0 1], 'LineWidth', 1.0, 'LineStyle', '-' ); hold on;

    ccfgFigH(tmp_gcf.Number).origin.xn = quiver3( 0, 0, 0, xMin, 0,    0,    'color', [1 0 0], 'LineWidth', 1.0, 'LineStyle', '-.', 'ShowArrowHead', 'off' ); hold on;
    ccfgFigH(tmp_gcf.Number).origin.yn = quiver3( 0, 0, 0, 0,    yMin, 0,    'color', [0 1 0], 'LineWidth', 1.0, 'LineStyle', '-.', 'ShowArrowHead', 'off' ); hold on;
    ccfgFigH(tmp_gcf.Number).origin.zn = quiver3( 0, 0, 0, 0,    0,    zMin, 'color', [0 0 1], 'LineWidth', 1.0, 'LineStyle', '-.', 'ShowArrowHead', 'off' ); hold on;

    ccfgFigH(tmp_gcf.Number).origin.xt = text(   1.2*xMax, 0,        0,        'OX', 'color', [1 0 0] );
    ccfgFigH(tmp_gcf.Number).origin.yt = text(   0,        1.2*yMax, 0,        'OY', 'color', [0 1 0] );
    ccfgFigH(tmp_gcf.Number).origin.zt = text(   0,        0,        1.2*zMax, 'OZ', 'color', [0 0 1] );

    assignin( 'base', 'ccfgFigH', ccfgFigH );

end


%%


xLimits = xlim;
yLimits = ylim;
zLimits = zlim;




ccdisp( [ 'xLimits: [', num2str(xLimits(1)), ', ', num2str(xLimits(2)), ']' ] )
ccdisp( [ 'yLimits: [', num2str(yLimits(1)), ', ', num2str(yLimits(2)), ']' ] )
ccdisp( [ 'zLimits: [', num2str(zLimits(1)), ', ', num2str(zLimits(2)), ']' ] )

grid on;
rotate3d on;
hold on;



ccdisp(['Figure: ',num2str(tmp_gcf.Number),' has been updated!'])


ccdisp('DONE: ccrender')

return

ccdisp

Just throw some text to MATLAB console.

function [ ] = ccdisp( str )

% CCDISP display as CYBERCRAFT
%
% Use
%
%   ccdisp( str )
%

% add here "try + catch" OR "ifexists"

disp( ['CYBERCRAFT: ', str ] );

return

rawCartToSph

Convert cartesian to spherical coordinates (row-wise).

function [y] = rawCartToSph(x)
% Convert cartesian to spherical coordinates (row-wise)
    if ~isempty(x)
        for ii = 1:size(x,1)
            [y(ii,1),y(ii,2),y(ii,3)] = cart2sph(x(ii,1),x(ii,2),x(ii,3));
        end
    else
        y = x;
    end
end

rawSphToCart

Convert spherical to cartesian coordinates (row-wise).

function [y] = rawSphToCart(x)
% Convert spherical to cartesian coordinates (row-wise)
    if ~isempty(x)
        for ii = 1:size(x,1)
            [y(ii,1),y(ii,2),y(ii,3)] = sph2cart(x(ii,1),x(ii,2),x(ii,3));
        end
    else
        y=x;
    end
end

rawFixStrJoin

Some EEGLab plugins (e.g., cleanline) contain function strjoin which overwrites the original MATLAB function. The following function overshadows the any external strjoin functions with the original one.

function [] = rawFixStrJoin()
    disp('=== Before ===')
    which('strjoin','-all')
    addpath([matlabroot,'/toolbox/matlab/strfun/'])
    disp('=== After ===')
    which('strjoin','-all')
end

DOIN [z01] Handy scripts

rm ./tg_*
rm ./fun/*

OPEN [z02] Remarks and observations

OPEN General

  • Principal sub-matrices in MVAR model are reconstructed quite robustly from IntNoise signal (that may have lowered dimensionality) when compared with SigIn
  • The above also aplies to PDC

[z91] GNU Emacs specific settings

(setq org-image-actual-width '(800))

(setq org-todo-keywords '(
                           (sequence "TODO(t)" "|" "DONE(d)" "SRTD" "NRML")
                           (sequence "NEW!" "FIX!" "WTF!" "DUE!" "CHCK" "REDO" "TOSS" "TEST" "OPEN" "DOIN"  "|" "CNCL" "NVRM")
                           (sequence "SOON" "LATE" "NEXT" "|" "OPTN" "WAIT" "HOLD")
                           (sequence "!run" "!std" "!opt" "!fun" "!fig" "|")
                           (sequence "CYCL" "|")
                           ))

Things to be done shortly

Major

check if clear all is not disturbing batch-run /// loop-run !!!

add evoked time-locked response

As per:

  • cite:g2010—Hui-et-al—Identifying-true-cortical-interactions-in-MEG-using-the-nulling-beamformer

SETTINGS parser

Include SETUP.ERPs in BATCH and LOOP

Fix SETUP.ERPs generation (match array sizes)

Minor

ERPs figure

Simulations work flow diagram

/--------------------------\       /--------------------------\
| sel_atl.mat              |       | ROIs                     |
|--------------------------|       |--------------------------|
| sel_ele.mat              *       |                          *
|--------------------------|       |--------------------------|
| sel_ele.mat              |       |                          |
|--------------------------|       |--------------------------|
| sel_geo_deep_thalami.mat |       |                          |
|--------------------------|       |--------------------------|
| sel_mri00.mat            |       |                          |
|--------------------------|       |--------------------------|
| sel_msh.mat              |       |                          |
|--------------------------|       |--------------------------|
| sel_vol.mat              |       |                          |
\--------------------------/       \--------------------------/






/----------------------------\
|                            |
| Brain triangulation        |
|                            |
+----------------------------+                   /----------------------------\
|                            |                   |                            |
| Skull triangulation        *------------------>* Volume conduction model    |
|                            |                   |                            |
+----------------------------+                   +----------*-----------------+
|                            |                              |
| Scalp Triangulation        |                              |
|                            |                              |
\----------------------------/                              |
                                                            |
/----------------------------------------\                  |
|                                        |                  |
| Cortex parcellation                    |                  |
|                                        |                  |
\----------------*-----------------------/                  |
                 |                                          |
                 |                                          |
                 V                                          V
/----------------------------------------\       /----------*--------------------\
|                                        |       |                               |
| ROIs random sampling                   *------>*  Leadfield computation        |
|                                        |       |                               |
\-----------*----------------------------/       \-------------------------------/
            |                                               |
            |   /------------------------\                  |
            |   |                        |                  |
            +-->*   Volume cond. model   |                  |
                |                        |                  V
                +------------------------+       /----------*--------------------\
                |                        |       |                               |
                | Grid (ROI based)       *<------* Volume lookup (ROI)           |
                |                        |       |                               |
                +------------------------+       \-------------------------------/
                |                        |
                | Leadfields             |
                |                        |
                \------------------------/