[FieldTrip] understanding ft_dipolfitting function

Schoffelen, J.M. (Jan Mathijs) janmathijs.schoffelen at donders.ru.nl
Tue Apr 16 17:12:11 CEST 2024


Hi Sara,
I asked my new best friend, and see below for how the conversation evolved. I think that this is adequate. I hope that somebody takes up the challenge and makes a concrete suggestion for the improvement of the documentation to ft_dipolefitting, in order to avoid future confusion. Please submit the suggested code changes as a PR into the fieldtrip github repository.
Thank you,

Jan-Mathijs



ChatGPT
ChatGPT

In the provided code snippet, there are two main sections that handle different scenarios for specifying the dipole positions: one for when a grid search is used and another for when a starting location is provided directly.

Let's break down each section:

Lines 1-8:

  *   When a grid search is performed (cfg.gridsearch = 'yes'), a complete grid of dipole positions is constructed using the function ft_prepare_sourcemodel.
  *   The grid can be specified using cfg.xgrid, cfg.ygrid, and cfg.zgrid, which define the coordinates of the grid points along the x, y, and z axes, respectively. These can be provided as vectors or set to 'auto' for automatic grid generation.
  *   Additionally, cfg.resolution can be used to specify the spacing between grid points for automatic grid generation.
  *   If the source model represents a triangulated cortical sheet, the vertices and triangles of the sheet can be provided using cfg.sourcemodel.pos and cfg.sourcemodel.tri.

Lines 11-15:

  *   If a grid search is not performed (cfg.gridsearch = 'no' or not specified), the user can specify the positions of a few dipoles of interest directly.
  *   The dipole positions can be provided as a matrix of coordinates using cfg.sourcemodel.pos.
  *   Optionally, cfg.sourcemodel.inside can be used to specify whether each grid point is inside the brain.
  *   For a 3-D grid, cfg.sourcemodel.dim can be used to specify the dimensions of the grid.

Lines 17-18:

  *   If a grid search is not performed, and instead, a direct search for the dipole position is conducted (cfg.gridsearch = 'no' or not specified), the starting location for the nonlinear search must be provided.
  *   This starting location is specified using cfg.dip.pos, which is a matrix containing the initial dipole positions. Each row of the matrix corresponds to the coordinates of a dipole.

In summary, the first section handles the construction of a dipole grid or cortical sheet if a grid search is used, while the second section handles the specification of dipole positions directly if a grid search is not used. The cfg.dip.pos parameter is used specifically for providing starting locations when a grid search is not employed.

[User]
You
are you sure about this? I get the impression that the use of 'cfg.sourcemodel' applies to all cases where cfg.gridsearch = 'yes', and the that the use of 'cfg.dip' applies to the case where cfg.gridsearch = 'no'
ChatGPT
ChatGPT

You're correct, and I appreciate the clarification. Let's refine the explanation to ensure clarity:

  *
When cfg.gridsearch = 'yes', the cfg.sourcemodel structure is utilized to specify the dipole positions, regardless of whether a grid search is performed or not. This structure allows for defining a dipole grid or cortical sheet.
  *
On the other hand, when cfg.gridsearch = 'no' or is not specified, the cfg.dip structure is used to specify the initial dipole positions directly for the nonlinear search.

In both cases, cfg.sourcemodel is used to specify the dipole positions, but the interpretation of these positions varies depending on whether a grid search is performed or not. Thank you for pointing out the need for clarification.

[User]
You
I am not so sure about your last point, where you say "In both cases, cfg.sourcemodel is used to specify the dipole positions, but the interpretation of these positions varies depending on whether a grid search is performed or not. Thank you for pointing out the need for clarification." My interpretation is that cfg.sourcemodel is only used when cfg.gridsearch = 'yes'
ChatGPT
ChatGPT

You're correct, and I appreciate your patience in clarifying. Let me rephrase that:

  *
When cfg.gridsearch = 'yes', the dipole positions are indeed specified using the cfg.sourcemodel structure. This structure allows for defining a dipole grid or cortical sheet.
  *
When cfg.gridsearch = 'no' or is not specified, the dipole positions are not specified using cfg.sourcemodel. Instead, the starting locations for the nonlinear search are provided directly using the cfg.dip.pos parameter.

Thank you for bringing attention to this point, and I apologize for any confusion.

[User]
You
do you have a suggestion to improve the documentation of the ft_dipolefitting function to better reflect this?
ChatGPT
ChatGPT

Improving the documentation for the ft_dipolefitting function to better clarify the usage of cfg.sourcemodel and cfg.dip based on the cfg.gridsearch parameter could enhance user understanding. Here's a suggestion for improving the documentation:

matlabCopy code
function [source] = ft_dipolefitting(cfg, data)
% FT_DIPOLEFITTING fits a dipole model to EEG or MEG data.
%
% Usage:
%   [source] = ft_dipolefitting(cfg, data)
%
% Input:
%   cfg: Configuration structure specifying the fitting parameters.
%       cfg.gridsearch: Specifies whether to perform a grid search for
%                      initial dipole positions. Options are 'yes' or 'no'.
%                      Default is 'no'.
%
%       If cfg.gridsearch is 'yes':
%           cfg.sourcemodel: Structure specifying the dipole grid or cortical
%                            sheet for the grid search.
%               cfg.sourcemodel.pos: N*3 matrix with the vertex positions of
%                                     the dipole grid or cortical sheet.
%               cfg.sourcemodel.tri: M*3 matrix that describes the triangles
%                                     connecting the vertices.
%
%       If cfg.gridsearch is 'no' or not specified:
%           cfg.dip: Structure specifying the starting dipole positions for
%                    the nonlinear search.
%               cfg.dip.pos: Initial dipole position, matrix of Ndipoles x 3.
%
%   data: Data structure containing EEG or MEG data.
%
% Output:
%   source: Structure containing the fitted dipole(s) information.
%
% Example:
%   % Perform dipole fitting with a grid search
%   cfg.gridsearch = 'yes';
%   cfg.sourcemodel.pos = grid_positions;
%   cfg.sourcemodel.tri = grid_triangles;
%   source = ft_dipolefitting(cfg, data);
%
%   % Perform dipole fitting without a grid search
%   cfg.gridsearch = 'no';
%   cfg.dip.pos = initial_positions;
%   source = ft_dipolefitting(cfg, data);


By explicitly stating the usage of cfg.sourcemodel and cfg.dip based on the cfg.gridsearch parameter in the function documentation, users can better understand how to specify dipole positions depending on their chosen approach. Additionally, providing clear examples for both scenarios can further illustrate the usage of the function.

On 16 Apr 2024, at 16:37, Sara Cinelli via fieldtrip <fieldtrip at science.ru.nl<mailto:fieldtrip at science.ru.nl>> wrote:

I have a question regarding the following function:
function [source] = ft_dipolefitting(cfg, data)
which is reported at the following link: https://github.com/fieldtrip/fieldtrip/blob/release/ft_dipolefitting.m<https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ffieldtrip%2Ffieldtrip%2Fblob%2Frelease%2Fft_dipolefitting.m&data=05%7C02%7Cfieldtrip%40science.ru.nl%7C0dfb975b6a10409f2b3308dc5e27977a%7C084578d9400d4a5aa7c7e76ca47af400%7C1%7C0%7C638488771379042058%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=75ErcBZUzt43g6qWEznG86oPPvFp3YB61%2BF8PjzeDvA%3D&reserved=0>
I would like to understand what changes in the following lines when the question is about doing the grid search or not and what is the difference between sourcemodel and dipole.
In particular, it is not very clear for me what the function does from lines 11-15 and from 17-18: what is the difference between this two sections?

Thank you,

Sara
1 % If you start with a grid search, the complete grid with dipole positions is
2 % constructed using FT_PREPARE_SOURCEMODEL. It can be specified as as a regular 3-D
3 % grid that is aligned with the axes of the head coordinate system using
4 % cfg.xgrid = vector (e.g. -20:1:20) or 'auto' (default = 'auto')
5 % cfg.ygrid = vector (e.g. -20:1:20) or 'auto' (default = 'auto')
6 % cfg.zgrid = vector (e.g. 0:1:20) or 'auto' (default = 'auto')
7 % cfg.resolution = number (e.g. 1 cm) for automatic grid generation
8 % If the source model destribes a triangulated cortical sheet, it is described as
9 % cfg.sourcemodel.pos = N*3 matrix with the vertex positions of the cortical sheet
10 % cfg.sourcemodel.tri = M*3 matrix that describes the triangles connecting the vertices

11 % Alternatively the position of a few dipoles at locations of interest can be
12 % user-specified, for example obtained from an anatomical or functional MRI
13 % cfg.sourcemodel.pos = N*3 matrix with position of each source
14 % cfg.sourcemodel.inside = N*1 vector with boolean value whether grid point is inside brain (optional)
15 % cfg.sourcemodel.dim = [Nx Ny Nz] vector with dimensions in case of 3-D grid (optional)
16 %
17 % If you do not start with a grid search, you have to give a starting location
18 % for the nonlinear search
19 % cfg.dip.pos = initial dipole position, matrix of Ndipoles x 3

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.science.ru.nl/pipermail/fieldtrip/attachments/20240416/c0e4d361/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: AEdFTp6-QFrjBq-T5bQ_iHQvJjSV4kISHWwJcLugyK1j=s96-c.jpeg
Type: image/jpeg
Size: 3973 bytes
Desc: AEdFTp6-QFrjBq-T5bQ_iHQvJjSV4kISHWwJcLugyK1j=s96-c.jpeg
URL: <http://mailman.science.ru.nl/pipermail/fieldtrip/attachments/20240416/c0e4d361/attachment-0001.jpeg>


More information about the fieldtrip mailing list