|
| 1 | +--- |
| 2 | +title: How do I select 32 OPM sensor positions from the 144 slots in the FieldLine Beta2 smart helmet? |
| 3 | +tags: [opm, fieldline, template] |
| 4 | +category: faq |
| 5 | +--- |
| 6 | + |
| 7 | +The FieldLine Beta2 smart helmet that we have at the DCCN has 144 slots for OPM sensors. The template gradiometer definition that is included with FieldTrip lists all those slots, which each have a name like `L101_bz` or `R503_bz`. The prefix (`L` or `R`) indicates the left or right side of the helmet, the three-digit number indicates the slot, and the suffix indicates the orientation (`_bx`, `_by`, or `_bz`) of the corresponding channel. When using the FieldLine HEDscan v3 system each OPM sensor is capable of measuring the magnetic field in either one, two, or in three orthogonal directions (bx, by, and bz), so each physical slot corresponds to three separate entries in the gradiometer. |
| 8 | + |
| 9 | +{% include markup/yellow %} |
| 10 | +It is recommended to work with the two orientations `by` and `bz`, since the sensitivity of the `bx` channel is along the direction of the laser and is very noisy. |
| 11 | +{% include markup/end %} |
| 12 | + |
| 13 | +At the DCCN we currently only have 32 OPM sensors (which means 64 channels) which we can distribute over the 144 slots in the helmet. Depending on your research question you may want to position these 32 sensors over specific brain regions. |
| 14 | + |
| 15 | +The following code demonstrates how to make a graphical selection of the helmet slots in which to place the OPM sensors |
| 16 | + |
| 17 | +## Reading the template sensor positions |
| 18 | + |
| 19 | +You can read the full Beta2 helmet template with all 144 slots using: |
| 20 | + |
| 21 | + grad = ft_read_sens('fieldtrip/template/gradiometer/fieldlinebeta2.mat'); |
| 22 | + |
| 23 | + % it is important to work in consistent units, so let's convert everything to SI units (m, T, V, etc) |
| 24 | + grad = ft_convert_units(grad, 'm'); |
| 25 | + |
| 26 | +To inspect the helmet layout: |
| 27 | + |
| 28 | + figure |
| 29 | + ft_plot_sens(grad, 'fiducial', false) |
| 30 | + view([135 20]); |
| 31 | + |
| 32 | +## Manual selection of sensor slots |
| 33 | + |
| 34 | +For a specific experiment you will have to decide in which of the 144 slots to place the 32 OPM sensors. A very simple selection would for example be to select every fourth sensor location: |
| 35 | + |
| 36 | + cfg = []; |
| 37 | + cfg.channel = 1:4:144; % select every 4th sensor |
| 38 | + selected = ft_electrodeselection(cfg, grad); |
| 39 | + |
| 40 | + figure |
| 41 | + ft_plot_sens(selected, 'fiducial', false) |
| 42 | + |
| 43 | +or to select all locations on the left: |
| 44 | + |
| 45 | + cfg = []; |
| 46 | + cfg.channel = 'L*'; % starting with L |
| 47 | + selected = ft_electrodeselection(cfg, grad); |
| 48 | + |
| 49 | + figure |
| 50 | + ft_plot_sens(selected, 'fiducial', false) |
| 51 | + |
| 52 | +## Graphical selection of sensor slots |
| 53 | + |
| 54 | +As demonstrated in the [OPM helmet design](/tutorial/sensor/opm_helmet_design) tutorial, using the **[ft_sensorplacement](/reference/ft_sensorplacement)** function we can distribute sensors on a 3D printed helmet. This is not what we need here, but the function also returns a 3D model of all sensor positions. This allows us to see where the sensors would or could be, and using **[ft_electrodeselection](/reference/ft_electrodeselection)** we can subsequently make a selection. |
| 55 | + |
| 56 | +We have to trick **[ft_sensorplacement](/reference/ft_sensorplacement)** into using our predefined OPM sensor locations from the temlpate helmet as electrode positions. On each electrode position, it will place an OPM sensor (and the 3D model). |
| 57 | + |
| 58 | + % make an electrode structure |
| 59 | + elec = keepfields(grad, {'unit', 'coordsys'}); |
| 60 | + elec.type = 'eeg'; |
| 61 | + elec.label = grad.label; |
| 62 | + elec.elecpos = grad.coilpos; % this is the position of each "electrode" or OPM |
| 63 | + elec.elecori = grad.coilori; % this is the orientation of each "electrode" or OPM |
| 64 | + |
| 65 | +We also need a head surface on which the electrodes can be projected. We can simply take the electrode (or template OPM) positions and use that instead of a real head surface. |
| 66 | + |
| 67 | + headshape = elec.elecpos; |
| 68 | + |
| 69 | +Finally we need the 3D model of the sensor geometry, which will be copied and placed on each electrode position. |
| 70 | + |
| 71 | + template = ft_read_headshape('fieldline_sensor.stl'); |
| 72 | + template.unit = 'mm'; |
| 73 | + template = ft_convert_units(template, 'm'); |
| 74 | + |
| 75 | +With these inputs, we can now generate the sensor positions, which will be the same as the original ones, but importantly also the 3D OPM sensor geometry structure. |
| 76 | + |
| 77 | + cfg = []; |
| 78 | + cfg.template = template; |
| 79 | + cfg.elec = elec; |
| 80 | + [cfg, sensor] = ft_sensorplacement(cfg, headshape); |
| 81 | + |
| 82 | + |
| 83 | + figure |
| 84 | + ft_plot_sens(grad); |
| 85 | + ft_plot_mesh(sensor) |
| 86 | + |
| 87 | +Now that we have the 3D model of the 144 sensors, we can plot them as a mesh in **[ft_electrodeselection](/reference/ft_electrodeselection)**. You can use the MATLAB rotate button to look from different angles at the helmet and when 3D rotation is off, you can click on an electrode (which is at the base of each OPM sensor) to enable/disable each sensor. |
| 88 | + |
| 89 | + cfg = []; |
| 90 | + cfg.headshape = elec.elecpos; |
| 91 | + cfg.mesh = sensor; |
| 92 | + selected = ft_electrodeselection(cfg, grad); |
| 93 | + |
| 94 | +Since we have 144 slots and 32 sensors, we have to disable 112 of the possible slots. Rather than starting with all sensors enabled, you can also start with a single sensor enabled. You can subsequently disable that channel, and start selecting the 32 sensor positions from a blank slate. It is not possible to start without any sensor selected, so you should always at least have one in `cfg.channel`. |
| 95 | + |
| 96 | + cfg = []; |
| 97 | + cfg.headshape = elec.elecpos; |
| 98 | + cfg.mesh = sensor; |
| 99 | + cfg.channel = 1; % only select the 1st sensor to start with |
| 100 | + selected = ft_electrodeselection(cfg, grad); |
| 101 | + |
| 102 | +Recommended is to place at least 5 sensors evenly spaced around the head to keep it in place within the helmet: one on the vertex, two at the temples, and two at the front and back. |
| 103 | + |
| 104 | +## See also |
| 105 | + |
| 106 | +For more information on handling and analyzing OPM data see also these tutorials |
| 107 | + |
| 108 | +{% include seealso category="tutorial" tag="opm" %} |
| 109 | + |
| 110 | +and example scripts |
| 111 | + |
| 112 | +{% include seealso category="example" tag="opm" %} |
| 113 | + |
| 114 | +and frequently asked questions. |
| 115 | + |
| 116 | +{% include seealso category="faq" tag="opm" %} |
0 commit comments