Back to the main page.

Bug 1792 - implement the realtime head localiser for the Elekta neuromag system

Status CLOSED FIXED
Reported 2012-10-25 12:49:00 +0200
Modified 2019-08-10 12:42:08 +0200
Product: FieldTrip
Component: realtime
Version: unspecified
Hardware: Other
Operating System: Other
Importance: P3 enhancement
Assigned to: Arjen Stolk
URL:
Tags:
Depends on: 2341
Blocks:
See also: http://bugzilla.fcdonders.nl/show_bug.cgi?id=1638http://bugzilla.fieldtriptoolbox.org/show_bug.cgi?id=3369

Robert Oostenveld - 2012-10-25 12:49:08 +0200

I discussed with the MEG people in Trento whether and how we could use the realtime headlocalizer on their neuromag machine. I also discussed it with Arjen, the PhD student working on this (among others). This "bug" serves as a platform for linking the people and information to each other.


Robert Oostenveld - 2012-10-29 11:38:40 +0100

What I understand following discussion with Arjen (who got the info from Leipzig) is that the neuromag system records the localizer coil signals superimposed on the normal MEG data and that there is no online localization of the localizer coils (which are magnetic dipoles). For the ft_regressconfound function it means that an offline function needs to be made that estimates the position of the localizer coils as function of time. Or is there a Neuromag software tool that does this? For the realtime/online_meg/ft_realtime_headlocalizer function it means that it has to be extended with an online realtime fit of the localizer coils. That consists of a fft or a bandpassfilter+PCA followed by fitting a magnetic dipole to the (spectral) topography. It would help both for the offline and online development to have a recording with the continuous head localization switched on. It does not have to be a long recording, say 5 minutes would do. There should ideally be a little bit of head movement in a realistic range (e.g. 1 cm).


Thomas Hartmann - 2012-10-29 12:02:50 +0100

(In reply to comment #1) hi, just today i took a look at one file including cHPI and some head movements with one of our masters students and came to the same conclusion. i am just uploading the file to my dropbox. should be there in like 10min to download. here is the link: https://www.dropbox.com/sh/gt1byj3z0tjcl88/WoynC4lrfw cheers and thanks for working on it!! thomas


Arjen Stolk - 2012-10-29 13:04:33 +0100

Created attachment 355 real-time head localizer


Arjen Stolk - 2012-11-21 08:10:55 +0100

Created attachment 375 neuromag_headloc_flowchart This flowchart provides a simple overview of what has already been implemented in the FieldTrip toolbox with respect to the CTF head localizer setup. Additionally it shows the elements of the infrastructure that need to be implemented for it to work on a Neuromag system.


Robert Oostenveld - 2012-12-03 16:33:53 +0100

Created attachment 388 screen shot Arjen and I have looked in detail at the data. We don't understand the frequency specific topographies, and neither does the dipole fitting procedure. The magnetic dipole fit procedure is able to reproduce the topo's, but results in dipole positions outside the helmet (with an almost perfect match to the topography of the recorded data) To understand what is wrong in our understanding, we did a "conventional" analysis with hdr = ft_read_header(dataset); offset = 3; % seconds begsample = ([0 1 2 3 4 5]+offset) * hdr.Fs+1; endsample = begsample + hdr.Fs-1; cfg = []; cfg.trl = [begsample(:) endsample(:)]; cfg.trl(:,3) = 0; cfg.dataset = dataset; cfg.channel = 'MEGMAG'; data = ft_preprocessing(cfg); cfg = []; cfg.method = 'mtmfft'; cfg.output = 'pow'; cfg.foilim = [1 500]; cfg.taper = 'hanning'; freq = ft_freqanalysis(cfg, data); cfg = []; cfg.parameter = 'powspctrm'; cfg.operation = 'log10'; freqlog = ft_math(cfg, freq); cfg = []; cfg.layout = 'neuromag306mag.lay'; cfg.interactive = 'yes'; ft_multiplotER(cfg, freq); % ft_multiplotER(cfg, freqlog); See attached screenshot. It shows the three peaks, that they are almost exclusively visible in a bunch of channels on the right, and the three topographies. Anyone an idea?


Robert Oostenveld - 2012-12-03 16:36:04 +0100

added Gianpaolo to the CC list. @GP, please look at comment 5


Arjen Stolk - 2012-12-07 16:25:18 +0100

We presumed the three coils should and were attached to the two ear sites and the nasion during the recording. is this correct?


Thomas Hartmann - 2012-12-07 16:27:34 +0100

(In reply to comment #7) we have five coils in total. three of them are attached to the forhead and two are attached behing the ears.


Arjen Stolk - 2012-12-07 17:08:02 +0100

(In reply to comment #8) The spectrum shows 3 peaks; were two coils disengaged? Do the plotted topographies (see screenshot) subjectively match the positions of the coils during the recording? Id est; two right frontal, and one right ear?


Thomas Hartmann - 2012-12-07 17:22:27 +0100

(In reply to comment #9) we have some problems with 2 of the 5 coils now and then. i do not know for sure whether this was the case in this measurement as well, but it is very likely. the system checks whether the coil positions are valid when initializing the measurement. it would make sense if those deemed bad are not included in any further continuous head positioning.... the topographies look ok. the right ear one looks perfect to me. i would have expected one more in the middle, though, but that might be correct as well. i will try to prepare a measurement for you during the next week with working five coils and better defined positions so we can further verify. besides, i know that the positions of the coil are also digitized together with the headshape and fiducials. i havent found any trace of the yet in the data but will keep looking for it. besides: thanks for the fantastic work. it is awesome to see progress on this!!!!


Arjen Stolk - 2012-12-07 17:42:50 +0100

(In reply to comment #10) Hi Thomas, good to hear that the sensor topographies do make sense. We were puzzled by them and also by the observation that the contribution of each coil to the sensor array is very focal. Namely, there's no spatial gradient in the distribution; each coil projects very strongly on a small subset of the axial gradiometers. Using those axial gradiometer channels subsequently results in dipole positions fitted outside the dewar; due to the sharp distribution the algorithm cannot distinct between inside and outside, while probably getting the distance to the sensors correct. Perhaps we can solve this issue by limiting the grid search to a space defined as inside the dewar (e.g. a sphere). My guess is that MaxFilter does the same when performing the signal space separation algorithm. We will let you know on the outcome. It would indeed be nice if we can get the actual positions to confirm the correctness of the dipole fits.


Arjen Stolk - 2012-12-17 11:02:47 +0100

Hi Thomas, After just discussing with Robert, we realized another approach may be more effective. Id est, to use the digitized coil positions from the fif header to restrict/bias the grid search. Do you think you can get us another dataset with 5 working coils on a short notice? And secondly, where to find to those digitized positions in the fif file? Yours, Arjen


Gianpaolo Demarchi - 2012-12-21 12:08:33 +0100

(In reply to comment #12) Hi Arjen, just a quick info ... AFAIK fieldtrip is using the very same "mne" toolbox for the fiff reading, so I found the needed info in the orig.raw.info.dig structure The first three elements are the Polhemus values of the preauricolar point and nasion (in some order, left preauricolar is +x, nasion is +y, and upwards is +z), the followings 5 elements of the structure are the digitized values of the 5 HPI coils, and the next ones are the head shape and/or EEG electrodes, if present. I'm not physically in the lab, but I'll find some file (short, or shortened) that contains all the 5 coils active, both as initial location, and as continuous HPI. Best wishes, Gianpaolo


Gianpaolo Demarchi - 2012-12-21 12:26:22 +0100

ADDENDUM: the orig. raw.info.dig structures contains some additional info, such as "kind", which tells what kind of thing is digitized (1 for RPA/LPA/NAS, 2 for HPI coils, 4 for head shape, 3 for EEG but I'm not sure), and the "ident" field, which is an increasing number for the "kind" type (i.e. for the HPI coil goes from 1 to 5). I'm not fully aware of the coord_frame value, I should dig into the "mne" documentation to see what is what (head, device?).


Gianpaolo Demarchi - 2012-12-21 18:23:39 +0100

ADDENDUM: the orig. raw.info.dig structures contains some additional info, such as "kind", which tells what kind of thing is digitized (1 for RPA/LPA/NAS, 2 for HPI coils, 4 for head shape, 3 for EEG but I'm not sure), and the "ident" field, which is an increasing number for the "kind" type (i.e. for the HPI coil goes from 1 to 5). I'm not fully aware of the coord_frame value, I should dig into the "mne" documentation to see what is what (head, device?).


Robert Oostenveld - 2013-01-15 16:08:13 +0100

(In reply to comment #13) > I'm not physically in the lab, but I'll find some file (short, or shortened) > that contains all the 5 coils active, both as initial location, and as > continuous HPI. Hi Gianpaolo, Have you had any chance of finding such a dataset?


Gianpaolo Demarchi - 2013-01-16 08:56:02 +0100

(In reply to comment #16) Hi Robert, here we go: https://www.dropbox.com/sh/tnlo25g2qrduo95/JoSglN9uBf AFAIK (I was not there when it was collected) this one (these ones, one long and a shortened version, to upload faster) should have all the coils active. I fear that something is broken, since it's giving me the "Yokogawa" warning when I try to open them, and I'll try to send you a better one ASAP, but by now the machine is off (some maintenance work) so I cannot really do another shot today ... Sorry for the delay, Gianpaolo


Robert Oostenveld - 2013-01-16 14:25:34 +0100

Created attachment 405 intermediate version, has debugging stuff in it


Arjen Stolk - 2013-02-20 17:33:22 +0100

These lines of code get the HPI positions (obtained with polhemus tracking) from the fif header. % locate the number and positions of the HPI coils from the header ctr = 0; for j = 1:length(hdr.orig.raw.info.dig) if hdr.orig.raw.info.dig(1,j).kind == 2 % 1: RPA/LPA/NAS, 2: HPI coils, 4: Head shape ctr = ctr+1; HPIpos(ctr,:) = double((hdr.orig.raw.info.dig(1,j).r).*100); % convert from m to cm end end fprintf('%d HPI coils found in the header file\n', ctr); However, using ft_realtime_coillocalizer, I have not been able to correctly fit the coil positions on basis of the recorded MEG data (using 102 magnetometer channels). In fact, those positions are not even close to the ones obtained with polhemus (in 'HPIpos') and are frequently fitted even outside the dewar. So far, it seems that dipolefitting is tough because the spatial distribution of the coil-induced magnetic field is sharp and not gradient-like (see plot made by Robert and attached somewhere in this bug report).


Arjen Stolk - 2013-02-20 19:38:08 +0100

Two things need to be tested/checked in order to constrain the dipole fitting procedure: 1) whether there is a (separate) channel in the dataset that contains the sinusoidal electrical current (and thus phase information) 2) build in a 'rigid body' constraint option (into dipolefit.m) that allows fitting of a rigid body that is based on the 5 HPI coil positions combined. An additional 'onetoone' mapping (between estimated coil position and element of of the rigid body) constraint should also be considered to further constrain the grid search (not possible for the BTI MEG system because all coils are energized with the same sinusoidal frequency) (In reply to comment #19)


Arjen Stolk - 2013-04-10 00:00:05 +0200

Hi Gianpaolo, Robert and I have recently been trying to optimize the dipole fitting procedure for the Neuromag HPI coils. I do not have screenshots of the results right now, but at one point we started to believe that there was a mismatch between the order of generated magnetic fields and measured fields. The MaxFilter documentation states: "Typical frequencies of the signals are 154, 158, 162, 166 and 170 Hz for the sampling rate of 600 Hz (low-pass Þlter at 200 Hz), or 293, 307, 314, 321 and 328 Hz for higher sampling rates." For the example dataset you gave us (Fs = 1000 Hz), we assumed that the frequency of 293 Hz belonged to HPI coil 1, 307 Hz to HPI coil 2, etc. However, we suspect this may not be the correct order and were wondering if you know more about this. Reading the neuromag file header using: dataset = '/home/common/matlab/fieldtrip/data/test/bug1792/sample_chpi.fif'; hdr = ft_read_header(dataset); I could retrieve some information on the HPI acquistion and analysis parameters: >> hdr.orig.raw.info.acq_pars ans = ... ACQhpiamp 2 ACQhpidmax 0.005 ACQhpigmin 0.98 ... DEFhpiProgName hpi_psd DEFhpiTriggerChannel STI201 DEFhpifitProgName hpifit ... Also, as indicated by an earlier post by you, there is some information on the identity of the HPIcoil: >> hdr.orig.raw.info.dig(4) ans = kind: 2 ident: 1 r: [3x1 single] coord_frame: 4 However, I could not find which sinusoidal frequency the coil was energized with. Do you know whether to find it? Best wishes, Arjen


Gianpaolo Demarchi - 2013-04-10 18:29:48 +0200

(In reply to comment #21) Hi Arjen, sorry for the long delays in replying, I'm on and off with this project (and with my entire life, though ;-)) I started tinkering with the ft_realtime_coillocalizer.m you sent me yesterday, without much success (I come on this point later, though ...) > The MaxFilter documentation states: > For the example dataset you gave us (Fs = 1000 Hz), we assumed that the > frequency of 293 Hz belonged to HPI coil 1, 307 Hz to HPI coil 2, etc. However, > we suspect this may not be the correct order and were wondering if you know > more about this. As a matter of fact I/we don't know any order ... we're trying to follow an order, also when mounting them, like "the first one on the connector, it's the first one on the left side" but we never followed a strict rule, since the Elekta SW never complained for any order, it detects the relative distance and spits out some number independent from the order ... >Also, as indicated by an earlier post by you, there is some information on the > identity of the HPIcoil: >> hdr.orig.raw.info.dig(4) > However, I could not find which sinusoidal frequency the coil was energized > with. Do you know whether to find it? I got this info "reverse engineering" what is what and what comes first (NasLR are three, so they should come before, HPI coils are five, this are the ones ... etc ...), but I don't know any exact information ... I strongly doubt that there is anywhere in the fiff file, or in the sucked-via-mne header such an info ... I'll try to look again in the "paper-based" manuals (but I know them ~by heart, there's nothing :-( ) and I can try to explicitly ask Elekta for that info, if it's not an industrial secret ... Going back to my problem, if you can help also off the bugzilla is fine, I wanted to try to look at the function you said, and I manually "streamed" some data containing cHPI data from one Matlab session to the next one in the following way cfg.source.dataset = whatever fiff ... cfg.speed = 1 ft_realtime_fileproxy(cfg) and this fills in a buffer on localhost:1972 as expected On another Matlab, I fire: cfg.coilfreq= 293 ft_realtime_coillocalizer(cfg) and it fails with: Reference to non-existent field 'grad'. Error in ft_realtime_coillocalizer (line 134) [vol, sens] = ft_prepare_vol_sens([], hdr.grad, 'channel', cfg.channel); I tried to specify what is what, i.e. cfg.coilfreq= 293 cfg.headerformat = 'fcdc_buffer_offline' ft_realtime_coillocalizer(cfg) and this seems to complain of something else, namely: Warning: could not read header from buffer:/header, retrying in 1 second > In ft_read_header at 951 In ft_realtime_coillocalizer at 95 Any snipplet/hint, also off the list/bugzilla, would be appreciated ... In the meantime I try to figure out the rest ... Best, GP Best wishes, Arjen </p>

Arjen Stolk - 2013-04-10 20:34:40 +0200

"As a matter of fact I/we don't know any order ... we're trying to follow an order, also when mounting them, like "the first one on the connector, it's the first one on the left side" but we never followed a strict rule, since the Elekta SW never complained for any order, it detects the relative distance and spits out some number independent from the order ..." Ok, thanks. I'll see whether we can come up with a solution on how match a frequency to a coil number. Currently we have implemented a 'rigidbody' type constraint in 'dipole_fit.m' which generates the hypothetical magnetic field distribution of all coils combined, based on their relative positions as obtained from the fif header. The actual positions and orientations of the coils making up this rigid body are then approximated by fitting the resulting hypothetical field distribution to the actually recorded magnetic field distribution. This method should improve fitting of the coils as compared to fitting them separately. Note that these functions have not yet been uploaded to the main repository as they are work-in-progress and also because we have not yet tested them for compatibility with other functions. Also, the here uploaded ft_realtime_coillocalizer is currently an outdated version. For offline (on an already recorded dataset) and online testing of the realtime neuromag interface I suggest you have a look at these pages: http://fieldtrip.fcdonders.nl/development/realtime/neuromag http://fieldtrip.fcdonders.nl/example/ft_realtime_signalviewer Thanks for your quick reply. Currently I am writing up my thesis work, but I will come back to you asap. Arjen


Gianpaolo Demarchi - 2013-04-10 21:37:58 +0200

(In reply to comment #23) >Ok, thanks. I'll see whether we can come up with a solution on how match a > frequency to a coil number. Thanks ... as said, I'm going to ask Elekta, so we should have "good info" asap ... hopefully ... > Note that these functions have not yet been uploaded to the main repository as > they are work-in-progress and also because we have not yet tested them for > compatibility with other functions. Also, the here uploaded > ft_realtime_coillocalizer is currently an outdated version. For offline (on an > already recorded dataset) and online testing of the realtime neuromag interface > suggest you have a look at these pages: > http://fieldtrip.fcdonders.nl/development/realtime/neuromag > http://fieldtrip.fcdonders.nl/example/ft_realtime_signalviewer This works flawlessly. We've done some BCI stuff last year based on that, which worked out pretty well. I just tested ft_realtime_signalviewer (offline, with ft_rt_fileproxy) and still works without any problem. That's why I was asking what was the issue with ft_rt_coillocalizer, but you're right, it's pointless that I fight with an already outdated version, so I'll wait for you providing a new one, as soon as think it's fine for an alpha/beta testing ... > Thanks for your quick reply. Sorry again for my erratic behavior (quick, slow, quick, slow) :-( ! > Currently I am writing up my thesis work, but I > will come back to you asap. Then go and fight with that, forget this crap ;-) ! GP


Arjen Stolk - 2013-04-14 18:35:11 +0200

Created attachment 450 neuromag coilpos sample_chpi.fif


Arjen Stolk - 2013-04-14 18:38:21 +0200

Hi GP, Playing a bit more with the example dataset ('sample_chpi.fif'), I still remain confused. I have plotted the coil positions as obtained from the neuromag header (slide 1 of 'neuromag_coilpos_sample.pdf'), their resulting simulated magnetic fields (slide 2), and the actual recorded magnetic fields per coil frequency (slide 3). Note that the coil identities (i.e. '1', '2', ..) do not match the order of the coil frequencies (i.e. '293', '307', ..). However, ignoring this order for the moment, I believe to see quite some overlap between the coil positions and topographical distribution of the recorded fields. For instance; coil 1: 321 Hz coil 2: 314 Hz coil 3: 293 Hz ?? coil 4: 293 Hz ?? coil 5: 307/328 Hz ?? As you can tell from those question marks, there is no match for all coils. It is as if one coil (either the 307 or 328 Hz) is not at the correct location as registered with polhemus... Do you have any clue? Yours, Arjen p.s. find below the code used to create those plots: % read header file dataset = '/home/common/matlab/fieldtrip/data/test/bug1792/sample_chpi.fif'; hdr = ft_read_header(dataset); % plot sensor positions sens = ft_read_sens(dataset); figure; ft_plot_sens(sens) % plot HPI coil positions ctr = 0; for j = 1:length(hdr.orig.raw.info.dig) if hdr.orig.raw.info.dig(1,j).kind == 2 % 1: RPA/LPA/NAS, 2: HPI coils, 4: Head shape ctr = ctr+1; pos(ctr,:) = double((hdr.orig.raw.info.dig(1,j).r).*100); % coil position in cm ident(ctr) = hdr.orig.raw.info.dig(1,j).ident; % coil identity end end fprintf('%d HPI coils found in fif header\n', ctr); for c = 1:ctr hold on; plot3(pos(c,1), pos(c,2), pos(c,3), 'ro', ‘MarkerSize’, 12, ’LineWidth’, 3); hold on; text(pos(c,1), pos(c,2), pos(c,3), num2str(ident(c))); end xlabel(‘x-axis’) ylabel(‘y-axis’) %% THIS PERTAINS TO FICTITIOUS DATA % construct volume conductor model (simple sphere) vol = []; vol.r = 9; vol.o = [0 0 4]; channel = ft_channelselection('MEGMAG', sens.label); [vol, sens] = ft_prepare_vol_sens(vol, sens, 'channel', channel); % construct lead field matrix for all ‘dipoles’ (i.e. coils) lf = ft_compute_leadfield(pos, sens, vol); % plot lead field along x-axis for each coil figure; hold on; cfg =[]; cfg.layout = 'neuromag306mag.lay'; temp.dimord = ‘chan’; temp.label = channel ; subplot(2,3,1); hold on; temp.avg = lf(:,1); cfg.comment = num2str(ident(1)); ft_topoplotER(cfg, temp); subplot(2,3,2); hold on; temp.avg = lf(:,4); cfg.comment = num2str(ident(2)); ft_topoplotER(cfg, temp); subplot(2,3,3); hold on; temp.avg = lf(:,7); cfg.comment = num2str(ident(3)); ft_topoplotER(cfg, temp); subplot(2,3,4); hold on; temp.avg = lf(:,10); cfg.comment = num2str(ident(4)); ft_topoplotER(cfg, temp); subplot(2,3,5); hold on; temp.avg = lf(:,13); cfg.comment = num2str(ident(5)); ft_topoplotER(cfg, temp); %% THIS PERTAINS TO ACTUAL DATA % define trials for analysis (in this 6 consecutive trials of one second) offset = 3; % seconds begsample = ([0 1 2 3 4 5]+offset) * hdr.Fs+1; endsample = begsample + hdr.Fs-1; % preprocess the trials cfg = []; cfg.trl = [begsample(:) endsample(:)]; cfg.trl(:,3) = 0; cfg.dataset = dataset; cfg.channel = 'MEGMAG'; data = ft_preprocessing(cfg); % determine spectral content cfg = []; cfg.method = 'mtmfft'; cfg.output = 'pow'; cfg.foilim = [1 500]; cfg.taper = 'hanning'; freq = ft_freqanalysis(cfg, data); % plot topographical distribution of neuromag coil frequencies figure; hold on; cfg = []; cfg.layout = 'neuromag306mag.lay'; subplot(2,3,1); hold on; cfg.xlim = [293 293]; cfg.comment = ‘293 Hz’; ft_topoplotER(cfg, freq); subplot(2,3,2); hold on; cfg.xlim = [307 307]; cfg.comment = ‘307 Hz’; ft_topoplotER(cfg, freq); subplot(2,3,3); hold on; cfg.xlim = [314 314]; cfg.comment = ‘314 Hz’; ft_topoplotER(cfg, freq); subplot(2,3,4); hold on; cfg.xlim = [321 321]; cfg.comment = ‘321 Hz’; ft_topoplotER(cfg, freq); subplot(2,3,5); hold on; cfg.xlim = [328 328]; cfg.comment = ‘328 Hz’; ft_topoplotER(cfg, freq);


Arjen Stolk - 2013-04-15 17:20:07 +0200

Created attachment 452 neuromag coilpos matteo_chpi.fif


Arjen Stolk - 2013-04-15 17:26:31 +0200

Hi GP, I have added a similar analysis pdf file for another neuromag recording you have previously sent me (matteo_cHPI.fif). The polhemus tracked coil positions look similar to that of sample_chpi.fif (see first slide of both pdf files). However, also here, the recorded magnetic field distributions for each frequency do not make sense to me (even worse than in sample_chpi.fif, cf. third slide of both pdf files). Just to check; are the polhemus tracked coil positions, as stored in the fif header file (and plotted in the first slide of the pdfs), what you would expect? Yours, Arjen


Gianpaolo Demarchi - 2013-04-15 19:04:17 +0200

Created attachment 453 Log info of the fiff file


Gianpaolo Demarchi - 2013-04-15 19:06:10 +0200

(In reply to comment #26) > Hi GP, > Playing a bit more with the example dataset ('sample_chpi.fif'), I still remain > confused. Me the same :-( > Note that the coil identities (i.e. '1', '2', ..) do not match the order of the > coil frequencies (i.e. '293', '307', ..). However, ignoring this order for the > moment, I believe to see quite some overlap between the coil positions and > topographical distribution of the recorded fields. For instance; I tested the script you sent me on the same data, and on another dataset. So, we can forget of the order of the coils somehow ... The order stored in the hdr.orig.dig.* does only reflect how they were digitized, not how they're energized from the MEG electronics ... Per se is not a bad thing, just we've to find a way to cope with that. I looked at the PSD of the data, and on the topography "movie" with cfg=[]; cfg.xlim = [291:2:329]; ft_topoplotER(cfg, freq); and it really seems that there are only four coils/frequency available: there are only four clearly detectable peaks in the spectrum, and in the topolot movie the last one (328) overlaps with the 307 one, with also some spurious other data popping up from the other three coils/positions. There are small peaks at 250 and 300 Hz, but those are clearly 50Hz harmonics, also from the topography. There's an elekta tool, called show_fiff, that tells you some relevant info on the fiff file you're playing with. I ran it on our file, and attacched you'll find the log, with a lot of info ... most of them are picked up by by fiff->mne->ft pipeline, and end up in the hdr "orig" structure, but not all of them ... E.g. [meg@sinuhe development]$ /neuro/bin/util/show_fiff -v sample_chpi_short.fif (see the log attached) You can choose a meaningful "tag" that you're interested in, passing it in the following way [meg@sinuhe development]$ /neuro/bin/util/show_fiff -vt 216 sample_chpi_short.fif 216 = HPI # coils 5 So you see that there were five hpi coils (really ?!) And: [meg@sinuhe development]$ /neuro/bin/util/show_fiff -vt 245 sample_chpi_short.fif 245 = HPI coil no 1 245 = HPI coil no 2 245 = HPI coil no 3 245 = HPI coil no 4 245 = HPI coil no 5 with the corresponding frequencies: [meg@sinuhe development]$ /neuro/bin/util/show_fiff -vt 236 sample_chpi_short.fif 236 = HPI coil freq 293 236 = HPI coil freq 307 236 = HPI coil freq 314 236 = HPI coil freq 321 236 = HPI coil freq 328 The problems arise from the fact that this order is always the same, i.e. from low to high freqs, and it's not necessarily (I guess) related to the Polhemus digitized points and order. But, if I then look at another "tag" (or simply I look at the whole log with "| grep dig." ) I get out [meg@sinuhe development]$ /neuro/bin/util/show_fiff -vt 213 sample_chpi_short.fif 213 = dig. point hpi 1 ( 27.5, 100.7, 2.6) 213 = dig. point hpi 2 ( 70.2, -16.5, -26.8) 213 = dig. point hpi 3 ( -47.2, 95.5, 6.9) 213 = dig. point hpi 4 ( -68.1, -28.2, -29.6) 213 = dig. point hpi 5 ( 67.6, -23.6, -27.3) 213 = dig. point cardinal 1 ( -61.0, 0.0, 0.0) 213 = dig. point cardinal 2 ( -0.0, 91.7, 0.0) 213 = dig. point cardinal 3 ( 65.3, -0.0, 0.0) 213 = dig. point hpi 1 ( -65.3, -26.1, 7.3) 213 = dig. point hpi 2 ( -41.3, 91.2, 51.4) 213 = dig. point hpi 3 ( 33.9, 95.1, 48.0) 213 = dig. point hpi 4 ( 36.7, 91.8, 31.9) 213 = dig. point hpi 5 ( 71.6, -22.1, 13.1) 213 = dig. point extra 1 ( -10.7, 96.5, 72.3) 213 = dig. point extra 2 ( -12.1, 94.9, 74.2) (and all the other extra points) So, the first points are the hpi coils in device (?!) coordinates, then the landmarks, then the same hpi points in head (?!) coordinates, which are incidentally the ones that we're getting out from hdr.orig.dig(1,4:8).r ans = -0.0653 -0.0261 0.0073 ans = -0.0413 0.0912 0.0514 ans = 0.0339 0.0951 0.0480 ans = 0.0367 0.0918 0.0319 ans = 0.0716 -0.0221 0.0131 So, in the end it really seems that there is a 1-1, 2-2 etc. mapping with the frequency AND coil number, but it's not what we have in the very end. So, from left to right they should be (1,2,3,4,5) -> (293,307,314,321,328) and instead we see (321, 314, 293, ???, 307/328/??? ). So, someone in our machinery is definitely lying ;-) > Do you have any clue? I tell you the very truth, I'm a bit lost as well. As said, part of the info I'm getting out from the show_fiff function goes into hdr.orig.* , and part of it is wasted ... In principle one could try to recover it also in Matlab/fieldtrip via: [fid tree dir] = fiff_open(dataset) and all the info in literally "buried" in the dir and tree "tag" structure ... and I cannot easily get them out from there .... but as said they seem to lie ... I'm trying to think of a workaround ... Something like ... Let's forget what are the position stored in the header info; we could try to fit three dipoles on three coils (independent, maybe with some user input choosing in the beginning which ones) at the beginning of each run, and then measure the relative movement only with respect to this initial position ... but, again, this is just brainstorming and maybe it's better that I have some rest now :-( Ciao, GP, depressed > Yours, > Arjen


Gianpaolo Demarchi - 2013-04-15 19:13:48 +0200

(In reply to comment #28) Sorry we were overlapping our replies ;-) Btw, the fact that two coils are closed together it's not a bad thing, since it's how they are mounted in reality: the original idea was that since the frontal ones are the ones more likely to fall down, having two close to each other was better ... But I'm rethinking this thing now ... maybe we've just to mount them far apart and stop ... Again, maybe we've just to select three of them, which should be enough to fit a rigid body, and forget about correspondences with what is stored in the header/polhemus ... Goedenavond, Gianpaolo


Arjen Stolk - 2013-04-15 22:03:42 +0200

Hi GP, Thanks again for your quick and adequate reply. I feel we're really getting closer now. "[meg@sinuhe development]$ /neuro/bin/util/show_fiff -vt 213 sample_chpi_short.fif 213 = dig. point hpi 1 ( 27.5, 100.7, 2.6) 213 = dig. point hpi 2 ( 70.2, -16.5, -26.8) 213 = dig. point hpi 3 ( -47.2, 95.5, 6.9) 213 = dig. point hpi 4 ( -68.1, -28.2, -29.6) 213 = dig. point hpi 5 ( 67.6, -23.6, -27.3) 213 = dig. point cardinal 1 ( -61.0, 0.0, 0.0) 213 = dig. point cardinal 2 ( -0.0, 91.7, 0.0) 213 = dig. point cardinal 3 ( 65.3, -0.0, 0.0) 213 = dig. point hpi 1 ( -65.3, -26.1, 7.3) 213 = dig. point hpi 2 ( -41.3, 91.2, 51.4) 213 = dig. point hpi 3 ( 33.9, 95.1, 48.0) 213 = dig. point hpi 4 ( 36.7, 91.8, 31.9) 213 = dig. point hpi 5 ( 71.6, -22.1, 13.1) 213 = dig. point extra 1 ( -10.7, 96.5, 72.3) 213 = dig. point extra 2 ( -12.1, 94.9, 74.2) (and all the other extra points) So, the first points are the hpi coils in device (?!) coordinates, then the landmarks, then the same hpi points in head (?!) coordinates, which are incidentally the ones that we're getting out from hdr.orig.dig(1,4:8).r " I plotted these positions. Will attach now..


Arjen Stolk - 2013-04-15 22:04:11 +0200

Created attachment 454 neuromag coilpos sample_chpi.fif part 2


Arjen Stolk - 2013-04-15 22:06:20 +0200

(In reply to comment #33) What can be seen, is that what you define as 'head coordinate system' matches perfectly to the topoplots. In fact, the identity number matches the order of coil frequencies too.


Arjen Stolk - 2013-04-15 22:11:18 +0200

Created attachment 455 neuromag coilpos sample_chpi.fif part 2 Have been mixing them up. "device coordinates" in blue, "head coordinates" in red.


Arjen Stolk - 2013-04-15 22:23:47 +0200

So the topoplots match (perfectly) the "device coordinates"/first 5 positions of the coils. The "head coordinates"/second 5 coil positions match the coordinate system of the sensor positions, i.e. the two closely located coil positions are at the front of the head. I will try and discuss this with Robert over a cup of coffee asap. Useful link: http://fieldtrip.fcdonders.nl/faq/how_are_the_different_head_and_mri_coordinate_systems_defined Code used to generate those plots: % plot sensor positions dataset = '/home/common/matlab/fieldtrip/data/test/bug1792/sample_chpi.fif'; hdr = ft_read_header(dataset); sens = ft_read_sens(dataset); % HPI coil positions (polhemus/device coordinates?) pos_d(1,:)=[27.5, 100.7, 2.6]; pos_d(2,:)=[70.2, -16.5, -26.8]; pos_d(3,:)=[-47.2, 95.5, 6.9]; pos_d(4,:)=[-68.1, -28.2, -29.6]; pos_d(5,:)=[67.6, -23.6, -27.3]; pos_d = pos_d/10; % display figure; hold on; % display subplot(2,2,1); hold on; ft_plot_sens(sens) for c = 1:5 hold on; plot3(pos_d(c,1), pos_d(c,2), pos_d(c,3), 'bo', 'MarkerSize', 12, 'LineWidth', 3); hold on; text(pos_d(c,1), pos_d(c,2), pos_d(c,3), num2str(c)); end xlabel('x-axis') ylabel('y-axis') title('device coord?'); view([0 90]) % display subplot(2,2,3); hold on; ft_plot_sens(sens) for c = 1:5 hold on; plot3(pos_d(c,1), pos_d(c,2), pos_d(c,3), 'bo', 'MarkerSize', 12, 'LineWidth', 3); hold on; text(pos_d(c,1), pos_d(c,2), pos_d(c,3), num2str(c)); end xlabel('x-axis') ylabel('y-axis') title('device coord?'); view([0 0]) % HPI coil positions (head coordinates?) pos_h(1,:)=[-65.3, -26.1, 7.3]; pos_h(2,:)=[-41.3, 91.2, 51.4]; pos_h(3,:)=[33.9, 95.1, 48.0]; pos_h(4,:)=[36.7, 91.8, 31.9]; pos_h(5,:)=[71.6, -22.1, 13.19]; pos_h = pos_h/10; % display subplot(2,2,2); hold on; ft_plot_sens(sens) for c = 1:5 hold on; plot3(pos_h(c,1), pos_h(c,2), pos_h(c,3), 'ro', 'MarkerSize', 12, 'LineWidth', 3); hold on; text(pos_h(c,1), pos_h(c,2), pos_h(c,3), num2str(c)); end xlabel('x-axis') ylabel('y-axis') title('head coord?'); view([0 90]) % display subplot(2,2,4); hold on; ft_plot_sens(sens) for c = 1:5 hold on; plot3(pos_h(c,1), pos_h(c,2), pos_h(c,3), 'ro', 'MarkerSize', 12, 'LineWidth', 3); hold on; text(pos_h(c,1), pos_h(c,2), pos_h(c,3), num2str(c)); end xlabel('x-axis') ylabel('y-axis') title('head coord?'); view([0 0])


Gianpaolo Demarchi - 2013-04-16 12:00:47 +0200

(In reply to comment #36) Great! I tested everything on another file, and there are still a couple of things I'd like to slowly sort out. a) The "5 coils", the one thats should fire at 328 Hz, indeed seems to be never active, in the sense that if we look at the 328 topography we do see a coil popping up somewhere (where the 2nd/3rd or whatever is), but the amplitude is much lower (10^-27 vs 10^-21 of the really active ones). So, to me, either the 328 frequency is fed into another coil at much lower intensity, or one of the other active coils has some spurious activity at 328 Hz. I'm investigating it right now (namely, check whether all the coils are active), since we changed recently the acquisition console b) It's still not clear to me in which reference frame we are playing ... At least we've to cope with "polhemus", "head" and "device" ... So I'll try to sort them out ... b) Still, I didn't manage to get out the "hpi" (namely, the two coordinate sets of the coils) info from the fiff_read() function, instead of passing from the show_fiff utility, which is Elekta only and we would like to stick to fieldtrip/matlab as much as possible .... Anyway, there is some light at the end of the tunnel .... Best, GP


Arjen Stolk - 2013-04-16 12:34:24 +0200

After having coffee with Robert and checking the MaxFilter documentation, it seems that the difference in coil positions are not simply due to a different coordinate system (device vs. head). In fact, both are right-handed Cartesian coordinate systems. The direction of x-axis is from left to right, that of y-axis to the front, and the z-axis points up. The relatively small difference between coordinate systems therefore cannot explain the large difference we observe between those coil positions. Comparing again the actual MEG data (the topoplots) and the polhemus tracked positions (in agreement with what you mention: the two closely located coils are supposed to be at the front of the head), it seems as if something has gone wrong. The first "hpi" coordinate set is in line with the actual data, and perhaps this was an initial guess on the coil positions made by the neuromag system/software. You correctly mentioned that one of the coils (328 hz one) has a relatively weak signal. Perhaps we should try a new recording with 5 clearly defined positions of those coils (a photograph would also help). For instance, 1 above each eye, 1 above the nose, and 1 at each mastoid (5 coils in total). What do you think?


Gianpaolo Demarchi - 2013-04-19 10:09:39 +0200

(In reply to comment #38) Dear Arjen, tried to sneak in a quick measurement yesterday ... > After having coffee with Robert and checking the MaxFilter documentation, it not too helpful, though ... > seems that the difference in coil positions are not simply due to a different > coordinate system (device vs. head). I just "shot" in the mess ... I tried to tinker with "trans" matrices without too much success, then I came to the same conclusion ... > In fact, both are right-handed Cartesian > coordinate systems. The direction of x-axis is from left to right, that of > y-axis to the front, and the z-axis points up. ... which is the Neuromag coordinate system, with the origin set in between LPA/RPA ... > The relatively small difference > between coordinate systems therefore cannot explain the large difference we > observe between those coil positions. Ok ... > Comparing again the actual MEG data (the topoplots) and the polhemus tracked > positions (in agreement with what you mention: the two closely located coils > are supposed to be at the front of the head), it seems as if something has gone > wrong. The first "hpi" coordinate set is in line with the actual data, and > perhaps this was an initial guess on the coil positions made by the neuromag > system/software. Then, if this is the case, they should be practically the same. The Acquisition software pushes you to redo the hpi measurement in the beginning until all of the fitted coils are within 5 mm from the polhemus data. This is done only once (i.e. at the beginning of the measurement, not twice like other sw/hw) and then you've the choice either to start the continuous hpi tracking, feeding in the ~300 Hz current, on going on as it is, and hoping that the subject doesn't move too much ... > You correctly mentioned that one of the coils (328 hz one) has a relatively > weak signal. Perhaps we should try a new recording with 5 clearly defined > positions of those coils (a photograph would also help). For instance, 1 above > each eye, 1 above the nose, and 1 at each mastoid (5 coils in total). What do > you think? Done. You can find all the files here, with the anonymized (;-)) version of the pictures. https://www.dropbox.com/sh/tnlo25g2qrduo95/JoSglN9uBf This time I was there checking what is what. As for all the measurements first we acquired the landmarks (pseudoLPA/RPA, N). Then there are the 5 localization coils, acquired in a "right" order, i.e. the first coil on the connector is the first coil digitized, and gets 293 Hz current (topi-checked), and so forth ... We put them on according to the Elekta bible, so as high as possible to stay in the helmet, but not on the hair ... Looking at the topoplots we see the the coils "fit" the pictures. Despite all my efforts in tinkering on the console I dind't manage to energize the 5th coil with the supposed 328 Hz. So this one either picks up some noise from a nearby friend, but definitely it's not behaving as expected. This is not a problem per se: the default Elekta setup is 4 coils (the idea is 3 for a reference frame, plus a spare one if one falls apart), and since we had problems in the past with some measurements, we decided to put on another extra coil, maybe in Italy people sweats more ... But again, I think if we stick to 4 coils only, we still will fit the needs of 95% of the Neuromag users. So, I think we're not too far away ... Practically speaking we could: 1) Do the dipoles fit only on the four "really" active coils from the fieldtrip side, and stick to using four coils only for our side ... when they'll come for the next maintenance I'll try to guess what's wrong with the 328Hz with them ... 2) Try to find a way to suck the hpi positions (also the "guessed" one) from the fiff "dir/tree" information. Part of the relevant info (the digitized one) end up the hdr.orig structure, but some part of if is read via fiff_open and discarded, and I'm really lost in struct hierarchy that this function spits out ... Best, Gp PS: the hpi coils info as per /neuro/bin/util/show_fiff 213 = dig. point hpi 1 ( -77.7, -26.3, -44.5) 213 = dig. point hpi 2 ( -66.5, 58.4, -21.3) 213 = dig. point hpi 3 ( 18.8, 106.8, -6.2) 213 = dig. point hpi 4 ( 63.8, 52.3, -24.2) 213 = dig. point hpi 5 ( -80.7, -17.8, -42.5) 213 = dig. point cardinal 1 ( -74.6, -0.0, 0.0) 213 = dig. point cardinal 2 ( -0.0, 104.9, 0.0) 213 = dig. point cardinal 3 ( 72.6, 0.0, 0.0) 213 = dig. point hpi 1 ( -79.1, -31.1, 4.4) 213 = dig. point hpi 2 ( -67.0, 54.0, 24.9) 213 = dig. point hpi 3 ( 20.6, 101.8, 39.9) 213 = dig. point hpi 4 ( 65.6, 44.4, 22.6) 213 = dig. point hpi 5 ( 73.4, -30.9, -2.3)


Arjen Stolk - 2013-04-25 13:21:12 +0200

Created attachment 462 neuromag coilpos test_chpi.fif


Arjen Stolk - 2013-04-25 13:21:37 +0200

Created attachment 463 neuromag coilpos test photos


Arjen Stolk - 2013-04-25 13:28:34 +0200

Nice work, GP. I have uploaded the results involving similar plots as for the other datasets. It seems indeed Italians sweat at 328 Hz. I will have a go with your suggestions; dipolefitting the 4 coils (293, 307, 314, and 321 Hz), and then see whether we really need to those "guessed" positions (assuming they are).


Arjen Stolk - 2013-04-25 13:52:21 +0200

Created attachment 464 neuromag coilpos test animation It's preliminary, but my enthusiasm could not withhold me from sending you this. It's starting to make much more sense now. :)


Arjen Stolk - 2013-04-25 14:56:45 +0200

Created attachment 465 neuromag coilpos test animation rigidbody constraint


Gianpaolo Demarchi - 2013-04-25 18:55:50 +0200

Dear Arjen, great news! I think we're quite close ... Sadly today it's our "liberation day", and as you can expect from the italian style, we're all on holiday and the university will be closed till Monday ;-) So I don't have any chances of testing it, if the case ... But I'll do it on Monday right away ... Regarding the 328 Hz coil, I guess it's a problem of our system, and I'm planning to take a closer look to that issue during the next yearly maintenance round, in the summer ... I would rather go by now with four coils (which should suffice for fitting a solid object, like my head ;-)), keeping the option (like cfg.ncoils=5) to use the fifth one in the future, or for the other Neuromag labs ... Best, GP


Arjen Stolk - 2013-04-26 10:39:35 +0200

Dear GP, Thanks for your quick reply. We are getting close indeed. I'll try to work on an improved implementation today but won't be able to upload all the files to the newest FT version within two weeks. So enjoy your holidays. :) The 328 Hz coil seems indeed a consistent problem, at least for your MEG setup. Would be nice, although not crucial for the moment, to have it working (again). Currently, the FT scripts will allow you to specify the coilfrequencies, and thus, the number of coils. Keep you posted! Yours, Arjen


Gianpaolo Demarchi - 2013-04-26 11:17:35 +0200

(In reply to comment #46) Ciao Arjen, > Thanks for your quick reply. We are getting close indeed. I'll try to work on > an improved implementation today but won't be able to upload all the files to > the newest FT version within two weeks. So enjoy your holidays. :) If you want, and if you manage, let's try to finish it sooner ... If you've some alpha/beta version that you want me to to test send it right away via email/bugzilla, so I can give it a quick shot next week ... Probably in a couple of weeks I won't be in the lab anymore, and I'll be off for some time (days, weeks ... a baby is coming ;-) ). Best, GP


Arjen Stolk - 2013-04-26 19:33:40 +0200

Created attachment 470 dewar vs head coordinates % neuromag dewar vs head dataset = '/home/common/matlab/fieldtrip/data/test/bug1792/20130418_test_cHPI.fif'; % cfg.coilfreq = [293, 307, 314, 321]; hdr = ft_read_header(dataset,'headerformat','neuromag_mne'); % sensors grad_h = hdr.grad; grad_d = mne2grad(hdr, 'dewar'); figure; hold on; ft_plot_sens(grad_h,'style','.b'); hold on; ft_plot_sens(grad_d,'style','.r'); % digitizer points for j=1:4 shape_h(j,:) = hdr.orig.dig(j+3).r*100; end hold on; % note that the headposition coils in dewar space are in hdr.orig.dir(4:7) plot3(shape_h(1:4,1),shape_h(1:4,2),shape_h(1:4,3),'bo', 'MarkerSize', 12); shape_d = ft_read_headshape(dataset,'coordinates','dewar'); hold on; % note that the headposition coils in dewar space are in shape.pnt(1:4,:) plot3(shape_d.pnt(1:4,1),shape_d.pnt(1:4,2),shape_d.pnt(1:4,3),'ro', 'MarkerSize', 12);


Arjen Stolk - 2013-04-26 20:07:39 +0200

Some additional notes: Since the sensor positions in dewar space are consistent, we'll have to use dewar space coordinates for the realtime head localizer. Copied some documentation from the CTF to the neuromag page: http://fieldtrip.fcdonders.nl/getting_started/realtime_headlocalizer_neuromag BTW, congrats with your expectations of the baby! I will soon/tomorrow try to provide a zip file with the more up-to-date version (with respect to the neuromag head localizer).Hence, why the example code will not yet work.


Arjen Stolk - 2013-04-27 00:25:56 +0200

Hi GP, Created some pages that will hopefully successfully help users to use our neuromag head localizer. Feel free to adjust/add where needed. http://fieldtrip.fcdonders.nl/getting_started/realtime_headlocalizer_neuromag http://fieldtrip.fcdonders.nl/faq/how_can_i_visualize_the_neuromag_head_position_indicator_coils I'll work on the code a bit more, and will try to send you a working copy asap. Best, Arjen


Arjen Stolk - 2013-04-29 11:34:26 +0200

Hi GP, The coil localization seems to work offline here. I am very curious whether it works online in your lab as well! Can you download the fieldtrip package from here? It's a temporary version that I still need to integrate with the svn/online version. But for testing purposes, let's have a go with this one. https://github.com/StolkArjen/fieldtrip/tree/bug1792 As further outlined here: http://fieldtrip.fcdonders.nl/getting_started/realtime_headlocalizer_neuromag You'll need to run this on the acquisition pc: $HOME/fieldtrip/realtime/src/acquisition/neuromag/neuromag2ft And this on the visualization pc (can be the same pc): addpath ~/fieldtrip addpath ~/fieldtrip/realtime/online_meg ft_defaults cfg = []; cfg.dataset = 'buffer://hostname:1972'; cfg.coilfreq = [293, 307, 314, 321]; % note I have dropped the 328 Hz one ft_realtime_coillocalizer(cfg) I am still working on some GUI issues involved in ft_realtime_HEADlocalizer. ft_realtime_COILlocalizer does not have a GUI and works pretty well here.


Gianpaolo Demarchi - 2013-04-29 11:51:32 +0200

(In reply to comment #51) Hi Arjen, > The coil localization seems to work offline here. I am very curious whether it > works online in your lab as well! I'm slowly downloading it right now ... I think I'll manage to test it tomorrow ... > Can you download the fieldtrip package from here? It's a temporary version that > I still need to integrate with the svn/online version. But for testing > purposes, let's have a go with this one. I tried to test with my standard ft version, and I got stuck already at a wrong mne2grad version, so I gave up ... > You'll need to run this on the acquisition pc: > $HOME/fieldtrip/realtime/src/acquisition/neuromag/neuromag2ft Yep ... indeed, before doing BCI stuff last year, I tried to test it with the CTF headlocalizer right away ... obiouvsly it didn't work, but sparkled the original idea to adapt it to the Elekta machines as well ... I'll add some comment on the wiki ASAP, namely that there are different versions of this function in the bin folder (HP-UX and linux), and depending on which people should get only one binary ... > I am still working on some GUI issues involved in ft_realtime_HEADlocalizer. >ft_realtime_COILlocalizer does not have a GUI and works pretty well here. I'll come back as soon as I've tested it ... Ciao, GP


Arjen Stolk - 2013-04-29 12:06:00 +0200

Ok, thanks! Keeping my fingers crossed. :)


Robert Oostenveld - 2013-06-28 12:43:07 +0200

I merged the changes related to bug 1114, 2209, 1961 and 1792 into the svn repository see http://code.google.com/p/fieldtrip/source/detail?r=8285 for bug 1792 this does not mean that all issues are resolved, the merge of the code is merely to clean up my git todo list for the holiday.


Gianpaolo Demarchi - 2013-07-02 12:29:00 +0200

(In reply to comment #53) Ok, slowly back from my father leisure time ... The main problem I had to run the realtime/buffer pipeline was due to a silly firewall that Elekta decided to introduce in the new Linux console wrt the old Unix one. Now, opening the relevant ports, this part seems to work fine, in the sense that finally I can both run sine2ft on the acquisition console and strem to a bufferViewer* anywhere else in the network, and if I start the neuromag2ft server I can finally see all my data coming with ft_realtime_signalviewer in Matlab ... It took some time, but now I'm back to where I was one and a half a year ago, finally ;-) So, this works flawlessly: cfg = []; cfg.dataset = 'buffer://192.168.185.142:1972'; ft_realtime_signalviewer(cfg) obviously dominated by the triggers channels but choosing some magnetometers, cfg.channel = [1:3:10] ft_realtime_signalviewer(cfg) shows me very well the cars passing by ... BUT, running cfg = []; cfg.dataset = 'buffer://192.168.185.142:1972'; cfg.coilfreq = [293, 307, 314, 321]; % note I have dropped the 328 Hz one ft_realtime_coillocalizer(cfg) miserably fails with the following error: Reference to non-existent field 'grad'. Error in ft_realtime_coillocalizer (line 134) [vol, sens] = ft_prepare_vol_sens([], hdr.grad, 'channel', cfg.channel); So, the grad info is lost in the buffer transfer, since hdr = ft_read_header(cfg.dataset) hdr = Fs: 1000 nChans: 319 nSamples: 574000 nSamplesPre: 0 nTrials: 1 orig: [1x1 struct] label: {319x1 cell} chantype: {319x1 cell} chanunit: {319x1 cell} has clearly no grad structure left over ... You (Arjen) solved it for a local fiff file using hdr = ft_read_header(cfg.dataset,'headerformat','neuromag_mne'); which takes care, with mne2grad, of the grad story ... Sadly fiff_open doesn't know how to handle the buffer itself ... hdr = ft_read_header(cfg.dataset,'headerformat','neuromag_mne'); Error using fiff_open (line 49) Cannot open file buffer://192.168.185.142:1972 Error in fiff_read_meas_info (line 82) [ fid, tree ] = fiff_open(source); Error in ft_read_header (line 1249) orig = fiff_read_meas_info(filename); As an additional info, I tried both using the fieldtrip-bug1792 version you provided, and the current one git-fetched right now. Matlab is the newest 2013a, no other problems with that so far ... So, how to "carry over" the grad info in the buffer?! Is neuromag2ft.c that should take of it? Thanks in advance for any hint ... Best, GP * For the binaries in the bin folder ... The newest Elekta console seems to be "too new" / "too old" / "too different" and the binaries provided with fieldtrip "miss" some *.so libraries. But after installing some -devel libraries, the make runs smooth, and you end up with all the needed libs/bins ..


Arjen Stolk - 2013-07-02 12:40:17 +0200

Hi GP, congrats again and nice to hear from you again. "cfg = []; cfg.dataset = 'buffer://192.168.185.142:1972'; ft_realtime_signalviewer(cfg)" Great to see this low level mechanism now works! "cfg = []; cfg.dataset = 'buffer://192.168.185.142:1972'; cfg.coilfreq = [293, 307, 314, 321]; % note I have dropped the 328 Hz one ft_realtime_coillocalizer(cfg) Reference to non-existent field 'grad'. Error in ft_realtime_coillocalizer (line 134) [vol, sens] = ft_prepare_vol_sens([], hdr.grad, 'channel', cfg.channel);" I remember we have had and fixed the same online issue with acq2ft, ctf version of neuromag2ft. Most likely we haven't implemented the same fix for neuromag2ft.c yet: I will see whether we can fix this. Keep you posted.


Arjen Stolk - 2013-07-29 16:39:22 +0200

Hi GP, I have finally incorporated all the neuromag head localizer material into the latest version of FT. The online access to the grad info is still not implement, but I have created a workaround for the moment ('cfg.gradfile'). Could you try the following? cfg = []; cfg.dataset = 'buffer://hostname:1972'; cfg.coilfreq = [293, 307, 314, 321]; % note I have dropped the 328 Hz one cfg.gradfile = XXX.fif; % point to an already existing dataset for grad field ft_realtime_coillocalizer(cfg) Yours, Arjen


Arjen Stolk - 2013-07-29 16:55:54 +0200

(In reply to comment #57) Oops, not coillocalizer, but headlocalizer: cfg = []; cfg.dataset = 'buffer://hostname:1972'; cfg.coilfreq = [293, 307, 314, 321]; % note I have dropped the 328 Hz one cfg.gradfile = XXX.fif; % point to an already existing dataset for grad field ft_realtime_headlocalizer(cfg)


Gianpaolo Demarchi - 2013-07-30 12:25:06 +0200

(In reply to comment #58) Dear Arjen, I tested both the "svn" and the "git" version, just to be sure that I'm on the latest version, and in both cases (checked manually that they both contain you cfg.grad hack commit) it simply doesn't work ... :-( The error is the usual one, i.e. Reference to non-existent field 'grad'. Error in ft_realtime_headlocalizer (line 74) isneuromag = ft_senstype(hdr.grad, 'neuromag'); and the problem is that ft_senstype kicks in to check the hdr.grad *before* you create it later with if isfield(cfg,'gradfile'); temp = ft_read_header(cfg.gradfile, 'coordsys', 'dewar'); hdr.grad = temp.grad; end at line 145. I tried to move this hack before the ft_senstype, i.e. to line 74, and this part is solved, but then you get another error: Error using ft_read_header (line 187) dewar coordinates are sofar only supported for CTF data Error in ft_realtime_headlocalizer (line 75) temp = ft_read_header(cfg.gradfile, 'coordsys', 'dewar'); so, I think this is something else to fix, in the ft_read_header this time ... and I don't want to spoil also that :-( ! Ciao, GP


Arjen Stolk - 2013-07-30 12:55:33 +0200

Hi GP, Thanks for testing this out. You're right that I had overlooked that ft_senstype was also trying to parse hdr.grad, so I have moved the cfg.gradfile lines upstream, like you did. I see ft_read_header with coordsys 'dewar' is forced to cause an error by ft_read_header: % the support for head/dewar coordinates is still limited if strcmp(coordsys, 'dewar') && ~any(strcmp(headerformat, {'fcdc_buffer', 'ctf_ds', 'ctf_meg4', 'ctf_res4', 'neuromag_fif', 'neuromag_mne', 'babysquid_fif'})) error('dewar coordinates are not supported for %s', headerformat); end I wonder why. Keep you posted.


Arjen Stolk - 2013-07-30 13:00:07 +0200

Btw, I wonder whether you are using the most current version when that ft_read_header is thrown. Reading the error specification again; it is only to given an error when the user wants dewar coordinates for systems other than ctf and neuromag. So I am guessing it should work when you having moved up that cfg.gradfile code?


Robert Oostenveld - 2013-07-30 13:11:05 +0200

Hi guys, is it an idea to install teamviewer on the computer that will do the realtime analysis and have Arjen look along (and control the keyboard and mouse)? You could also install teamviewer on a windows computer and then use a vncserver+vncviewer to connect to a linux computer. Arjen then would be controling the linux computer through the vncviewer. And then have skype running simultaneously, so that you can work on it together. Robert


Arjen Stolk - 2013-07-30 13:17:01 +0200

That'd be great weren't that there's currently one month left for my thesis. I think we're quite close now though to get this thing running at least.


Robert Oostenveld - 2013-07-30 16:03:41 +0200

(In reply to comment #63) Precisely: since you only have 1 month left, I suggest you quickly look over Gianpaolo's shoulder rather than continue to spend time on emailing back and forth. With teamviewer it ain't more difficult than inhouse at the donders with vnc.


Robert Oostenveld - 2013-08-02 11:45:48 +0200

Let me move the discussion back from the email thread to bugzilla for future reference and to keep everyone posted. On 2 Aug 2013, at 10:54, Demarchi, Gianpaolo wrote: > In principle I can turn the MEG on, without the SQUID part, just to see > if we can record and stream something, but without the "magnetic" > measurement of the coils positions is a tad pointless … sorry :-( If this were to work, i.e. if the software does not fail with warm squids, it would be very helpful to test the fif chunck (which is to be passed from neuromag2ft to the buffer). I could go ahead and make some changes to neuromag2ft.c to the process_tag.c file), you would recompile and run it, a (debug) file is created on disk which we could analyze, and then we'd know whether it would work as we presently assume. Subsequently we could implement the final version with the fif_chunck in the buffer.


Gianpaolo Demarchi - 2013-08-02 11:57:38 +0200

(In reply to comment #65) >Let me move the discussion back from the email thread to bugzilla for future > reference and to keep everyone posted. Sorry, my fault ... I'm too lazy to login and use the web interface, emailing is faster ... > On 2 Aug 2013, at 10:54, Demarchi, Gianpaolo wrote: >> In principle I can turn the MEG on, without the SQUID part, just to see >> if we can record and stream something, but without the "magnetic" >> measurement of the coils positions is a tad pointless … sorry :-( > If this were to work, i.e. if the software does not fail with warm squids, it > would be very helpful to test the fif chunck (which is to be passed from > neuromag2ft to the buffer). This was the idea ... I'll test this on Monday now, but if I keep the preamp off, and if I do the acquisition without any MEG/EEG channel, only with some technical tracks, it *could* be that the "fif" header and data file is correctly created and sent to the shared memory, so the neuromag2ft can suck it ... Again, this is a guesstimate, no grants, but in principle I don't see why it should fail ;-) > I could go ahead and make some changes to neuromag2ft.c to the process_tag.c > file), you would recompile and run it, yes ... > a (debug) file is created on disk which > we could analyze, and then we'd know whether it would work as we presently > assume. yes ... > Subsequently we could implement the final version with the fif_chunck > in the buffer. Ok, I'll keep you posted asap I know whether those dirty tricks work or not ... Ciao, GP


Robert Oostenveld - 2013-08-02 12:15:18 +0200

(In reply to comment #66) I made some small code cleanups. mac001> svn commit *.c *.h Sending neuromag2ft.c Sending process_data.c Sending process_tag.c Transmitting file data ... Committed revision 8372.


Robert Oostenveld - 2013-08-02 12:52:31 +0200

(In reply to comment #66) I now also added a piece of code that opens the file "neuromag2ft.fif" in the present working directory and streams all relevant blocks to it. If you are able to recompile and create the file, we could have a look at its content. Hopefully it can be read with the MNE reading functions that underly ft_read_header. If so, then we can use the same strategy that we use for the res4 CTF header file (i.e. copy the file to the buffer as chunk, write it to disk on the other end, decipher it using the standard reading functions). mac001> svn commit process_tag.c Sending process_tag.c Transmitting file data . Committed revision 8373.


Gianpaolo Demarchi - 2013-08-05 10:13:40 +0200

(In reply to comment #68) Dear all, sadly the trick didn't work ... despite I only try to acquire non MEG channels, the thing wants to setup the HPI measurement anyway, which fails since there are no real MEG channels, because the "powering" part of the SQUIDs is off ... setu ... 412-Perhaps no connection to MEG front-end electronics: Failed to close HPI coil switches: Janitor-MEG: Command 'set hpi coil5 1' causes: Failed: Board in slot 249 is not present or initialized I've seen the relevant piece of code in the process_tag.c, and managed to compile the new neuromag2ft flawlessly, and runs also fine ... neuromag2ft (130805 09:50:42) About to connect to the Neuromag DACQ shared memory on this workstation (client ID 14013)... neuromag2ft (130805 09:50:42) Connection ok neuromag2ft (130805 09:50:42) Current buffer length value = 1500 neuromag2ft (130805 09:50:42) FieldTrip buffer server thread started (TID 1087502656) neuromag2ft (130805 09:50:42) Will scale up MEG mags by 1, grads by 1 and EEG data by 1 neuromag2ft (130805 09:50:42) Waiting for the measurement to start... Press Ctrl-C to terminate this program Sadly there's nobody feeding in data on the other side of the buffer :-( Anyway, I'll resurrect the thread as soon as I've the MEG back to business, i.e. less than one month ... Thanks again! Best, Gianpaolo


Stephen Whitmarsh - 2013-09-05 14:29:38 +0200

Dear all, We just recorded out first human at NatMEG - the new MEG lab at Karolinska, Stockholm. Making online head localization via FT possible is on our priority list. Please let me know if I can help in any way. Best wishes, Stephen


Arjen Stolk - 2013-09-05 15:01:18 +0200

great, have a look at this page to get yourself set-up. :) http://fieldtrip.fcdonders.nl/getting_started/realtime_headlocalizer (btw, it seems this page it not linked anymore from the getting started page?)


Gianpaolo Demarchi - 2013-09-10 12:59:30 +0200

(In reply to comment #68) Hi all, finally we're back to business after the MEG maintenance. I tried briefly the new hack, without much success ... [meg@sinuhe x86_64-pc-linux-gnu]$ ./neuromag2ft neuromag2ft (130910 12:15:05) About to connect to the Neuromag DACQ shared memory on this workstation (client ID 14013)... neuromag2ft (130910 12:15:05) Connection ok neuromag2ft (130910 12:15:05) Current buffer length value = 1500 neuromag2ft (130910 12:15:05) FieldTrip buffer server thread started (TID 1101257024) neuromag2ft (130910 12:15:05) Will scale up MEG mags by 1, grads by 1 and EEG data by 1 neuromag2ft (130910 12:15:05) Waiting for the measurement to start... Press Ctrl-C to terminate this program neuromag2ft (130910 12:15:17) Opened file /neuro/dacq/raw/dacqZNSSUp. neuromag2ft.fif: No such file or directory neuromag2ft.fif: No such file or directory neuromag2ft (130910 12:15:17) New measurement is starting... neuromag2ft.fif: No such file or directory neuromag2ft.fif: No such file or directory neuromag2ft.fif: No such file or directory .... (a lot of these lines ) .... neuromag2ft.fif: No such file or directory neuromag2ft (130910 12:15:17) Data buffers coming soon... neuromag2ft (130910 12:15:17) Creating a header: 309 channels, sampling rate 1000 Hz neuromag2ft (130910 12:15:17) Header sent to the FieldTrip buffer neuromag2ft.fif: No such file or directory neuromag2ft.fif: No such file or directory neuromag2ft (130910 12:15:56) Measurement ended (36 buffers). neuromag2ft (130910 12:15:56) File closed (FIFF_CLOSE_FILE). neuromag2ft.fif: No such file or directory neuromag2ft (130910 12:15:56) File closed. neuromag2ft (130910 12:16:04) Terminated by the user neuromag2ft (130910 12:16:04) About to disconnect from Neuromag data server... neuromag2ft (130910 12:16:04) Connection closed. neuromag2ft (130910 12:16:04) Neuromag data server: Disconnected neuromag2ft (130910 12:16:04) About to disconnect from / terminate the FieldTrip buffer neuromag2ft (130910 12:16:04) FieldTrip buffer thread cancelled neuromag2ft (130910 12:16:04) Exiting So, for some reason, it cannot create the neuromag2ft.fif file. I even tried to 'touch neuromag2ft.fif' and see whether it was filled by the neuromag2ft, but the filesize was always zero, during streaming and after quitting the program. The data streaming, on the other hand, still works ... ft_signalviewer was showing me some data on another machine ... And yes, I tried both with the August version of neuromag2ft, then I did a svn update, and recompiled everything, and the same result happens with the version of today. And yes, I tried both as meg user, and root, just in case of wrong permissions in the directory ... Any further hint and piece of code to test is more than welcome ... If needed in the next days I can setup a teamviewer session, and you can control my own laptop and fight ... To Stephen: try to setup the online streaming part, and when this is done, I don't think that Elekta bothered changing the fiff specs with the new Triux machine, and the rest should work the same as with my Vectorview machine (or at least I hope ;-)) Best, GP


Robert Oostenveld - 2013-09-10 13:13:09 +0200

(In reply to comment #72) around line 197 in process_tag.c there is perror("neuromag2ft.fif"); which is the cause for the errors. It means that the file to which I am trying to write the incoming header information was not opened. Could you change line 191 from ft_chunck_neuromag_fif = fopen("neuromag2ft.fif", "rb"); into ft_chunck_neuromag_fif = fopen("/tmp/neuromag2ft.fif", "rb"); That should be a location the program is allowed to write. Or add another explicit path location where you know it should work.


Gianpaolo Demarchi - 2013-09-11 13:11:21 +0200

Created attachment 514 neuromag2ft.fif example


Gianpaolo Demarchi - 2013-09-11 13:13:05 +0200

Created attachment 515 neuromag2ft.fif old


Gianpaolo Demarchi - 2013-09-11 13:13:36 +0200

(In reply to comment #73) Here we go ... I initially only changed the place where the data live, but in the the main problem, according to my rusty c programming, was that the file should be opened for writing and not for reading ... So I changed the line ft_chunck_neuromag_fif = fopen("neuromag2ft.fif", "rb"); to ft_chunck_neuromag_fif = fopen("neuromag2ft.fif", "w+b"); This created finally a file, which doesn't look to be a genuine fiff file, i.e. [meg@sinuhe x86_64-pc-linux-gnu]$ /opt/neuromag/bin/util/show_fiff neuromag2ft.fif File neuromag2ft.fif does not start properly! But if you just cat/more/less it, you see there's MEG stuff in .. probably is not properly closed at the end when I do ctrl-c. Eyeballing, it looks like the data stream is not properly terminated and/or not containing any data (from the small size), and the fiff info tree not built ... Anyway, this is the log, w signalviewer working properly on another computer: [meg@sinuhe x86_64-pc-linux-gnu]$ ./neuromag2ft neuromag2ft (130911 12:42:02) About to connect to the Neuromag DACQ shared memory on this workstation (client ID 14013)... neuromag2ft (130911 12:42:02) Connection ok neuromag2ft (130911 12:42:02) Current buffer length value = 1500 neuromag2ft (130911 12:42:02) FieldTrip buffer server thread started (TID 1111767360) neuromag2ft (130911 12:42:02) Will scale up MEG mags by 1, grads by 1 and EEG data by 1 neuromag2ft (130911 12:42:02) Waiting for the measurement to start... Press Ctrl-C to terminate this program neuromag2ft (130911 12:42:12) Opened file /neuro/dacq/raw/dacqSDBAKK. neuromag2ft (130911 12:42:12) New measurement is starting... neuromag2ft (130911 12:42:12) Data buffers coming soon... neuromag2ft (130911 12:42:12) Creating a header: 309 channels, sampling rate 1000 Hz neuromag2ft (130911 12:42:12) Header sent to the FieldTrip buffer neuromag2ft (130911 12:43:48) Terminated by the user neuromag2ft (130911 12:43:48) About to disconnect from Neuromag data server... neuromag2ft (130911 12:43:48) Connection closed. neuromag2ft (130911 12:43:48) Neuromag data server: Disconnected neuromag2ft (130911 12:43:48) About to disconnect from / terminate the FieldTrip buffer neuromag2ft (130911 12:43:48) FieldTrip buffer thread cancelled neuromag2ft (130911 12:43:48) Exiting My C is too old now, but it seems as if it never reaches this part in the process_tag.c case FIFF_CLOSE_FILE : dacq_log("File closed.\n"); break; since I cannot find this line never in the log ... EDIT: Never mind, I was wrong, if I save the acquired file instead of discarding it, I get the proper neuromag2ft (130911 12:49:54) Measurement ended (25 buffers). neuromag2ft (130911 12:49:54) File closed (FIFF_CLOSE_FILE). neuromag2ft (130911 12:49:54) File closed. but the file is still tiny and not fiff-compliant ... BTW, I also get a 'segment fault' once in a while ... I should redscorver I do debug c stuff :-) File(s) attached anyway ... G.


Arjen Stolk - 2013-09-17 10:59:37 +0200

Hi GP & Stephen, Ideally, that file is readable by "fiff_read_meas_info" (/external/mne) which is called by ft_read_header. Can you try reading it with either one of those functions? Alternatively, please have a go at the file with a snippet of code Robert created (see below). What we want, is header information regarding the digitized head coil position indicators and gradiometers. Yours, Arjen function decode_fiff(filename) fid = fopen(filename, 'rb', 'ieee-be'); while ~feof(fid) kind = fread(fid, 1, 'int32=>int32'); type = fread(fid, 1, 'int32=>int32'); size = fread(fid, 1, 'int32=>int32'); next = fread(fid, 1, 'int32=>int32'); if next<0 break end data = fread(fid, size, 'uint8=>uint8'); disp([kind type size next]); end fclose(fid)


Gianpaolo Demarchi - 2013-09-17 12:53:39 +0200

(In reply to comment #77) Dr. Stolk, welcome back! Here we go ... As expected 'fiff_read_meas_info' doesn't like the badly formatted fiff file I'm trying to inject (as much as Elekta's own show_fiff): >> fileName='neuromag2ft.fif' fileName = neuromag2ft.fif >> fiff_read_meas_info(fileName) Error using fiff_open (line 56) file does not start with a file id tag Error in fiff_read_meas_info (line 82) [ fid, tree ] = fiff_open(source); The snipplets you sent 'works', being somehow more low level: >> decode_fiff(fileName) 16777216 167772160 436207616 0 ans = 0 but I cannot judge how sense it makes :-( Best, GP


Robert Oostenveld - 2013-09-17 12:55:07 +0200

(In reply to comment #78) regarding >> fiff_read_meas_info(fileName) Error using fiff_open (line 56) file does not start with a file id tag it might be possible to prepend a file-id tag.


Arjen Stolk - 2013-09-24 11:43:35 +0200

(In reply to comment #78) Thanks, GP, but unfortunately I'm still occupied for another short period. Quickly debugging from what you wrote, it seems that information is being chunked by neuromag2ft (as desired, hopefully containing relevant information). However, it also seems 'fiff_read_meas_info' needs more than that chunk alone to read the file correctly. Could you try and compare a real fiff file with the one created by neuromag2ft (using that decoding mscript) and see if anything's missing (perhaps that file id-tag?)? Robert pointed me to a list of definitions of the objects in a fiff file that may come in handy: e.g. those library files (fiff_types.h, etc) in fieldtrip/realtime/src/acquisition/neuromag/include Yours, arjen


Arjen Stolk - 2013-10-04 16:57:03 +0200

With the thesis just handed in today, I had a quick look and compared neuromag datasets on basis of their structure with our neuromag2ft chunk. It seems indeed a file-id tag is missing ([100 31 20 0] to be precise). I will have a look whether adding one does the trick for us. Keep you posted. Arjen


Robert Oostenveld - 2013-10-22 09:41:30 +0200

Arjen has made a lot of progress over the last few days. I have just added the basic infrastructure to the ft_read_header function, which will allow the processing of the neuromag_fif chunk when present. Please note that the actual fif chunk still needs to be added to the fieldtrip buffer and to the neuromag2ft executable. mac001> svn commit Sending fileio/ft_read_header.m Adding fileio/private/decode_fif.m Sending fileio/private/decode_nifti1.m Sending fileio/private/decode_res4.m Transmitting file data .... Committed revision 8618.


Robert Oostenveld - 2013-10-22 10:25:49 +0200

I have made changes to the buffer source, defining the neuromag_fif buffer (with fixed code 8) and implementing it the same as for the ctf case. I also updated teh neuromag2ft code: mac001> svn commit process_tag.c Sending process_tag.c Transmitting file data . Committed revision 8621. It now writes the two additional tags. to the (temporary) fif file. The fif headerfile is not yet copied to the fieldtrip buffer. I suggest compiling and testing it once more on a real neuromag MEG system before we move on and write the fif headerfile content to the buffer.


Gianpaolo Demarchi - 2013-10-22 11:24:24 +0200

(In reply to comment #83) Hi, quickly ... [meg@sinuhe neuromag]$ make gcc -g -Wall -I ../../buffer/src -I ./include -I ./include/dacq_rel5up -c neuromag2ft.c process_data.c process_tag.c process_tag.c: In function ‘send_header_to_FT’: process_tag.c:120: warning: assignment makes pointer from integer without a cast process_tag.c: In function ‘process_tag’: process_tag.c:191: error: expected expression before ‘<<’ token process_tag.c:349: error: expected declaration or statement at end of input process_tag.c:189: warning: unused variable ‘buf’ process_tag.c:188: warning: unused variable ‘ch’ process_tag.c:187: warning: unused variable ‘c’ process_tag.c:186: warning: unused variable ‘block_kind’ process_tag.c:349: warning: control reaches end of non-void function make: *** [neuromag2ft.o] Error 1 I tried to take a look at the code, but my 'C' karma is too rusty to spot a non obvious error probably ... If you wish we can continue debugging off the list, and come back later when those small things are sorted ... GP PS: and yes, I've the latest revision [meg@sinuhe fieldtrip]$ svn update At revision 8621.


Robert Oostenveld - 2013-10-22 11:59:25 +0200

(In reply to comment #84) I hope I fixed them just now. It now compiles on my linux computer (sorry, I should have tested before).


Gianpaolo Demarchi - 2013-10-22 14:51:49 +0200

(In reply to comment #85) Now it compiles ... Still, neuromag2ft.fif looks "incomplete" to ft_read_header.m/fiff_read_meas_info and friends, but I didn't get fully whether this was meant to work or not .... G.


Arjen Stolk - 2013-10-22 15:06:44 +0200

(In reply to comment #86) Hey GP, do you have that new neuromag2ft.fif file for me? I'll check whether it is what we expected.


Gianpaolo Demarchi - 2013-10-22 15:18:54 +0200

(In reply to comment #87) Yes, sorry ... I made different versions (different opening/closing of the ACQ software), but from the size they're the same, so I'll upload only few of them ... GP


Gianpaolo Demarchi - 2013-10-22 15:19:45 +0200

Created attachment 533 neuromag2ft.fif again


Gianpaolo Demarchi - 2013-10-22 15:20:47 +0200

Created attachment 534 neuromag2ft.fif - just different order of opening/closing


Arjen Stolk - 2013-10-22 23:09:17 +0200

(In reply to comment #90) Great, thanks. Quick attempt: It seems we're able to readily process this chunk using existing mne toolbox code (and a slightly modified fiff_open - little endian). I'll have a go at proceed with further tests/steps tomorrow. addpath /home/action/arjsto/fieldtrip-svn/external/mne cd /home/action/arjsto/fieldtrip-svn/fileio/private [fid, tree] = fiff_open_le('/home/action/arjsto/Headloc/neuromag2ft.fif'); orig = fiff_read_meas_info(fid, tree) Read a total of 8 projection items: grad3v_alustava.fif : PCA-v1 (1 x 306) idle grad3v_alustava.fif : PCA-v2 (1 x 306) idle grad3v_alustava.fif : PCA-v3 (1 x 306) idle mag5v_alustava.fif : PCA-v1 (1 x 306) idle mag5v_alustava.fif : PCA-v2 (1 x 306) idle mag5v_alustava.fif : PCA-v3 (1 x 306) idle mag5v_alustava.fif : PCA-v4 (1 x 306) idle mag5v_alustava.fif : PCA-v5 (1 x 306) idle orig = file_id: [1x1 struct] meas_id: [1x1 struct] meas_date: [2x1 int32] nchan: 309 sfreq: 1000 highpass: 0.1000 lowpass: 330 chs: [1x309 struct] ch_names: {1x309 cell} dev_head_t: [] ctf_head_t: [] dev_ctf_t: [] dig: [0x0 struct] bads: [] projs: [1x8 struct] comps: [0x0 struct] acq_pars: [] acq_stim: []


Gianpaolo Demarchi - 2013-10-23 12:22:23 +0200

(In reply to comment #91) Great news! Looks really that all the info is in place (apart from obvious stuff missing, since it was a empty room without coils etc ...). Tell me when you're ready for prime time, that I give a shot with all the things in, including a brain ;-) Best, GP


Robert Oostenveld - 2013-10-23 17:28:19 +0200

I added the neuromag fif headerfile chunk to the realtime data stream, recompiled on linux. lets keep our thumbs crossed and hope it now all comes together! roboos@mentat001> svn commit Sending neuromag/bin/x86_64-pc-linux-gnu/neuromag2ft Sending neuromag/process_tag.c Transmitting file data .. Committed revision 8629.


Arjen Stolk - 2013-10-23 21:24:29 +0200

(In reply to comment #93) Great! Almost there. We'll probably face another set of small bugs, but let's have a try at it, GP. :D


Gianpaolo Demarchi - 2013-10-24 11:27:45 +0200

(In reply to comment #93) Almost there ... I think ... Firstly, I assume your linux is different than the dacq machine, since: [meg@sinuhe x86_64-pc-linux-gnu]$ ./neuromag2ft ./neuromag2ft: /lib64/libc.so.6: version `GLIBC_2.7' not found (required by ./neuromag2ft) so I recompiled it ... no problem. Then, running the thing: [meg@sinuhe x86_64-pc-linux-gnu]$ ./neuromag2ft neuromag2ft (131024 09:54:21) About to connect to the Neuromag DACQ shared memory on this workstation (client ID 14013)... neuromag2ft (131024 09:54:21) Connection ok neuromag2ft (131024 09:54:21) Current buffer length value = 1500 neuromag2ft (131024 09:54:21) FieldTrip buffer server thread started (TID 1100998976) neuromag2ft (131024 09:54:21) Will scale up MEG mags by 1, grads by 1 and EEG data by 1 neuromag2ft (131024 09:54:21) Waiting for the measurement to start... Press Ctrl-C to terminate this program neuromag2ft (131024 09:54:42) Opened file /neuro/dacq/raw/dacqOJHMpk. neuromag2ft (131024 09:54:42) New measurement is starting... neuromag2ft (131024 09:54:42) Data buffers coming soon... neuromag2ft (131024 09:54:42) Creating a header: 309 channels, sampling rate 1000 Hz neuromag2ft (131024 09:54:42) Failed to open the file with the fif header information fopen: Success neuromag2ft (131024 09:54:42) Header sent to the FieldTrip buffer neuromag2ft (131024 09:54:53) Measurement ended (9 buffers). neuromag2ft (131024 09:54:53) File closed (FIFF_CLOSE_FILE). neuromag2ft (131024 09:54:53) File closed. neuromag2ft (131024 09:55:04) Terminated by the user neuromag2ft (131024 09:55:04) About to disconnect from Neuromag data server... neuromag2ft (131024 09:55:04) Connection closed. neuromag2ft (131024 09:55:04) Neuromag data server: Disconnected neuromag2ft (131024 09:55:04) About to disconnect from / terminate the FieldTrip buffer neuromag2ft (131024 09:55:04) FieldTrip buffer thread cancelled neuromag2ft (131024 09:55:04) Exiting I dunno whether this is an expected behavior, since the neuromag2ft.fif is indeed created ... The error comes from process_tag.c ~line 155, but eyeballing since this part happens after the fopen part , and since the file is indeed created, this part throws always an error then if(headerfile != NULL) { dacq_log("Failed to open the file with the fif header information\n", numbytes); perror("fopen"); } so probably it should be if(headerfile == NULL) ... If I say b*shit, take everything that I say as early morning rants ;-) Anyway, I include also the tiny neuromag2ft.fif BTW, streaming of data *still* works, signaviewer on the mac shows me some data ;-) Your faithful alpha tester, GP


Gianpaolo Demarchi - 2013-10-24 11:30:29 +0200

Created attachment 535 neuromag2ft.fif - another one bites the dust


Arjen Stolk - 2013-10-24 12:27:34 +0200

>> addpath /home/action/arjsto/fieldtrip-svn/external/mne cd /home/action/arjsto/fieldtrip-svn/fileio/private >> [fid, tree] = fiff_open_le('/home/action/arjsto/Headloc/neuromag2ft.fif'); orig = fiff_read_meas_info(fid, tree) Error using fiff_open_le (line 58) file does not start with a file id tag and using decode_fiff.m (attached), it seems that this file is what it used to be. >> [tag] = decode_fiff('neuromag2ft.fif') tag = 1x5 struct array with fields: kind type size next data >> tag(1) ans = kind: 9 type: 0 size: 0 next: 0 data: [] >> tag(2) ans = kind: 105 type: 3 size: 4 next: 0 data: [4x1 double] >> tag(3) ans = kind: 105 type: 3 size: 4 next: 0 data: [4x1 double] >> tag(4) ans = kind: 2 type: 0 size: 0 next: 0 data: [] >> tag(5) ans = kind: [] type: [] size: [] next: [] data: []


Arjen Stolk - 2013-10-24 12:28:26 +0200

Created attachment 536 decode_fiff: reads the tags and data of a fif file


Arjen Stolk - 2013-10-24 12:29:45 +0200

(In reply to comment #97) I meant it is NOT like what it is used to be.


Gianpaolo Demarchi - 2013-10-24 13:55:41 +0200

(In reply to comment #99) Ok, now I see it's working also for me, with the right "decoding" ... Please watch out the potential conflicting/confusing file names of the new decode_fiff and fileio/private/decode_fif.m ;-) GP


Arjen Stolk - 2013-10-24 14:01:00 +0200

(In reply to comment #100) :) Checking why the updated process_tag.c (in /realtime/src/acquisition/neuromag/) suddenly is writing this rather incomplete fif file. Previously, the file-id tag was nicely added to the beginning of the file, while now it's missing.


Robert Oostenveld - 2013-10-25 11:29:14 +0200

Sorry for my sloppy c-programming. I have resolved some issues with the fif headerfile, fixed some actual bugs, changed the flow of the code to make the channel names chunk and the neuromag_fif chunk more consistent, the present version should allow for starting neuromag2ft onde and sending the fif header file information multiple times, updating the networked FT buffer. roboos@mentat001> svn commit Sending neuromag/bin/x86_64-pc-linux-gnu/neuromag2ft Sending neuromag/process_tag.c Transmitting file data .. Committed revision 8638.


Arjen Stolk - 2013-10-25 11:41:35 +0200

(In reply to comment #102) Happy testing, GP. :D


Gianpaolo Demarchi - 2013-10-25 11:49:49 +0200

(In reply to comment #103) I was already compiling and testing ;-) By accident I svn-updated a couple of mins after you did the last commit, and I was checking online the diff ... I'll let you know asap ;-) G.


Gianpaolo Demarchi - 2013-10-25 13:58:38 +0200

(In reply to comment #103) Here I am ... So, first of all we should emphasize in the future wiki page that we've absolutely to start first ./neuromag2ft and then the acquisition software, otherwise this could lead to unpredictable outcomes (i.e. neuromag2ft segfaulting and/or acquisition getting stuck after exactly 10 secs, then everything afterwards flushed on the screen when you kill neuromag2ft). Then, more on topic, despite the promising logs of the program neuromag2ft (131025 13:45:05) About to connect to the Neuromag DACQ shared memory on this workstation (client ID 14013)... neuromag2ft (131025 13:45:05) Connection ok neuromag2ft (131025 13:45:05) Current buffer length value = 1500 neuromag2ft (131025 13:45:05) FieldTrip buffer server thread started (TID 1095293248) neuromag2ft (131025 13:45:05) Will scale up MEG mags by 1, grads by 1 and EEG data by 1 neuromag2ft (131025 13:45:05) Waiting for the measurement to start... Press Ctrl-C to terminate this program neuromag2ft (131025 13:45:11) Opened file /neuro/dacq/raw/dacq4qZSVy. neuromag2ft (131025 13:45:11) New measurement is starting... neuromag2ft (131025 13:45:11) Data buffers coming soon... neuromag2ft (131025 13:45:11) Creating a header: 309 channels, sampling rate 1000 Hz neuromag2ft (131025 13:45:11) Appended 2469 bytes with channel name information neuromag2ft (131025 13:45:11) Appended 66367 bytes with fif header information neuromag2ft (131025 13:45:11) Header sent to the FieldTrip buffer neuromag2ft (131025 13:45:57) Terminated by the user neuromag2ft (131025 13:45:57) About to disconnect from Neuromag data server... neuromag2ft (131025 13:45:57) Connection closed. neuromag2ft (131025 13:45:57) Neuromag data server: Disconnected neuromag2ft (131025 13:45:57) About to disconnect from / terminate the FieldTrip buffer neuromag2ft (131025 13:45:57) FieldTrip buffer thread cancelled neuromag2ft (131025 13:45:57) Exiting about appended additional info, if you try to read the buffer it "only" contains MEG data, and no additional relevant info (e.g. dig and grad stuff). Namely: >> hdr = ft_read_header('buffer://192.168.185.142:1972') hdr = Fs: 1000 nChans: 309 nSamples: 142000 nSamplesPre: 0 nTrials: 1 orig: [1x1 struct] label: {309x1 cell} chantype: {309x1 cell} chanunit: {309x1 cell} >> hdr.orig ans = bufsize: 68852 which is incidentally 16 bits less than the info appended, 66367 + 2469, but no dig/grad whatsoever ... Your faithful alpha tester, Gianpaolo PS: as of today I get a threatening warning from fieldtrip about using 2013a Warning: You are using MATLAB 2013a. FieldTrip is currently not supported on 2013a (8.1) or newer. Using your current MATLAB version can lead to unexpected behaviour, which might not be easily noticable. Continuing is not advised. Shall I be worried, for the debugging? In principle I can try to use another machine, but I didn't have any problem with 2013a so far ...


Robert Oostenveld - 2013-10-25 14:36:29 +0200

(In reply to comment #105) you know best where to document it, so I suggest you simply go ahead and update it according to your insights. None of us has any hands-on experience with the neuromag scanner. neuromag2ft segfaulting is not good :-( but hopefully we can confirm that the communication works. The memory problem should be solved at a later time. Could you start it, and prior to stopping copy the /tmp/neuromag2ff.fif file to another location (and attach it here). It is now cleaned when recording stops. Could you in a separate run > fieldtrip/realtime/bin/glnxa64/recording bufferdir 1972 for as short time (say 10 seconds) and send Arjen the zipped bufferdir content? It represents on disk exactly the content that is streamed to the buffer, and with "playback" it should be possible for us to look at it in detail. Regarding the matlab2013a warning, please see http://bugzilla.fcdonders.nl/show_bug.cgi?id=2095#c13 It is just an extra warning, nothing functionally changed, so if it worked for you in the past, there is no reason to change. But there are known issues with 2013a, so please beware.


Gianpaolo Demarchi - 2013-10-25 16:45:31 +0200

(In reply to comment #106) > neuromag2ft segfaulting is not good :-( > but hopefully we can confirm that the communication works. The memory problem > should be solved at a later time. Yep ... > Could you start it, and prior to stopping copy the /tmp/neuromag2ff.fif file to > another location (and attach it here). It is now cleaned when recording stops. Done (I'll upload next ...) > Could you in a separate run > fieldtrip/realtime/bin/glnxa64/recording bufferdir 1972 > for as short time (say 10 seconds) and send Arjen the zipped bufferdir content? > It represents on disk exactly the content that is streamed to the buffer, and > with "playback" it should be possible for us to look at it in detail. I tried various combinations of running recording with and without neuromag2ft running (with it complains of the address already in use), but the folder is always empty, apart from contents.txt. What am I doing wrong?! This should plug into neuromag2ft, isn't?! And if so, why complaining of the address already in use and not filling the bufferdir with 001 subdirs, or whatever ... ?! :-( > Regarding the matlab2013a warning, please see > http://bugzilla.fcdonders.nl/show_bug.cgi?id=2095#c13 I saw it, I was just worried to do something nasty in the debugging now ;-) > It is just an extra warning, nothing functionally changed, so if it worked for > you in the past, there is no reason to change. But there are known issues with > 2013a, so please beware. Yes, I know the EEGLAB warnings and the dmlt stuff, I just wanted to stay on the safe side ... I'll test further on Monday, but as said now I'm stuck with recording ... not recording :-( G.


Gianpaolo Demarchi - 2013-10-25 16:46:35 +0200

Created attachment 541 neuromag2ft.fif - freshly baked ....


Arjen Stolk - 2013-10-28 09:25:44 +0100

(In reply to comment #108) Freshy baked file seems to be ok: >> addpath /home/action/arjsto/fieldtrip-svn/external/mne >> cd /home/action/arjsto/fieldtrip-svn/fileio/private >> [fid, tree] = fiff_open_le('/home/action/arjsto/Headloc/neuromag2ft.fif'); >> orig = fiff_read_meas_info(fid, tree) Read a total of 8 projection items: grad3v_ssp_upr.fif : PCA-v1 (1 x 306) idle grad3v_ssp_upr.fif : PCA-v2 (1 x 306) idle grad3v_ssp_upr.fif : PCA-v3 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v1 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v2 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v3 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v4 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v5 (1 x 306) idle orig = file_id: [1x1 struct] meas_id: [1x1 struct] meas_date: [2x1 int32] nchan: 309 sfreq: 1000 highpass: 0.1000 lowpass: 330 chs: [1x309 struct] ch_names: {1x309 cell} dev_head_t: [] ctf_head_t: [] dev_ctf_t: [] dig: [0x0 struct] bads: [] projs: [1x8 struct] comps: [0x0 struct] acq_pars: [] acq_stim: []


Arjen Stolk - 2013-10-28 09:39:02 +0100

(In reply to comment #109) ">> hdr.orig ans = bufsize: 68852 " It might be that the matlab end of the buffer stream is not yet up-to-date (ft_read_header requires debugging). Alternatively, the data is not correctly appended to the buffer. Could you try whether recording works? Otherwise we'll need to setup a realtime debugging session (skype or somethign). > Could you in a separate run > fieldtrip/realtime/bin/glnxa64/recording bufferdir 1972 > for as short time (say 10 seconds) and send Arjen the zipped bufferdir content? > It represents on disk exactly the content that is streamed to the buffer, and > with "playback" it should be possible for us to look at it in detail.


Gianpaolo Demarchi - 2013-10-28 13:11:21 +0100

(In reply to comment #110) Dear all, sorry for the late reply, but I was deeply testing ;-) So, first with the the good news ... In the buffer there is life ! ... ehm ... a hdr.neuromag_fif field ;-) The main problem was that I needed a mac binary, since the "remote" console now is my mac ... I know you'll come with all the right binaries in the future ;-) Anyway, I had a problem compiling for the mac ... Since I'm now on 10.9 I had to change the mexopts.sh accordingly, but then, for some strange reason (changes in the API?!) running compile.m gave the following errore (maybe I should open another bug later): >> compile Compiling library functions in util.c ... Compiling library functions in printstruct.c ... Compiling library functions in clientrequest.c ... Compiling library functions in tcprequest.c ... Compiling helper functions in buffer_putevt.c ... buffer_putevt.c:125:16: error: non-void function 'buffer_putevt' should return a value [-Wreturn-type] if (Nev == 0) return; ^ 1 error generated. mex: compile of ' "buffer_putevt.c"' failed. Error using mex (line 206) Unable to complete successfully. Error in compile (line 150) eval(cmd); Now, pro tempore I patched the buffer_putevt.c:125 with if (Nev == 0) return 0; just to let it compile ... I'll let you find the elegant solution ;-) With the buffer.mexmaci64 freshly compiled, there's some hope ... While if I do: hdr = ft_read_header('buffer://192.168.185.142:1972') >> hdr.orig ans = bufsize: 68852 if I manually use buffer, i.e. >> hdr = buffer('get_hdr', [],'192.168.185.142',1972) hdr = nchans: 309 nsamples: 2000 nevents: 0 fsample: 1000 data_type: 9 bufsize: 68852 channel_names: {309x1 cell} neuromag_fif: [1x66367 uint8] I finally get a lot of neuromag_fif info (hopefully the right tags). So, finally some additional info is transmitted on the network ... yay!!! The bad news is that it seems I'm too stupid to make "recording" run, that means that I've still to properly understand how it works. If I start ./neuromag2ft before recording, recording complains of address already in use (ft_start_buffer_server, bind: Address already in use), and recording stops there ... If I start recording before neuromag2ft, neuromag2ft complains about (tcpserver bind: Address already in use), the network streaming doesn't seems to work ... On the mac console I get > In ft_read_header at 1012 In ft_realtime_signalviewer at 88 (Warning: could not read header from buffer://192.168.185.142:1972, retrying in 1 second ) whereas the "bufferdir" directory from recording is never filled ... otoh I get, sometimes, strange outputs like [meg@sinuhe glnxa64]$ ./recording test001 Started new client thread with packet merging = 1 t=1382961698.003 Get header ...FAILED t=1382961699.010 Get header ...FAILED t=1382961700.012 Get header ...FAILED t=1382961701.015 Get header ...FAILED but probably this is related to the fact that sometimes neuromag2ft "freezes" the acquisition buffer, i.e. no more data is shown in the acquisition window, and you get all the data "flushed" when you ctrl-c neuromag2ft, with a lot of errors from the acq console :-( Anyway, I've to give up the lab now for real measurements ... I've tried to tinker also when someone is measuring, on Friday, but as said sometimes neuromag2ft freezes the data stream and/or seg-faults, and I spoiled one measurement block :-( I'll try further tests among the slots in the next days, any feedback is anyway more than welcome! Best, Gianpaolo </p>

Robert Oostenveld - 2013-10-28 14:05:01 +0100

(In reply to comment #109) Hi Gianpaolo thanks for the very detailed and useful report. Regarding the absence of the updated mex, sorry, my fault. I had started MATLAB already to compile, but then throught ... well, it ptobably only has to run on linux for now. I'll recompile and post on bug #2341. Regarding the error in the mex compilation. Apparently 10.9 is more strict. The reported error with the return value shall be fixed. Regarding the recording buffer. The idea is that the neuromag2ft "client" writes to the recording buffer "server". By default the client will also start its own server. Using the --bufhost and --bufport option to neuromagft should allow you to have them coexist. But since you have already passed the buffer onto MATLAB, we might want to skip this step altogether. The problems with process_tag inside neuromag2ft are more problematic. Apparently the internal logic is incorrect and it does weird memory stuff. That requires someone to go through the code once more. It would help to have faster feedback cycles, i.e. us (Arjen and me) looking/typing along on your sinuhe. Would that work? PS could you get Arjen the output of ft_read_header and of buffer itself in a mat file?


Gianpaolo Demarchi - 2013-10-28 15:47:26 +0100

(In reply to comment #112) > Regarding the recording buffer. The idea is that the neuromag2ft "client" > writes to the recording buffer "server". By default the client will also start > its own server. Using the --bufhost and --bufport option to neuromagft should > allow you to have them coexist. But since you have already passed the buffer > onto MATLAB, we might want to skip this step altogether. Ok ... > The problems with process_tag inside neuromag2ft are more problematic. > Apparently the internal logic is incorrect and it does weird memory stuff. That > requires someone to go through the code once more. It would help to have faster > feedback cycles, i.e. us (Arjen and me) looking/typing along on your sinuhe. > Would that work? In principle yes, the only problem is that I've to steal real measurement time from the lab, and not using "left overs" as I'm doing now ... Anyway, *tentatively" let's say that I can try to book the lab on Wed. morning, for tomorrow now it's a bit too late shifting things around, telling the users and subjects, etc ... if it's fine with you obviously ... I can try to let you run my mac via teamviewer, and/or I can directly let you ssh to sinuhe via a gateway machine, with my login name ... > PS could you get Arjen the output of ft_read_header and of buffer itself in a > mat file? If I manage to get a "snipplet" of the lab tomorrow, I'll do it ... now as said I'm a bit scared of tinkering while real measurements are running ... Ciao, GP


Gianpaolo Demarchi - 2013-10-29 10:11:10 +0100

(In reply to comment #112) Hi again, I'm in the lab this morning, I managed to steal some time ;-) Attached you'll find a mat file, with the output of the following commands: ftrdhdr = ft_read_header('buffer://192.168.185.142:1972') bufhdr = buffer('get_hdr', [],'192.168.185.142',1972) moreover, I'll attach some seconds of the output of "recording". It's probably useless now, but I'm quite proud I managed to make it work ;-) (self reminder: RTF --help instructions) G.


Gianpaolo Demarchi - 2013-10-29 10:12:28 +0100

Created attachment 542 Different hdr outputs of ft_read_header and pure buffer


Gianpaolo Demarchi - 2013-10-29 10:13:23 +0100

Created attachment 543 Few seconds of "recording", filled by neuromag2ft


Arjen Stolk - 2013-10-29 11:00:03 +0100

(In reply to comment #116) Thanks GP; debugging ft_read_header and decode_fif using that header info.


Arjen Stolk - 2013-10-29 11:12:01 +0100

>> cachechunk = decode_fif(bufhdr.neuromag_fif) Read a total of 8 projection items: grad3v_ssp_upr.fif : PCA-v1 (1 x 306) idle grad3v_ssp_upr.fif : PCA-v2 (1 x 306) idle grad3v_ssp_upr.fif : PCA-v3 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v1 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v2 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v3 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v4 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v5 (1 x 306) idle Warning: No device to head transform available in fif file > In fileio/private/mne2grad at 78 In fileio/private/decode_fif at 38 Warning: EEG channels will likely have coordinates in head frame, not device frame > In fileio/private/mne2grad at 79 In fileio/private/decode_fif at 38 cachechunk = grad: [1x1 struct] orig: [1x1 struct] >> cachechunk.grad ans = coilpos: [510x3 double] coilori: [510x3 double] tra: [306x510 double] unit: 'cm' label: {306x1 cell} coordsys: 'dewar' chantype: {306x1 cell} type: 'neuromag306' Ok, seems we now have grad info. :D


Arjen Stolk - 2013-10-29 11:28:43 +0100

(In reply to comment #118) The next time you try (with latest FT version), I expect hdr (after calling hdr = ft_read_header('buffer://192.168.185.142:1972') again) to contain a grad (and an orig) structure. I this is the case, then we can try and get ft_realtime_headlocalizer to work on that information. :) Without digitized points ft_realtime_headlocalizer will fail, but give it a quick shot prior to testing with a subject to see if nothing else is blocking us at this point.


Gianpaolo Demarchi - 2013-10-29 12:29:00 +0100

(In reply to comment #119) Eureka! >> hdr = ft_read_header('buffer://192.168.185.142:1972') Read a total of 8 projection items: grad3v_ssp_upr.fif : PCA-v1 (1 x 306) idle grad3v_ssp_upr.fif : PCA-v2 (1 x 306) idle grad3v_ssp_upr.fif : PCA-v3 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v1 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v2 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v3 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v4 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v5 (1 x 306) idle Warning: No device to head transform available in fif file > In fileio/private/mne2grad at 78 In fileio/private/decode_fif at 34 In ft_read_header at 1033 Warning: EEG channels will likely have coordinates in head frame, not device frame > In fileio/private/mne2grad at 79 In fileio/private/decode_fif at 34 In ft_read_header at 1033 hdr = Fs: 1000 nChans: 309 nSamples: 11000 nSamplesPre: 0 nTrials: 1 orig: [1x1 struct] grad: [1x1 struct] label: {309x1 cell} chantype: {309x1 cell} chanunit: {309x1 cell} I've digitized something random, and then put the localization coils in with some tape ... the localization is awful obviously, but just to have something to feed in ... still getting data stream stuck / segfaulting once in a while, but this is a next task ... I'll send also the new hdr ... Great!!! G.


Gianpaolo Demarchi - 2013-10-29 12:33:05 +0100

Created attachment 544 hdr with the new ft_read_header


Arjen Stolk - 2013-10-29 12:51:45 +0100

(In reply to comment #121) Great, the new hdr is promising! Are you trying out the digitized head positions, or did those segfaults prevent you from doing so?


Arjen Stolk - 2013-10-29 13:00:38 +0100

Added an update to ft_realtime_headlocalizer, making sure it calls ft_read_headshape with fileformat = 'neuromag_fif' (which otherwise will be determined to be 'fcdc_buffer') in order to analyze those digitized head positions.


Gianpaolo Demarchi - 2013-10-30 11:22:15 +0100

(In reply to comment #123) Hi, I'm trying with a digitized phantom, i.e. I have the coils, the landmarks and some head points in, but still the buffer does not contain "dig" stuff, i.e. the hdr.orig.dig is sadly empty ... >> hdr = ft_read_header('buffer://192.168.185.142:1972') Read a total of 8 projection items: grad3v_ssp_upr.fif : PCA-v1 (1 x 306) idle grad3v_ssp_upr.fif : PCA-v2 (1 x 306) idle grad3v_ssp_upr.fif : PCA-v3 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v1 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v2 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v3 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v4 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v5 (1 x 306) idle Warning: No device to head transform available in fif file > In fileio/private/mne2grad at 78 In fileio/private/decode_fif at 41 In ft_read_header at 1033 Warning: EEG channels will likely have coordinates in head frame, not device frame > In fileio/private/mne2grad at 79 In fileio/private/decode_fif at 41 In ft_read_header at 1033 hdr = Fs: 1000 nChans: 309 nSamples: 134000 nSamplesPre: 0 nTrials: 1 orig: [1x1 struct] grad: [1x1 struct] label: {309x1 cell} chantype: {309x1 cell} chanunit: {309x1 cell} >> hdr.orig ans = file_id: [1x1 struct] meas_id: [1x1 struct] meas_date: [2x1 int32] nchan: 309 sfreq: 1000 highpass: 0.1000 lowpass: 330 chs: [1x309 struct] ch_names: {1x309 cell} dev_head_t: [] ctf_head_t: [] dev_ctf_t: [] dig: [0x0 struct] bads: [] projs: [1x8 struct] comps: [0x0 struct] acq_pars: [] acq_stim: [] bufsize: 68852 I'll include the hdr as attachment anyway ... This is strange, since I'm measuring the head position, accepting it and even I'm measuring the continuos head position is on ... but no dig field passed in the buffer ... But, if I take a short file from the same session, saved, it gives me the following: >> hdr2 = ft_read_header('testwphantomdigitized.fif') Read a total of 8 projection items: grad3v_ssp_upr.fif : PCA-v1 (1 x 306) idle grad3v_ssp_upr.fif : PCA-v2 (1 x 306) idle grad3v_ssp_upr.fif : PCA-v3 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v1 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v2 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v3 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v4 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v5 (1 x 306) idle 306 MEG channel locations transformed Opening raw data file testwphantomdigitized.fif... Read a total of 8 projection items: grad3v_ssp_upr.fif : PCA-v1 (1 x 306) idle grad3v_ssp_upr.fif : PCA-v2 (1 x 306) idle grad3v_ssp_upr.fif : PCA-v3 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v1 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v2 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v3 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v4 (1 x 306) idle mag5v_ssp_upr.fif : PCA-v5 (1 x 306) idle Range : 12000 ... 14999 = 12.000 ... 14.999 secs Ready. hdr2 = label: {309x1 cell} nChans: 309 Fs: 1000 grad: [1x1 struct] nSamples: 3000 nSamplesPre: 0 nTrials: 1 orig: [1x1 struct] chantype: {309x1 cell} chanunit: {309x1 cell} >> hdr2.orig.dig ans = 1x23 struct array with fields: kind ident r coord_frame i.e. a lot of dig info ... Any clue? Best, GP


Gianpaolo Demarchi - 2013-10-30 11:23:52 +0100

Created attachment 545 hdr from the stream and hdr2 from the file


Gianpaolo Demarchi - 2013-10-30 11:24:32 +0100

Created attachment 546 Short fiff with some digitized points ...


Arjen Stolk - 2013-10-30 18:19:16 +0100

(In reply to comment #124) This sounds as if the digitized HPI coil information (orig.dig) is only added to the fif container when the file is saved, or acquisition end. That would be a bummer since we need that information to localize the coils in real-time. Is there by any chance a software settings that changes this procedure (e.g. adding the polhemus data at acquisition onset)? Alternatively, we'll need to have one fif file saved directly after polhemus tracking (without further data acquisition), insert this file as an input argument to ft_realtime_headlocalizer (e.g. cfg.hpifile = 'XXX.fif'), then start a new fif file for data acquisition (while head position is monitored/adjusted during the acquisition). Would that be a possibility?


Arjen Stolk - 2013-10-30 18:38:04 +0100

(In reply to comment #127) added the optionality to ft_realtime_headlocalizer (line 129) if ~isfield(cfg, 'hpifile') shape = ft_read_headshape(cfg.headerfile, 'coordsys', 'dewar', 'format', 'neuromag_fif'); elseif isfield(cfg, 'hpifile') shape = ft_read_headshape(cfg.hpifile, 'coordsys', 'dewar', 'format', 'neuromag_fif'); end


Gianpaolo Demarchi - 2013-10-31 10:55:19 +0100

(In reply to comment #127) Ciao, > This sounds as if the digitized HPI coil information (orig.dig) is only added > to the fif container when the file is saved, or acquisition end. This would really be bad ... > That would be > a bummer since we need that information to localize the coils in real-time. Is > there by any chance a software settings that changes this procedure (e.g. > adding the polhemus data at acquisition onset)? I'll check in the cryptic manual, but probably is as you say ... written to the header at the end ... Currently I cannot do any further testing, since they're measuring in the lab (and I've already killed one block the other day with my "remote" tinkering ;-)) > Alternatively, we'll need to have one fif file saved directly after polhemus > tracking (without further data acquisition), insert this file as an input > argument to ft_realtime_headlocalizer (e.g. cfg.hpifile = 'XXX.fif'), or as an argument to neuromag2ft, so you don't have to move any fif file on the network, even if tiny ... > then > start a new fif file for data acquisition (while head position is > monitored/adjusted during the acquisition). Would that be a possibility? If this is the case, I don't see any other way out ... i.e. measuring a tiny shot containing only 1 sec of data with the dig info, and then fitting the dipole positions on the data streamed (luckily the 300 Hz noise is always there ;-)) ... As soon as the lab is free I try a couple of additional things, like enabling/disabling cHPI, and/or stopping/restarting raw file recording on the same fiff file ... it could well be that in that way, some relevant info is still written to the header ... I'll keep you posted, GP


Arjen Stolk - 2013-10-31 11:43:01 +0100

(In reply to comment #129) Oki doki, thank you for your quick reply. Let me/us know when you know more about the orig.dig field, or whether that bypass option (cfg.hpifile) does work.


Gianpaolo Demarchi - 2013-12-02 17:18:32 +0100

(In reply to comment #130) Here am I with some test files ... The "prepared" (/neuro/dacq/prepared) folder I guess contains the preparation done for this subject, whereas the "meas_info" (/neuro/dacq/meas_info ) contains a bit more info, namely (I think) also the measurement and fit of the HPI coils (hip_meas/hpi_result) of the current run ... Some files are equivalent, i.e. prepK4trSD.iso = isotrak prepK4trSD.proj = proj prepK4trSD.set = parameters prepK4trSD.subj = subject prepK4trSD referes to a generic subject preparation, it changes from session to session, whereas the files in the meas_info folder change from run to run. Or better, isotrak, prom, parameters, and subject are clones of the prep*, while hpi* and events change with the run ... From the size, the hpi_meas should be a complete fiff file with some real MEG measurements of the HPI coils, but renaming it to .fif didn't do the trick and still doesn't look to be a fully legit fiff file >> ft_read_header('hpi_meas.fif') Error using fiff_read_meas_info (line 97) Could not find measurement data Error in ft_read_header (line 1323) info = fiff_read_meas_info(filename); I managed to "open" them with the decode_fiff function, but I get a lot of useless (to me :-( ) data out Probably, if we/you do the trick that we used before, we can make those things digested by the neuromag2ft ... Attachment follows ... Ciao, G.


Gianpaolo Demarchi - 2013-12-02 17:22:08 +0100

Created attachment 566 meas_info and prepared folders - hopefully containing meaningful info for the HPI


Arjen Stolk - 2013-12-09 22:46:59 +0100

Hi GP, just back from the USA. Hope everything is well (little one too?). Thanks for sending those files. It turns out that, in contrast to the tapped online datastream, but in agreement with the .fif end product, they're in big-endian format (I checked hpi_meas.fif, isotrak.fif, and prepK4trSD.iso.fif). Also, these files contain the required file-id tag (kind=100) and directory pointer (kind=101) tag (which we are synthetically adding in the neuromag2ft software - which would thus not be needed anymore when we would chunk these stored files online). So far so good. However, I'm encountering the same error you mentioned ('Could not find measurement data') when trying to read those fiff files using fiff_read_meas_info. This could make sense since there might be no measurement data stored in either those files. Have to see whether we can create a patch for this too.


Arjen Stolk - 2013-12-11 11:40:18 +0100

[dig] = ft_read_isotrak('Archivio/meas_info/isotrak') dig = 1x309 struct array with fields: kind ident r coord_frame Have to see how to support/implement this functionality in both the sender and receiver end of the FT buffer. But the goods news is that it seems we will be able to access this crucial information online.


Arjen Stolk - 2013-12-11 11:41:21 +0100

Created attachment 574 FT_READ_ISOTRAK


Robert Oostenveld - 2013-12-11 11:48:50 +0100

(In reply to comment #135) can you merge ft_read_isotrak with ft_read_headshape?


Arjen Stolk - 2013-12-11 12:11:36 +0100

Trying to see if I can also pull out transformation matrices. Ideally, all this information is merged with ft_read_header then, isn't it (basically a low-level version of fiff_read_meas_info.m?


Arjen Stolk - 2013-12-11 13:00:36 +0100

bash-4.1$ svn commit Sending fileio/ft_read_header.m Sending fileio/private/decode_fif.m Sending test/test_ft_regressconfound.m <- unrelated Transmitting file data ... Committed revision 9018.


Arjen Stolk - 2013-12-12 17:20:43 +0100

Hi GP, Some good news with respect to the buffer infrastructure. Stephen Whitmarsh tested the newest implementation of neuromag2ft in Stockholm. At first sight it seems all the info we wanted is sent&received through the FT buffer (including information stored in meas_info/isotrak and meas_info/hpi_result, necessary for dipolefitting the HPI coils). So that finally works! With respect to dipolefit accuracy, we noticed that there are some obstacles to be overcome, at least for a phantom subject. We wonder whether an well-prepared subject (with HPI coils nicely placed as desired by neuromag, and with all 5 coils) will improve accuracy. Since we made a recording of the phantom, I can also try and determine the localization error of our dipolefit procedure offline, and hopefully improve it implementing more of 'Robert's wisdom'. If you want to have a go with the online setup, please download the latest FT version, and compile the mex file. Yours, Arjen


Gianpaolo Demarchi - 2013-12-12 21:43:24 +0100

(In reply to Arjen Stolk from comment #139) Hi Arjen, sorry for the late reply, but ... > Hi GP, > Some good news with respect to the buffer infrastructure. Stephen Whitmarsh tested > the newest implementation of neuromag2ft in Stockholm. ... one cannot be sick at home for a week, because ... > At first sight it seems all > the info we wanted is sent&received through the FT buffer (including information > stored in meas_info/isotrak and meas_info/hpi_result, necessary for dipolefitting the > HPI coils). So that finally works! ... you just disappear for a second and someone else is "kissing the girl", with whom you were trying for months :-( !!! coils-tus interruptus!!! Congratulations to Stephen ;-) Kidding apart, I'm happy that it works, and I really couldn't wait going to the lab and testing it (which hopefully will happen tomorrow ...) > With respect to dipolefit accuracy, we noticed that there are some obstacles to be > overcome, at least for a phantom subject. What's the difference with a real one? Too steady?! > We wonder whether an well-prepared subject (with HPI coils nicely placed as > desired by neuromag, and with all 5 coils) btw, there's no agreement even in the elekta people whether even if enabled all the 5 coils are working, or only 4, or the 5 are available on the Triux only (sort of urban legend now ) > will > improve accuracy. Since we made a recording of the phantom, I can also try and > determine the localization error of our dipolefit procedure offline, and hopefully > improve it implementing more of 'Robert's wisdom'. Zen master ... !!! > If you want to have a go with the online setup, please download the latest FT > version, and compile the mex file. I'll do it tomorrow, let me know if I can do some more tests ... Goede nacht, GP


Arjen Stolk - 2013-12-12 22:13:35 +0100

You're still our #1 alpha tester. :D I fear the localization accuracy might be poor when you test tomorrow (but I hope to be proven wrong). At least, it would be good to replicate the stockholm finding, which is having the infrastructure finally work in Trento. We also noticed there might a small bug in there (probably the one you've encountered and mentioned previously). Namely, when restarting the measurement the tmp/neuromag2ft.fif file was sometimes not being able to be opened. This is also was neuromag2ft outputs in the command window, so it was easy to notice. Restarting again would do the trick so far (as indicated by the absence of the error message 'cannot open xxx'). Oh, about those coils: I have no idea on recommendations. But we noticed there seemed to be a 20 Hz sinewave present over some channels when we turned on cHPI. Perhaps this is due to the combination of specific frequencies of close by HPI coils. The phantom head might have been too small. :)


Arjen Stolk - 2013-12-12 22:18:31 +0100

CC list test


Arjen Stolk - 2013-12-12 22:29:10 +0100

sanity check to see whether our online HPI information matches the offline (in fiff container) information: ft_hastoolbox('mne',1); info = fiff_read_meas_info('cHPI_test_arjsto.fif') dig = ft_read_isotrak('Stockholm/20131212/isotrak') isequal(info.dig, dig) ans = 1 [dev_head_t, ctf_head_t] = ft_read_hpiresult('Stockholm/20131212/hpi_result') isequal(info.dev_head_t, dev_head_t) ans = 1 Note that ft_read_isotrak and ft_read_hpiresult are not standalone functions, but subfunctions in decode_fif.m (in fileio/private)


Arjen Stolk - 2013-12-12 22:39:59 +0100

BTW, if you're going to test tomorrow, click the 'show sensors' button while the headlocalizer is running. This gives a good immediate impression about where the coils are dipolefitted inside the dewar. :D


Gianpaolo Demarchi - 2013-12-13 12:48:07 +0100

(In reply to Arjen Stolk from comment #144) Ciao Arjen, I tested quickly the setup and it didn't work as expected. Firstly, yes, I have on both machines the newest ft, svn-ed At revision 9030. Starting from the end, headlocalizer doesn't work: as some time ago, it complained: Reference to non-existent field 'grad'. Error in ft_realtime_headlocalizer (line 74) isneuromag = ft_senstype(hdr.grad, 'neuromag'); And it has good reasons to complain, since the data buffer contains, well ... only data: >> hdr = ft_read_header('buffer://192.168.185.142:1972'); >> hdr = Fs: 1000 nChans: 309 nSamples: 62000 nSamplesPre: 0 nTrials: 1 orig: [1x1 struct] label: {309x1 cell} chantype: {309x1 cell} chanunit: {309x1 cell} >> hdr.orig ans = bufsize: 71560 This happens, despite the server says it's appending the relevant data: neuromag2ft (131213 10:43:56) About to connect to the Neuromag DACQ shared memor y on this workstation (client ID 14013)... neuromag2ft (131213 10:43:56) Connection ok neuromag2ft (131213 10:43:56) Current buffer length value = 1500 neuromag2ft (131213 10:43:56) FieldTrip buffer server thread started (TID 108994 7968) neuromag2ft (131213 10:43:56) Will scale up MEG mags by 1, grads by 1 and EEG da ta by 1 neuromag2ft (131213 10:43:56) Waiting for the measurement to start... Press Ctrl -C to terminate this program neuromag2ft (131213 11:06:46) Opened file /neuro/dacq/raw/dacq3XnrCT. neuromag2ft (131213 11:06:46) New measurement is starting... neuromag2ft (131213 11:06:46) Data buffers coming soon... neuromag2ft (131213 11:06:46) Creating a header: 309 channels, sampling rate 1000 Hz neuromag2ft (131213 11:06:46) Appended 2469 bytes with channel name information neuromag2ft (131213 11:06:46) Appended 66367 bytes with information from /tmp/neuromag2ft.fif neuromag2ft (131213 11:06:46) Appended 2004 bytes with information from /neuro/dacq/meas_info/isotrak neuromag2ft (131213 11:06:46) Failed to open /neuro/dacq/meas_info/hpi_result neuromag2ft (131213 11:06:46) Header sent to the FieldTrip buffer neuromag2ft (131213 11:25:48) Measurement ended (1139 buffers). neuromag2ft (131213 11:25:48) File closed (FIFF_CLOSE_FILE). neuromag2ft (131213 11:25:48) File closed. neuromag2ft (131213 11:25:58) Opened file /neuro/dacq/raw/dacqYMW1eD. neuromag2ft (131213 11:25:58) New measurement is starting... neuromag2ft (131213 11:25:58) Data buffers coming soon... neuromag2ft (131213 11:25:58) Creating a header: 309 channels, sampling rate 1000 Hz neuromag2ft (131213 11:25:58) Appended 2469 bytes with channel name information neuromag2ft (131213 11:25:58) Failed to open /tmp/neuromag2ft.fif neuromag2ft (131213 11:25:58) Appended 2004 bytes with information from /neuro/dacq/meas_info/isotrak neuromag2ft (131213 11:25:58) Appended 688 bytes with information from /neuro/dacq/meas_info/hpi_result neuromag2ft (131213 11:25:58) Header sent to the FieldTrip buffer neuromag2ft (131213 11:29:08) Data buffers coming soon... neuromag2ft (131213 11:29:08) Creating a header: 309 channels, sampling rate 1000 Hz neuromag2ft (131213 11:29:08) Appended 2469 bytes with channel name information neuromag2ft (131213 11:29:08) Failed to open /tmp/neuromag2ft.fif neuromag2ft (131213 11:29:08) Appended 2004 bytes with information from /neuro/dacq/meas_info/isotrak neuromag2ft (131213 11:29:08) Appended 688 bytes with information from /neuro/dacq/meas_info/hpi_result neuromag2ft (131213 11:29:08) Header sent to the FieldTrip buffer neuromag2ft (131213 11:35:05) Measurement ended (356 buffers). neuromag2ft (131213 11:35:05) File closed (FIFF_CLOSE_FILE). neuromag2ft (131213 11:35:05) File closed. As a side note, the first "run" it complains about "Failed to open /neuro/dacq/meas_info/hpi_result", which is fine, since the streaming of the data happens before this file is created. Namely, you start the acquisition, the neuromag2ft server streams out the info, but only after few seconds the acquisition sw is asking you whether you want to measure the HPI (and then the hip_result is created, if a successful fit happens) or skip it. After the very first acquisition run, the acq sw can ask you to "reuse" the previous HPI fit, and that's why in the second run above you don't see the error about the hpi_result anymore; this leads to a potential problem (after having solved all the other issues) that with the current program you're streaming the HPI fit of the previous run: I don't know whether this was meant or not (maybe yes), but you're going to compare the actual coils fit with a somehow outdated (of the previous run/session) set of values. As said a quick workaround is making a quick start and stop, to create a hpi_result file, but in the ideal case neuromag2ft should wait for the new hip_result of the new session to be created, before starting streaming out the info. Still, once in a while you get a failure of opening /tmp/neuromag2ft.fif, but this doesn't seem to affect to actual streaming of meg data (checked with signalviewer), but maybe it affects the streaming of the grad/hpi/extra info, since it's using the 'old' file that didn't contain, among the other things, the hip fit results. That said, and despite the claims of "appending" info, on the client computer I do see only meg data, as stated by the hdr before ... @Stockholm_crew: have I done something blatantly wrong wrt what you have done?! If you see it please let me know, since I'm scared of thinking that the thing work or doesn't work depending whether is a Triux or Vectorview, doubling the effort of all of us ... I've done some more tests, also trying to pass the cfg.gradfile to ft_realtime_headlocalizer, but you've, correctly, removed this option in principle non necessary, if the streaming of the grad info works ... My 2 Gcents, GP


Arjen Stolk - 2013-12-13 14:17:16 +0100

Hi GP, Thanks for testing this on short notice. hdr.orig should indeed contain a .neuromag_header (captured from the realtime stream), a .neuromag_isotrak (the big endian file stored on disk), a .neuromag_hpiresult field (same as isotrak). There's an if-statement in ft_read_header, computing the info variable by calling decode_fif when the .neuromag_header field is present online. There's a couple of reasons why it's not present online, all related to checks in neuromag2ft.c (and process_tag.c, for instance when the temporay headerfile '/tmp/neuromag2ft.fif') cannot be opened. Did you try out the software using digitized head positions? I believe Stephen's order of start-up was: start acq (without recording), digitize, then start neuromag2ft, but I'm not entirely sure. Hopefully, he can give some recommendations here, Yours, arjen


Arjen Stolk - 2013-12-13 14:59:27 +0100

Another possibility; did you recompile the buffer mexfile? And put the mexfile in /fileo/private?


Arjen Stolk - 2013-12-13 15:10:21 +0100

order according to Stephen: 1) start acquisition software 2) select project 3) select subject 4) select HPI digitization 5) start sampling (which is not recording to file yet) 6) start neurmag2ft (alternatively, you could do it before 5 it seems) 7) tick the [record raw] box which will start the actual recording


Robert Oostenveld - 2013-12-13 16:34:28 +0100

Hi GP, Also in Stockholm we had the problem that depending on the (not fully clear) sequence of starting the neuromag_header would or would not be sent. If neuromag_header is not sent as chunk, the other two will also not be processed on the client side. There is still a bun in process_tag.c that has to do with the start/stop sequence and the temp file.


Gianpaolo Demarchi - 2013-12-13 22:07:55 +0100

(In reply to Robert Oostenveld from comment #149) Hi, all in one shot: > Thanks for testing this on short notice. hdr.orig should indeed contain a > .neuromag_header (captured from the realtime stream), a .neuromag_isotrak (the big > endian file stored on disk), a .neuromag_hpiresult field (same as isotrak). > There's an if-statement in ft_read_header, computing the info variable by calling > decode_fif when the .neuromag_header field is present online. There's a couple of > reasons why it's not present online, all related to checks in neuromag2ft.c (and > process_tag.c, for instance when the temporay headerfile '/tmp/neuromag2ft.fif') > cannot be opened. > Did you try out the software using digitized head positions? Yes, on a phantom like the last time ... > I believe Stephen's > order of start-up was: start acq (without recording), digitize, then start > neuromag2ft, but I'm not entirely sure. Hopefully, he can give some recommendations > here, See below ... > Another possibility; did you recompile the buffer mexfile? And put the mexfile in > /fileo/private? You mean on the client?! No, honestly I forgot this step :-( In fact, checking 13 Dic 10:36 buffer.mexa64 but since I'm on mac 29 Ott 11:27 buffer.mexmaci64 so, you compiled the linux one in the upstream ft repository, but on my side I completely forgot this step, sorry ... > order according to Stephen: > 1) start acquisition software > 2) select project > 3) select subject > 4) select HPI digitization > 5) start sampling (which is not recording to file yet) > 6) start neurmag2ft (alternatively, you could do it before 5 it seems) > 7) tick the [record raw] box which will start the actual recording I do the preparation in another room first, then I load on the acq machine afterwards. For historical reasons, I usually started neuromag2ft before starting the acq program, because in the past this was the only way for not hanging everything. But today I tried also the other way around (first acq, then n2ft, a la Stockholm) and nothing crashed, luckily. So I really appreciated this new version ... > Also in Stockholm we had the problem that depending on the (not fully clear) sequence > of starting the neuromag_header would or would not be sent. If neuromag_header is not > sent as chunk, the other two will also not be processed on the client side. What I'll do asap on monday is testing again with the recompiled buffer mex (sorry again :-(), and work a bit to check different sequences. > There is still a bun in process_tag.c that has to do with the start/stop sequence and > the temp file. Another bad issued that I had in the past was that, after starting [record raw] exactly after 10 seconds the acquisition "hangs", and you get all the data "flushing" on the screen as soon as you kill n2ft. That's why today I didn't test with the [record raw] ticked, in fact the streaming of the data happens right away as soon as you click [start], and even before the actual hpi coils fit happens. Still I think the server should wait for the new coils fit to happen, before streaming the data; otherwise the risk is that you'll send the fit results of a different run, or even worse, of a previous subject ... I'll come back with more info on Monday ... GP


Gianpaolo Demarchi - 2013-12-17 22:08:51 +0100

Dear all, this > Another possibility; did you recompile the buffer mexfile? And put the mexfile in > /fileo/private? in the end did the trick. Probably it's better to automatize it in the future, maybe adding a couple of relevant lines into compile.m Now, sometimes, all the info is there, like: >> hdr.grad ans = balance: [1x1 struct] chanori: [306x3 double] chanpos: [306x3 double] chantype: {306x1 cell} chanunit: {306x1 cell} coilori: [510x3 double] coilpos: [510x3 double] coordsys: 'dewar' label: {306x1 cell} tra: [306x510 double] type: 'neuromag306' unit: 'cm' This in particular works when when all the bits are put together, i.e. neuromag2ft (131217 16:05:07) Appended 2469 bytes with channel name information neuromag2ft (131217 16:05:07) Appended 66367 bytes with information from /tmp/neuromag2ft.fif neuromag2ft (131217 16:05:07) Appended 1500 bytes with information from /neuro/dacq/meas_info/isotrak neuromag2ft (131217 16:05:07) Appended 680 bytes with information from /neuro/dacq/meas_info/hpi_result Then problem is that this happens pseudorandomly ... *) The first time you start neuromag2ft there are still no fits of coils available, so you get "failed to open /neuro/dacq/meas_info/hpi_result", but /tmp/neuromag2ft.fif is freshly created and accessible. You get, among the other things (obviously): Warning: No device to head transform available in fif file *) If you stop and restart the acquisition, now the (previous) hpi_result becomes available, but for some strange reason /tmp/neuromag2ft.fif is no more accessible, and again some part of the info is missing ... My personal sort-of-working recipe is the following: 1) start acquisition software, select project, select subject, load the HPI digitization 2) start neuromag2ft 3) hit "Run" and fit the coils: this starts streaming incomplete data, because the hpi_results is being created and still missing ... 4) stop and restart neuromag2ft; now all the bits are in place, namely there (previous) hpi_result is available and restarting neuromag2ft makes a fresh /tmp/neuromag2ft.fif ... 5) Hit "restart", to restart the acquisition: at this stage one can "keep" the previous fit, since the new one won't be used anyway, and tick "cHPI" if I wish ... Now I've a reliable and stable stream of data, on which I can apply ft_realtime_headlocalizer(cfg) at this point I see the coils on the plots, sometimes jumping/flipping around, but sooner or later everything dies in: Error using dipole_fit (line 164) Maximum number of iterations exceeded before reaching the minimum, please try with another initial guess. If you see the attached figure, probably this is due to using the wrong/previous HPI fit (?!) Eyeballing, apart from fixing the /tmp/neuromag2ft.fif problem (missing an "append" somewhere!?), probably a good workaround would be changing a bit neuromag2ft in a way that it waits for a keypress before streaming, e.g. start acquisition, start neuromag2ft (which waits for me), do the HPI fit, and only now in the console hit "enter", so the new hpi_result is used ... Then, why the ft_rt_headloc fit fails, I cannot really help ;-) My two cents, G.


Gianpaolo Demarchi - 2013-12-17 22:09:44 +0100

Created attachment 576 Strange HPI coils / sensors outcome


Arjen Stolk - 2013-12-18 09:58:00 +0100

Thanks Gp, for the useful information. The critical order of actions that determines the stream-capturing&sending of the chunks to the buffer needs a closer look indeed. Ideally, neuromag2ft is, as with the CTF system, running all the time, bulletproof. The second issue is indeed to improve the fits. Right now, we're using the magnetometer channels (102), but we've been exploring the use of all 306 channels, and even specific subselections of channels. This will try require a more systematic investigation.


Arjen Stolk - 2014-02-11 21:33:03 +0100

Dear GP (and Stephen), I haven't posted here for a while, but this project hasn't been out of my head. So here's an update. I have been trying to improve the dipole fit procedure, but at this point the behavior is still as you described it: "I see the coils on the plots, sometimes jumping/flipping around, but sooner or later everything dies in" When looking at the modeled data that is used for comparison with the actually recorded data (in this case: a ~10min. phantom measurement in stockholm, with sss-treatment afterwards), I do not see any abnormalities (1st slide of attachment below). However, the explained variance of actually recorded signal amplitudes at the different sensors is pretty low, i.e. much lower than reported in the Maxfilter manual (.98), see slides 1 and 2 of attachment. Comparing the topographies of actual and model data, and especially their difference, shows that there is spatial structure left in the unexplained variance (3rd column of 3rd slide). It is highly likely that this is causing the behavior you described. At this point, it's an open question to me what is the most efficient way to proceed. Hopefully, Robert has another rabbit in his hat. Any suggestions/inside knowledge are welcome. :) Yours, Arjen %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Matlab code history, for replication purposes of attached figure below (stockholm-data-specific) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% cfg = []; cfg.dataset = '/home/action/arjsto/Headloc/Stockholm/cHPI_test_arjsto_sss.fif'; cfg.coilfreq = [307, 314, 293, 321]; cfg.bufferdata = 'first'; cfg.blocksize = 10; ft_realtime_headlocalizer(cfg) % debug @ line 169 in dipole_fit.m, and then @ line 324 in dipole_fit.m X = lf*mom; % 'model' figure; hold on; for j=1:4 subplot(2,2,j); hold on; ft_plot_topo3d(sens.chanpos, X(:,j)) % goodness-of-fit [B,BINT,R,RINT,STATS] = regress(dat(:,j),X(:,j)); % STATS: R-square, F, p, E fprintf('goodness of fit for sensor %s: %s \n', num2str(j), num2str(STATS(1))) title(['model R-square: ' num2str(STATS(1))]); end figure; hold on; for j=1:4 subplot(2,2,j); hold on; plot(X(:,j),dat(:,j),'b.') xlabel('lf*mom') ylabel('dat') end freqlabel = [307, 314, 293, 321]; % specific for stockholm setup during this particular recording cfgtopo = []; cfgtopo.marker = 'off'; cfgtopo.comment = 'no'; cfgtopo.layout = 'neuromag306all.lay'; data.label = sens.label; data.dimord = 'chan_freq'; data.freq = 1; figure; hold on; for j=1:4 subplot(4,3,j*3-2); hold on; data.powspctrm = dat(:,j); ft_topoplotTFR(cfgtopo, data); title(['data hpi' num2str(j)]) subplot(4,3,j*3-1); hold on; data.powspctrm = X(:,j); ft_topoplotTFR(cfgtopo, data); title(['model hpi' num2str(j)]) subplot(4,3,j*3); hold on; data.powspctrm = dif(:,j); ft_topoplotTFR(cfgtopo, data); title(['dif hpi' num2str(j) ', ' num2str(freqlabel(j)) 'Hz']) end


Arjen Stolk - 2014-02-11 21:34:16 +0100

Created attachment 591 goodness-of-fits of dipolefits on a phantom-measurement


Gianpaolo Demarchi - 2015-03-30 10:15:38 +0200

(In reply to Arjen Stolk from comment #155) Just to update a bit the status, after the "bump" of Robert. For the offline movement correction, now we are settled on a sort of "hackerish" solution. We get the head positions out of maxfilter (used only for that ;-)), that with the "-hp" switch puts the positions (quaternions) and the time in a text file, that we afterwards use either for showing the amount of movement (cimec_showmov.m, I can post if interested, just a cool name around standard ft functions), or for adding as extra "trialinfo" columns per trial (cimec_addmov.m, as before). This afterwards is used in the ft_regressconfound part, to regress out the movement. I haven't fully given up the "pure" matlab/ft way, but this sounded as a viable tradeoff, waiting for fresh forces/new info ... For the online part ... we just pull more the chin rest ;-) Since I saw this issue on men-python last week https://github.com/mne-tools/mne-python/issues/1883 which in turn hints towards this WIP https://github.com/mne-tools/mne-python/pull/1876 I've seen that in base.py there is a function get_chpi_positions (...) but seems to be as workaround-ish are we are, i.e. if there is the maxfilter output then use it for getting the quaternions, otherwise just suck the cHPI (sinusoidal) data, AFA my crappy understanding of python ... So, they don't seem to be much further ;-) G.


Arjen Stolk - 2016-07-31 02:16:18 +0200

Dear all, This topic hasn't been touched in a while, and it doesn't seem likely that I will be able to revisit it either. The current status seems to be that the buffer side is in good shape, but the required dipolefitting of the headposition coils isn't. I recall our suspicion was this was due a too complex interaction between the different headposition coils themselves and/or non-linear sensor sensitivity. Moreover, it seems Trento found a workaround that allows them to use the head positions in their offline analysis. Perhaps it would be possible to document those tools, Gianpaolo? For instance, here: http://www.fieldtriptoolbox.org/example/how_to_incorporate_head_movements_in_meg_analysis? On that note, I would like to close this bug. Feel free to reopen it though in case of new insights. Best, Arjen


Robert Oostenveld - 2019-08-10 12:35:53 +0200

This closes a whole series of bugs that have been resolved (either FIXED/WONTFIX/INVALID) for quite some time. If you disagree, please file a new issue on https://github.com/fieldtrip/fieldtrip/issues.


Robert Oostenveld - 2019-08-10 12:42:08 +0200

This closes a whole series of bugs that have been resolved (either FIXED/WONTFIX/INVALID) for quite some time. If you disagree, please file a new issue on https://github.com/fieldtrip/fieldtrip/issues.