Back to the main page.

Bug 3334 - create ft_appendlayout

Reported 2017-08-22 20:52:00 +0200
Modified 2019-08-10 12:43:49 +0200
Product: FieldTrip
Component: plotting
Version: unspecified
Hardware: PC
Operating System: Mac OS
Importance: P5 normal
Assigned to: Roemer van der Meij
Depends on:
See also:

Roemer van der Meij - 2017-08-22 20:52:54 +0200

I have some extra time on my hands the coming weeks, so thinking of making an ft_appendlayout. (Could be I made an bugzilla/github thing on this previously, but couldn't find it) Right now, I'm thinking of capabilities as shown by the options below. The first two ways of specifying the appending will be my priority and implemented first, but might as well add some others. Any additional ideas? Terminlogy TBD Each layout will be transformed to normalized units in the total space of the appendlayouts given the below options, and then simply concatenated into one bigger layout. lay = ft_appendlayout(cfg,lay,lay,lay,...) (default is a rough 3:4 aspect ratio arrangement) cfg.nrows = scalar, number of rows of appended layouts cfg.ncolumns = scalar, number of rows of appended layouts OR cfg.matrix = boolean/index matrix (can be used to e.g. keep a center square empty) OR cfg.orthographic?? = 'S/ALP/I' row-wise specification of orthographic viewpoint 'unfolding' cfg.shrinktosens = scalar or Nlay vector, 0<>1 (1=electrodes on layout border+padding, 0.5=half the distance of current edge (outline/mask), 0=no squeeze) cfg.paddingwithin = scalar, 0<>1, within layout padding on each side (fraction of layout box) cfg.paddingbetween = scalar, 0<>1, between layout padding on each side (fraction of layout box) cfg.keepoutline = yes/no (if no, cfg.squeezetosens cannot be used) cfg.keepmask = yes/no Ad cfg.shrinktosens: useful for depths in a full brain outline, where you'd like to keep some of the brain, but not all, as the sensors will be too small. Padding is added after cutting out the sensors. Ad cfg.orthographic: I mean a 'box' type unfolding like (in the example) S A L P R I (this probably won't appear well in bugzilla, but in this case I mean anterior-left-posterior-right, with superior above posterior and inferior below posterior) I currently don't have an idea on how to make this happen, because the ortho viewpoint a layout originated from is not detectable from the lay. Layouts also don't contain cfg's, so even a 'dirty' peek would not work.

Robert Oostenveld - 2017-08-23 09:12:52 +0200

I remember discussing it with you in relation to ECoG visualisation. That discussion is here at and subsequent comments. For bug 3096 I already created some code that is in a (rather stale) branch at Among others it attempts to support something like cfg.layout = {lay1, lay2, lay3} ft_multiplotER(cfg, data) which touches upon your suggestion. The reason for 3096 to relate to layouts is that I came up with the idea to use the layout for graphical channel selection. We should review the changes that I made in that branch and we should make a design decision. In general I am fine with stat = ft_freqstatistics(cfg, allfreq{:}) because that is simple MATLAB syntax, not FieldTrip specific. I could imagine the following to work (for various functions) cfg.elec = {elec_ecog, elec_shaft1, elec_shaft2}; or cfg.elec = ft_appendsens(cfg, elec_ecog, elec_shaft1, elec_shaft2); which could be written as alleles{:} just like allfreq{:}. Idem for cfg.grad (consider sequential measurements with small sensor arrays) and you can consider similar use for cfg.headmodel (consider simultaneous EEG and MEG) cfg.sourcemodel (consider cortical sheet and some deeper brain structures) ft_datatype_headmodel already supports it ft_prepare_vol_sens already supports it ft_compute_leadfield already supports it ft_convert_units supports it ft_prepare_layout supports it in my branch bug3096 ft_datatype_sens does not support it there are other functions in forward that also support it (grep for "iscell").

Roemer van der Meij - 2017-08-24 01:51:44 +0200

Ha, it's good to see I was at least somewhat consistent in my ideas ;) Useful indeed for channel selection in databrowser. Using cell-arrays sounds good. To get some additional control, shall we make an ft_appendlayout and call that from within ft_prepare_layout as you suggested with reasonable defaults? It's a similar operational level as ft_appendsens. Shall I make it? (using your branch as some suggestions) Hadn't thought of the comnt/scale yet. If desired to be kept, let's place them e.g. in the layout that's in the lower right. I now also remember the difficult situation of the neuromag sensor sets... One way we might still be able to do the ortho unfolding of e.g. MEG sensors (you were a fan of this right?), would be to allow for all/subset of cfg options of ft_prepare_layout to be organized in cell-arrays (channel/viewpoint/projection/etc), like the multiple highlight sets in ft_topoplotXXX. This would keep the ortho viewpoint information while creating the individual layouts. However, then one might as well do it oneself, as the viewpoints have to specific by the user (and, as such, the user would know which is which).

Robert Oostenveld - 2017-08-24 10:27:02 +0200

(In reply to Roemer van der Meij from comment #2) Yes, please start a new branch, taking some suggestions from my branch. I think cfg.layout in ft_prepare_layout is best handled like this (at the start), similar to the other functions if isfield(cfg, 'layout') && iscell(cfg.layout) lay = {}; for i=1:numel(cfg.layout) tmpcfg = cfg; tmpcfg.layout = cfg.layout{i}; lay{i} = ft_prepare_layout(tmpcfg); end lay = ft_appendlayout([], lay{:}); return end If advanced handling is needed, e.g. different left/right viewpoints, people should call it multiple times themselves. I think ft_appendlayout needs an option (or default behavior) to arrange the layouts in a nice way. Please don't start too fancy, horizontal/vertical is initially enough. But we should keep the 'unfoldedbox' option also in mind, i.e. as if you were to unfold a paper cube. Something to consider: what happens in multi and topoplot if the same channel is present in two of the layouts that are appended? That would happen for the unfoldedbox version. Something to consider: combining is one operation, making a subset selection is the reverse operation. We recently figured out that we don't have a selection making function for electrodes (I explicitly disabled it in ft_selectdata, since elec/grad/opto is not 100% robustly supported as "data"). Here the same applies, we don't have a subset selection function for layouts. The ft_selectdata should not be expected to work on layouts. We do have the option in the main FT functions to use to make a subset for subsequent processing/plotting. I would hope that to be enough here as well.

Roemer van der Meij - 2017-08-25 00:54:12 +0200

Sounds good. As a default, let's do a simple rectangle if >3 and horizontal otherwise as a start. Re: subselecting I like the fact that layouts are currently stable, and that 'selection' is done at the to-be-plotted-data level. It makes sense from the perspective of a reference map, which doesn't change after you do something with the data (unless it is a specific spatial transform such as grad->planar/etc), or if you select a subset of channels. Like viewing a picture of a heart doesn't change where it is in the body, and its useful to know exactly where it was (terrible analogy, I know). I'd argue the same could be said for elec/grad. They are (relatively) stable representations of all the electrodes/sensors. Re: duplicate channels To my great surprise, topoplotXXX and multiplotXXX deal with it fine already actually! (mostly). Added some coded to show it below. The interactive selection -> singleplotXXX doesn't deal well with it (duplicate channels only contribute to average once), but the singleplotXXX to topoplot works well again (duplicate channels are shown as duplicate). It is debatable whether or not duplicate channels should be counted more than once in the singleplotXXX average over channels. Problems with duplication could be deeper though, I still have to take a more thorough look. % load tutorial data load('dataFIC.mat') % get freq cfg = []; cfg.output = 'pow'; = 'MEG'; cfg.method = 'mtmconvol'; cfg.taper = 'hanning'; cfg.foi = 2:2:30; cfg.t_ftimwin = ones(length(cfg.foi),1).*0.5; cfg.toi = -0.5:0.05:1.5; TFRhann = ft_freqanalysis(cfg, dataFIC); % mess with layout cfg = []; cfg.layout = 'CTF151'; lay = ft_prepare_layout(cfg); lay.label(1:75) = lay.label(1); % plot topo cfg = []; cfg.baseline = [-0.5 -0.1]; cfg.baselinetype = 'absolute'; cfg.xlim = [0.9 1.3]; cfg.zlim = 'maxabs'; cfg.ylim = [15 20]; cfg.marker = 'labels'; cfg.layout = lay; figure ft_topoplotTFR(cfg, TFRhann); % plot multiplot cfg = []; cfg.baseline = [-0.5 -0.1]; cfg.baselinetype = 'absolute'; cfg.zlim = 'maxabs'; cfg.showlabels = 'yes'; cfg.layout = lay; figure ft_multiplotTFR(cfg, TFRhann); % mess with layout cfg = []; cfg.layout = 'CTF151'; lay = ft_prepare_layout(cfg); lay.pos = cat(1,lay.pos,lay.pos(1:151,:)); lay.width = cat(1,lay.width,lay.width(1:151)); lay.height = cat(1,lay.height,lay.height(1:151)); lay.label = cat(1,lay.label,lay.label(1:151)); lay.outline = cat(2,lay.outline,lay.outline); lay.mask = cat(1,lay.mask,lay.mask); for i = 5:8 lay.outline{i}(:,1) = lay.outline{i}(:,1)+1.2; end lay.mask{2}(:,1) = lay.mask{2}(:,1)+1.2; lay.pos(154:end,1) = lay.pos(154:end,1)+1.2; % plot topo cfg = []; cfg.baseline = [-0.5 -0.1]; cfg.baselinetype = 'absolute'; cfg.xlim = [0.9 1.3]; cfg.zlim = 'maxabs'; cfg.ylim = [15 20]; cfg.marker = 'labels'; cfg.layout = lay; figure ft_topoplotTFR(cfg, TFRhann); % plot multiplot cfg = []; cfg.baseline = [-0.5 -0.1]; cfg.baselinetype = 'absolute'; cfg.zlim = 'maxabs'; cfg.showlabels = 'yes'; cfg.layout = lay; figure ft_multiplotTFR(cfg, TFRhann);

Robert Oostenveld - 2019-03-27 23:21:06 +0100

this is now implemented and documented in the layout tutorial. See also mac011> git commit -a [master 04d60ac] updated the layout tutorial with the schematic iEEG grid (combined sEEG and ECoG) - - 9 files changed, 160 insertions(+), 4 deletions(-) create mode 100755 assets/img/tutorial/layout/SubjectUCI29_grids.png create mode 100644 assets/img/tutorial/layout/freq_layoutAll.png create mode 100644 assets/img/tutorial/layout/layoutAll.png create mode 100644 assets/img/tutorial/layout/layoutL.png create mode 100644 assets/img/tutorial/layout/layoutLAM.png create mode 100644 assets/img/tutorial/layout/layoutLPG.png create mode 100644 assets/img/tutorial/layout/layoutLTG.png create mode 100644 assets/img/tutorial/layout/layoutShafts.png

Robert Oostenveld - 2019-08-10 12:43:49 +0200

This closes a whole series of bugs that have recently been resolved (either FIXED/WONTFIX/INVALID). If you disagree, please file a new issue on