Skip to content

Commit

Permalink
consistent use of spaces as whitespace, not tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
robertoostenveld committed Aug 16, 2024
1 parent 93b921b commit 19d0a32
Show file tree
Hide file tree
Showing 12 changed files with 180 additions and 184 deletions.
2 changes: 1 addition & 1 deletion development/guideline/code.md
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ Here is a list of MATLAB release dates; a complete list can be found on [Wikiped

| version number | release name | release date |
| -------------- | ------------ | ------------ |
| MATLAB 9.9 | R2020b | 17 Sep 2020 |
| MATLAB 9.9 | R2020b | 17 Sep 2020 |
| MATLAB 9.8 | R2020a | 19 Mar 2020 |
| MATLAB 9.6 | R2019a | 20 Mar 2019 |
| MATLAB 9.5 | R2018b | 12 Sep 2018 |
Expand Down
2 changes: 1 addition & 1 deletion example/bids_pom.md
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ func/sub-POM1FM0023671_task-rest_acq-MB8_run-1_bold.nii.gz 1900-01-01T18:57:57
From the corresponding EMG `_events.tsv` we can get
```bash
14.5752 0.0002 72877 Response R 1
14.5752 0.0002 72877 Response R 1
```
which indicates that the first scan (coded in the EMG recording as response event "R 1") starts 14.5752 seconds _after_ the start of EMG acquisition. The EMG can therefore be aligned with the wall-time clock by means of the MRI triggers
Expand Down
2 changes: 1 addition & 1 deletion example/coherence_snr.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Specify the parameters of the two datasets.
ntrials1 = 100;
ntrials2 = 100;
ntrials = ntrials1 + ntrials2;
% introduce a random phase difference between the two channels on each trial
phaseFz = 2*pi * (zeros(1,ntrials) );
phasePz = 2*pi * (zeros(1,ntrials) + 0.1*rand(1,ntrials));
Expand Down
73 changes: 36 additions & 37 deletions example/entropy_analysis.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ Notably, mMSE is able to reveal brain-behavior links in EEG data that go undetec
## Download and install the mMSE toolbox

To run entropy analysis on your data, download the mMSE toolbox for FieldTrip from our GitHub page as follows:
git clone https://github.com/LNDG/mMSE.git

git clone https://github.com/LNDG/mMSE.git

or use the Download button on the GitHub page. The mMSE toolbox folder can be placed anywhere – it is not necessary to have it in your FieldTrip folder. However, the folder needs to be added to the path so MATLAB can find it. Furthermore, availability of the FieldTrip toolbox is required as the mMSE code relies on various FieldTrip helper functions. You can do this as follows:

addpath /path/to/your/mMSEfolder
addpath /path/to/your/mMSEfolder

After this step, you can call **[ft_entropyanalysis](https://github.com/LNDG/mMSE/blob/release/ft_entropyanalysis.m)** as any other FieldTrip function.

Expand All @@ -33,17 +33,17 @@ A final point pertains to the boundaries that are set around each data point to

To run mMSE analysis on your preprocessed data, first define the configuration:

cfg = [];
cfg.m = 2; % pattern length
cfg.r = 0.5; % similarity parameter
cfg.timwin = 0.5; % sliding window size
cfg.toi = -0.5:0.05:1; % set this according to your trial length
cfg.timescales = 1:42; % timescale list
cfg.recompute_r = 'perscale_toi_sp'; % when to recompute similarity parameter
cfg.coarsegrainmethod = 'filtskip'; % pointavg or filtskip
cfg.filtmethod = 'lp'; % chooise low pass filter for pointskip
cfg.mem_available = 16e9; % memory available, in bytes
cfg.allowgpu = true; % allow GPU computations, if available
cfg = [];
cfg.m = 2; % pattern length
cfg.r = 0.5; % similarity parameter
cfg.timwin = 0.5; % sliding window size
cfg.toi = -0.5:0.05:1; % set this according to your trial length
cfg.timescales = 1:42; % timescale list
cfg.recompute_r = 'perscale_toi_sp'; % when to recompute similarity parameter
cfg.coarsegrainmethod = 'filtskip'; % pointavg or filtskip
cfg.filtmethod = 'lp'; % chooise low pass filter for pointskip
cfg.mem_available = 16e9; % memory available, in bytes
cfg.allowgpu = true; % allow GPU computations, if available

These settings define the following parameters in the computation:
- `cfg.m` is the length of the data pattern that are being counted, consisting of `m` and `m+1` patterns. `cfg.m = 2` means that 2-element patterns are counted and compared with the number of 3-element patterns.
Expand All @@ -59,20 +59,20 @@ These settings define the following parameters in the computation:

After defining the cfg structure, entropy analysis is then simply run as follows:

[mmse] = ft_entropyanalysis(cfg, data);
[mmse] = ft_entropyanalysis(cfg, data);

The `mmse` output struct has the following fields:

`mmse` =

dimord: 'chan_timescales_time' defines how the numeric data should be interpreted
sampen: [48x42x26 double] sample entropy
label: {48x1 cell} the channel labels
timescales: [1x42 double] the timescales, expressed in ms
fsample: [1x42 double] data sampling rate at each coarse graining step (timescale)
time: [1x26 double] the time, expressed in seconds
r: [48x42x26 double] the boundary similarity parameter computed for each bin
cfg: [1x1 struct] the configuration used by the function that generated this data structure
dimord: 'chan_timescales_time' defines how the numeric data should be interpreted
sampen: [48x42x26 double] sample entropy
label: {48x1 cell} the channel labels
timescales: [1x42 double] the timescales, expressed in ms
fsample: [1x42 double] data sampling rate at each coarse graining step (timescale)
time: [1x26 double] the time, expressed in seconds
r: [48x42x26 double] the boundary similarity parameter computed for each bin
cfg: [1x1 struct] the configuration used by the function that generated this data structure

The `mmse` struct is structurally comparable to a `freq` structure as obtained from **[ft_freqanalysis](/reference/ft_freqanalysis)**, with the following exceptions: `timescales` replaces the `frequency` field, indicating the timescales axis; `sampen` replaces the `powspctrm` field, containing the resulting sample entropy values; `fsample` indicates the sampling rate of the data at each coarsegraining step; `r` contains the r values computed at each channel-by-timescales-by-time location.

Expand All @@ -82,20 +82,19 @@ If, after computing mMSE, you would like to use the FieldTrip functions for plot

Finally, it is also possible to run standard MSE analysis with our function. Standard MSE is computed across the complete timeseries at once so it has no time dimension. Furthermore, data is coarsened by averaging adjacent samples (point averaging). Finally, the r parameter is computed only once, instead of recomputed for each timescale. Please see the original MSE paper for details (**[Costa et al. 2002](https://doi.org/10.1103/PhysRevLett.89.068102.m)**).

To run standard MSE analysis, define your cfg as follows:

cfg = [];
cfg.m = 2; % pattern length
cfg.r = 0.5; % similarity parameter
cfg.timwin = data.time{1}(end)-data.time{1}(1); % Assuming 1 trial with continuous data
cfg.toi = median(data.time{1}); % middle time point
cfg.timescales = 1:42; % timescale list
cfg.recompute_r = 'per_toi'; % use same similarity parameter across scales
cfg.coarsegrainmethod = 'pointavg'; % pointavg original implementation
cfg.mem_available = 16e9; % memory available, in bytes
cfg.allowgpu = true; % allow GPU computations, if available
[mse] = ft_entropyanalysis(cfg, data);

To run standard MSE analysis, define your `cfg` as follows:

cfg = [];
cfg.m = 2; % pattern length
cfg.r = 0.5; % similarity parameter
cfg.timwin = data.time{1}(end)-data.time{1}(1); % Assuming 1 trial with continuous data
cfg.toi = median(data.time{1}); % middle time point
cfg.timescales = 1:42; % timescale list
cfg.recompute_r = 'per_toi'; % use same similarity parameter across scales
cfg.coarsegrainmethod = 'pointavg'; % pointavg original implementation
cfg.mem_available = 16e9; % memory available, in bytes
cfg.allowgpu = true; % allow GPU computations, if available
[mse] = ft_entropyanalysis(cfg, data);

Please contact us via [@neuro_klooster](https://twitter.com/neuro_klooster) or kloosterman\[at\]mpib-berlin.mpg.de if you have questions or if you find bugs. You can also send us a Pull Request on the Github page.

Expand Down
4 changes: 2 additions & 2 deletions example/meg_eyelink.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ The number of events are not necessarily matched. Under the assumption that a pa
% right-aligned
if nmin==numel(event_meg)
event_asc = event_asc((end-nmin+1):end);
event_meg = event_meg(1:nmin);
event_meg = event_meg(1:nmin);
else
event_meg = event_meg((end-nmin+1):end);
event_asc = event_asc(1:nmin);
event_asc = event_asc(1:nmin);
end
end

Expand Down
2 changes: 1 addition & 1 deletion example/reproducescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ To show how the reproducescript functionality works, we apply it to a script fro
cfg = [];
avgFIC = ft_timelockanalysis(cfg, dataFIC);

% let's make a manual change to the data that is not caputured in the provenance
% let's make a manual change to the data that is not caputured in the provenance
avgFIC.avg = avgFIC.avg * 1e15; % convert from T to fT

% save time-locked data
Expand Down
78 changes: 38 additions & 40 deletions faq/how_to_interpret_the_sign_of_the_phase_slope_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,43 +13,41 @@ Alternative to the answer above, if you're unsure what's going on, you can alway

The following chunk of code provides data that would allow you to answer the above question yourself:

clear all;

% simulate some data
fsample = 1000;
nsample = fsample*30;
dat = randn(1,nsample+100);
data.trial{1}(1,:) = dat(1,1:nsample) + 0.1.*randn(1,nsample);
data.trial{1}(2,:) = dat(1,100+(1:nsample)) + 0.1.*randn(1,nsample);
data.time{1} = (1:nsample)./fsample;
data.label = {'a';'b'}; % channel 2 is leading channel 1
figure;plot(data.time{1},data.trial{1}); xlim([0 1]);
% cut into 2 second snippets
cfg = [];
cfg.length = 2;
data = ft_redefinetrial(cfg, data);
% spectral decomposition
cfg = [];
cfg.method = 'mtmfft';
cfg.output = 'fourier';
cfg.tapsmofrq = 2;
cfg.foilim = [0 100];
freq = ft_freqanalysis(cfg, data);
% connectivity estimation
cfg = [];
cfg.method = 'psi';
cfg.bandwidth = 5;
psi = ft_connectivityanalysis(cfg, freq);
% visualization
cfg = [];
cfg.parameter = 'psispctrm';
ft_connectivityplot(cfg, psi);


clear all;

% simulate some data
fsample = 1000;
nsample = fsample*30;
dat = randn(1,nsample+100);
data.trial{1}(1,:) = dat(1,1:nsample) + 0.1.*randn(1,nsample);
data.trial{1}(2,:) = dat(1,100+(1:nsample)) + 0.1.*randn(1,nsample);
data.time{1} = (1:nsample)./fsample;
data.label = {'a';'b'}; % channel 2 is leading channel 1
figure;plot(data.time{1},data.trial{1}); xlim([0 1]);
% cut into 2 second snippets
cfg = [];
cfg.length = 2;
data = ft_redefinetrial(cfg, data);
% spectral decomposition
cfg = [];
cfg.method = 'mtmfft';
cfg.output = 'fourier';
cfg.tapsmofrq = 2;
cfg.foilim = [0 100];
freq = ft_freqanalysis(cfg, data);
% connectivity estimation
cfg = [];
cfg.method = 'psi';
cfg.bandwidth = 5;
psi = ft_connectivityanalysis(cfg, freq);
% visualization
cfg = [];
cfg.parameter = 'psispctrm';
ft_connectivityplot(cfg, psi);
71 changes: 35 additions & 36 deletions getting_started/mne.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,59 +35,58 @@ In order to import data from MNE-python into FieldTrip, it is most straightforwa

Below are some practical examples that demonstrate how to export FieldTrip data to a fif-file. For this we use the example data of [dataset 10](/faq/datasets#meg-tactile_dipole_fitting). If you want to try this out yourself, please download [SubjectBraille.zip](https://download.fieldtriptoolbox.org/tutorial/SubjectBraille.zip) and extract the `.ds` folder in a convenient location.

### example: export raw - single trial - data structure
### Example: export raw - single trial - data structure

As a first example, we read the data as a continuous chunk. Note that the example dataset used has actually been acquired in 'trial'-mode, which means that it consists of discontinuous segments of data.

datadir = <path-to-data>;
dataset = fullfile(datadir, 'SubjectBraille.ds');
cfg = [];
cfg.dataset = dataset;
cfg.trialdef.length = Inf;
cfg = ft_definetrial(cfg);
datadir = <path-to-data>;
dataset = fullfile(datadir, 'SubjectBraille.ds');
cfg = [];
cfg.dataset = dataset;
cfg.trialdef.length = Inf;
cfg = ft_definetrial(cfg);

cfg.continuous = 'yes';
cfg.channel = {'MEG', '-MLP31', '-MLO12'};
data = ft_preprocessing(cfg);
hs = ft_read_headshape(cfg.dataset); % let's also read this information
cfg.continuous = 'yes';
cfg.channel = {'MEG', '-MLP31', '-MLO12'};
data = ft_preprocessing(cfg);
hs = ft_read_headshape(cfg.dataset); % let's also read this information

We can now export the data to a fiff file, pretending as if it's raw data. Note that the original fiff-file definition stores the data in single precision (32-bit per data point) format. By default, FieldTrip stores the data in the same precision of the actual data, which usually is double (and even complex-valued). MNE-python should be capable of dealing with this type of numeric precision, but other software might not. If the data needs to be stored in single precision, you can use the key-value pair `'precision', 'single'`. Also, note that the current example is a bit silly, given that MNE-python is perfectly capable of reading in native CTF data. Here, it is presented as a proof-of-principle.

fiff_file = fullfile(datadir, 'ctf-raw.fif');
fieldtrip2fiff(fiff_file, data, 'headshape', hs);
save(fullfile(datadir, 'ctf-raw.mat'), 'data'); % for comparison
fiff_file = fullfile(datadir, 'ctf-raw.fif');
fieldtrip2fiff(fiff_file, data, 'headshape', hs);
save(fullfile(datadir, 'ctf-raw.mat'), 'data'); % for comparison

Including the headshape information as an extra input argument will result in the fif-file to also contain the information about the location of the HPI-coils. This might be relevant for a smooth experience in MNE-python, e.g., if one wishes to apply tSSS to the data.

Also, **[fieldtrip2fiff](/reference/fieldtrip2fiff)** will attempt to create an event file (provided the data object has an event structure buried somewhere in the processing history, called `'ctf_raw-eve.fif'`. The events will be represented as numbers, in a Nx3 matrix, where the first column contains the sample index of the event, and the third column contains the value. As of April 2023, also an interpretative comment will be saved in the event file, that allows to map the numbered events in the event file back onto the FieldTrip-style event representation.

### example: export raw - multiple trial - data structure
### Example: export raw - multiple trial - data structure

MNE-python also allows to work with so-called **Epoched** objects, which are similar to a FieldTrip raw data structure with multiple trials, with the constraint that each of the trials has exactly the same time axis. Let's start by reading the trials into FieldTrip, from the original dataset, and then save the data object as a fiff-file. Event information, if present in the `data` structure's `trialinfo` field will be stored in the fiff-file as well.

cfg = [];
cfg.dataset = dataset;
cfg.trialdef.eventtype = 'backpanel trigger';
cfg.trialdef.prestim = 0.6; % this is constrained by the way the data were collected
cfg.trialdef.poststim = 0.6;
cfg.trialdef.eventvalue = [4 8]; % these are the trigger values coded on the backpanel trigger, indicating targets and non-targets
cfg = ft_definetrial(cfg);
cfg.channel = {'MEG', '-MLP31', '-MLO12'}; % read all MEG channels except MLP31 and MLO12
data = ft_preprocessing(cfg);
cfg = [];
cfg.dataset = dataset;
cfg.trialdef.eventtype = 'backpanel trigger';
cfg.trialdef.prestim = 0.6; % this is constrained by the way the data were collected
cfg.trialdef.poststim = 0.6;
cfg.trialdef.eventvalue = [4 8]; % these are the trigger values coded on the backpanel trigger, indicating targets and non-targets
cfg = ft_definetrial(cfg);
cfg.channel = {'MEG', '-MLP31', '-MLO12'}; % read all MEG channels except MLP31 and MLO12
data = ft_preprocessing(cfg);

fiff_file = fullfile(datadir, 'ctf-epo.fif');
fieldtrip2fiff(fiff_file, data);
save(fullfile(datadir, 'ctf-epo.mat'), 'data');
fiff_file = fullfile(datadir, 'ctf-epo.fif');
fieldtrip2fiff(fiff_file, data);
save(fullfile(datadir, 'ctf-epo.mat'), 'data');

### example: export timelocked - evoked field - data structure
### Example: export timelocked - evoked field - data structure

Timelocked data can be exported to an **Evoked** object representation:

cfg = [];
cfg.trials = data.trialinfo==8;
avg = ft_timelockanalysis(cfg, data);
fiff_file = fullfile(datadir, 'ctf-ave.fif');
fieldtrip2fiff(fiff_file, avg);
save(fullfile(datadir, 'ctf-ave.mat'), 'avg');

cfg = [];
cfg.trials = data.trialinfo==8;
avg = ft_timelockanalysis(cfg, data);
fiff_file = fullfile(datadir, 'ctf-ave.fif');
fieldtrip2fiff(fiff_file, avg);
save(fullfile(datadir, 'ctf-ave.mat'), 'avg');
Loading

0 comments on commit 19d0a32

Please sign in to comment.