8000 Updated support for QZFM_UCL data #2130 by neurofractal · Pull Request #2242 · fieldtrip/fieldtrip · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Updated support for QZFM_UCL data #2130 #2242

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions fileio/ft_chantype.m
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@
for sel=find([input.orig.chs.kind]==602)' % Resp
chantype(sel) = {'respiration'};
end

elseif ft_senstype(input, 'babysquid74')
% the name can be something like "MEG 001" or "MEG001" or "MEG 0113" or "MEG0113"
% i.e. with two or three digits and with or without a space
Expand Down Expand Up @@ -308,7 +308,17 @@
chantype(sel) = {'refmag'}; % reference magnetometers
sel = myregexp('^[GPQR][0-9][0-9]$', label);
chantype(sel) = {'refgrad'}; % reference gradiometers


elseif isheader && ft_senstype(input,'QZFM_UCL')
chantype = input.orig.channels.type;

sel = myregexp('^MEGMAG$', chantype);
chantype(sel) = {'megmag'}; % magnetometers
sel = myregexp('^MEGREFMAG$', chantype);
chantype(sel) = {'refmag'}; % reference magnetemeters
sel = myregexp('TRIG', chantype);
chantype(sel) = {'trigger'}; % trigger channels

elseif ft_senstype(input, 'bti')
if isfield(input, 'orig') && isfield(input.orig, 'config')
configname = {input.orig.config.channel_data.name};
Expand Down
5 changes: 4 additions & 1 deletion fileio/ft_filetype.m
Original file line number Diff line number Diff line change
Expand Up @@ -1271,7 +1271,10 @@
type = 'neuroelectrics_nedf';
manufacturer = 'Neurolectrics';
content = 'EEG binary data (Enobio & Starstim)';

elseif filetype_check_extension(filename, '.bin') && exist([filename(1:(end-4)) '.json'], 'file')
type = 'QZFM_UCL';
manufacturer = 'QuSpin';
content = 'OPM-MEG data';
% some other known file types
elseif filetype_check_extension(filename, '.hdf5')
type = 'gtec_hdf5';
Expand Down
5 changes: 4 additions & 1 deletion fileio/ft_read_data.m
Original file line number Diff line number Diff line change
Expand Up @@ -1568,7 +1568,10 @@
dat(spikesel(i),j) = dat(spikesel(i),j) + 1;
end
end


case {'QZFM_UCL'}
dat = opm_fil(filename, hdr, begsample, endsample, chanindx);

case 'read_nex_data' % this is an alternative reader for nex files
dat = read_nex_data(filename, hdr, begsample, endsample, chanindx);

Expand Down
11 changes: 10 additions & 1 deletion fileio/ft_read_header.m
Original file line number Diff line number Diff line change
Expand Up @@ -2589,7 +2589,16 @@
end
hdr.label = hdr.label(:);
hdr.nChans = length(hdr.label);


case {'QZFM_UCL'}
% Use the opm_fil function
hdr = opm_fil(filename);
% Fix the hdr.chantype using ft_chantype
hdr.chantype = ft_chantype(hdr);
% This is needed so ft_read_header doesn't over-ride with raw BIDS
% info
readbids = 'no';

case {'ricoh_ave', 'ricoh_con', 'ricoh_mrk'}
% header can be read with Ricoh MEG Reader
hdr = read_ricoh_header(filename);
Expand Down
29 changes: 23 additions & 6 deletions fileio/private/opm_fil.m
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,20 @@
case 'double'
samplesize = 8;
end

% Try to get the type of sensor array (helmet) used
if isfield(header, 'HelmetManufacturer')
type = ['QZFM' '_' header.HelmetManufacturer];
else
type = ['QZFM' '_' header.HelmetManufacturer];
ft_warning(['No HelmetManufacturer specified in the accompanying' ...
' meg.json file. Assuming the sensor type is ''QZFM_UCL''']);
end

% Read the channels
channels = readtable(channelsfile, 'Delimiter', 'tab', 'FileType', 'text');

% this one is optional
% Get the coordsysfile - this one is optional
if exist(coordsysfile, 'file')
fid = fopen(coordsysfile, 'rt');
coordsys = jsondecode(fread(fid, [1 inf], 'char=>char'));
Expand All @@ -87,24 +97,24 @@
coordsys = [];
end

% this one is optional
% Get the positions file - this one is optional
if exist(positionsfile, 'file')
positions = readtable(positionsfile, 'Delimiter', 'tab', 'FileType', 'text');
else
positions = [];
end

d = dir(datafile);


% Construct the hdr
hdr.label = channels.name;
hdr.nChans = size(channels, 1);
hdr.nSamples = (d.bytes/(size(channels, 1) * samplesize))-1;
hdr.nSamplesPre = 0; % continuous data
hdr.nTrials = 1; % continuous data
hdr.Fs = header.SamplingFrequency;
hdr.chantype = channels.type;
try
hdr.chanunit = channels.unit;
hdr.chanunit = channels.units;
catch
hdr.chanunit = repmat({'unknown'}, size(hdr.label));
end
Expand All @@ -120,8 +130,15 @@
hdr.grad.label = positions.name;
hdr.grad.coilpos = [positions.Px positions.Py positions.Pz];
hdr.grad.coilori = [positions.Ox positions.Oy positions.Oz];
hdr.grad.type = 'meg';
hdr.grad.type = type;
hdr.grad.chantype = repmat({'megmag'},size(positions.name));
hdr.grad.chanunit = repmat({'fT'},size(positions.name));
hdr.grad.tra = diag(ones(1,length(positions.name)));

if isfield(header, 'HelmetManufacturer')
hdr.grad.HelmetManufacturersModelName = header.HelmetManufacturersModelName;
end

if ~isempty(coordsys)
hdr.grad.unit = coordsys.MEGCoordinateUnits;
hdr.grad.coordsys = coordsys.MEGCoordinateSystem;
Expand Down
8 changes: 8 additions & 0 deletions test/test_issue1395.m
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@
cfg.dataset = datafile;
data = ft_preprocessing(cfg);

%%
% Test without specifying cfg.headerformat and cfg.dataformat and
% cfg.eventformat
cfg = [];
cfg.dataset = datafile;
data_auto = ft_preprocessing(cfg);
clear data_auto

%%

cfg = [];
Expand Down
6 changes: 3 additions & 3 deletions utilities/ft_channelselection.m
Original file line number Diff line number Diff line change
Expand Up @@ -364,10 +364,10 @@
% all itab MEG channels start with MAG
labelmeg = datachannel(strncmp('MAG', datachannel, length('MAG')));

case{'qzfm_gen2'}
% This is for use with QZFM_Gen2 Optically Pumped Magnetometers manufactured by QuSpin Inc.
case{'QZFM_UCL'}
% This is for use with UCL-OPM Lab which uses QZFM Optically Pumped
% % Magnetometers manufactured by QuSpin Inc.
% SPECS: https://quspin.com/qzfm-gen-2-update/

labelmeg = datachannel(strncmp('meg', datachantype, 3));
labelmegref = datachannel(strncmp('refmag', datachantype, 3));

Expand Down
0