From 5e89ee45a0dcf07d828c001dc917f15097e9cef5 Mon Sep 17 00:00:00 2001 From: Clint Banzhaf Date: Wed, 21 Aug 2024 19:41:11 +0200 Subject: [PATCH] Version 1.1.0 (#1) --- README.md | 29 ++- components/devices.m | 66 +++++ components/protocols.m | 67 +++++ components/session.m | 132 ++++++---- devices/eeg_generic.json | 8 + devices/nirs_generic.json | 8 + devices/nirs_nirx_nirsport2.json | 90 +++++++ main.m | 36 ++- protocols/Gauss.m | 189 ++++++++++++++ protocols/RecordOnly.m | 52 ++++ protocols/example1.m | 57 ----- settings/Gauss.mat | Bin 0 -> 721 bytes ui/app.mlapp | Bin 64848 -> 75924 bytes ui/app_exported.m | 424 +++++++++++++++++++++---------- ui/selectchannels.m | 309 ++++++++++++++++++++++ 15 files changed, 1209 insertions(+), 258 deletions(-) create mode 100644 components/devices.m create mode 100644 components/protocols.m create mode 100644 devices/eeg_generic.json create mode 100644 devices/nirs_generic.json create mode 100644 devices/nirs_nirx_nirsport2.json create mode 100644 protocols/Gauss.m create mode 100644 protocols/RecordOnly.m delete mode 100644 protocols/example1.m create mode 100644 settings/Gauss.mat create mode 100644 ui/selectchannels.m diff --git a/README.md b/README.md index 253813b..c056f1b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# UKT - Neurofeedback +# NINFA Small Matlab Framework for running Custom Neurofeedback Protocols on LSL Streams @@ -14,12 +14,20 @@ Small Matlab Framework for running Custom Neurofeedback Protocols on LSL Streams ## Configuration -1. [Optional] Adjust `TYPE` of LSL input stream (default is for NIRS device) -2. Click `OPEN` to connect with LSL input stream -3. Configure `SETTINGS`, `ID` and `EPOCHS` -4. Click `START` to run a session +1. Select your device +2. [Optional] Adjust `TYPE` of LSL input stream +3. Click `OPEN` to connect with LSL input stream +4. Configure `SETTINGS`, `ID` and `EPOCHS` +5. Click `START` to run a session -![ukt-nf-settings](https://github.com/cyberjunk/ukt-nf/assets/780159/0690b24e-7a20-4357-bd0d-9171c880115d) +![ninfa](https://github.com/user-attachments/assets/7f8ba7ad-ea09-4d08-8384-57f182961430) + +### DEVICE + +* Select your device type and model from the available options. +* Add a device by creating a `.json` file for it in subfolder `devices` + * Take a look at the existing `nirs_nirx_nirsport2.json` + * The most important part is defining the LSL channels sent by the device ### LSL STREAM @@ -38,10 +46,10 @@ Small Matlab Framework for running Custom Neurofeedback Protocols on LSL Streams | Setting | Description | |----------------------|------------------------------------------------------------------------------------------------| -| `SELECTED CHANNELS` | Comma separated list of LSL input channel numbers to use (others are ignored). | +| `PROTOCOL` | The Matlab file from folder `protocols` with algorithm executed on each window. | +| `CHANNELS` | Select LSL channels to use in the selected protocol | | `WINDOW SIZE (S)` | Size of the sliding window in seconds. The window always contains last n seconds of samples. | | `SESSION LENGTH (S)` | The session will automatically stop after this time. | -| `PROTOCOL` | The Matlab file from folder `protocols` with algorithm executed on each window. | ### ID @@ -88,8 +96,9 @@ An epoch is a configurable timespan within a session. * A protocol calculates a feedback value from an input window * To add a protocol put the Matlab file in subfolder `protocols` -* See `example1.m` (returns a random feedback value) - +* The `Gauss.m` example requires a NIRS device that sends at least one `HbO` channel with `μmol/L` unit +* The `RecordOnly.m` works with any device type and model and just records data + ## Drift and Execution Times * `DRIFT` shows current offset in playback schedule (`where we are` vs. `where we should be`) diff --git a/components/devices.m b/components/devices.m new file mode 100644 index 0000000..9aa267b --- /dev/null +++ b/components/devices.m @@ -0,0 +1,66 @@ +classdef devices < handle + %Devices + % Detailed explanation goes here + + properties (Constant) + types = ["NIRS", "EEG"] + end + + properties + nirs struct = []; + eeg struct = []; + selected struct = struct([]); + end + + methods + function self = devices() + self.reload(); + end + + function reload(self) + files = ls("devices/*.json"); + for f = 1:size(files, 1) + file = files(f, 1:end); + json = jsondecode(fileread("./devices/" + file)); + switch json.type + case "NIRS" + idx = length(self.nirs) + 1; + self.nirs(idx).name = json.name; + self.nirs(idx).type = json.type; + self.nirs(idx).lsl = json.lsl; + case "EEG" + idx = length(self.eeg) + 1; + self.eeg(idx).name = json.name; + self.eeg(idx).type = json.type; + self.eeg(idx).lsl = json.lsl; + otherwise + disp("Ignoring unknown device type"); + end + end + end + + function r = select(self, type, name) + switch type + case "NIRS" + for d = 1:length(self.nirs) + if self.nirs(d).name == name + self.selected = self.nirs(d); + r = true; + return + end + end + case "EEG" + for d = 1:length(self.eeg) + if self.eeg(d).name == name + self.selected = self.eeg(d); + r = true; + return + end + end + otherwise + warning("Ignoring unknown device type: " + type); + end + r = false; + end + end +end diff --git a/components/protocols.m b/components/protocols.m new file mode 100644 index 0000000..b77c174 --- /dev/null +++ b/components/protocols.m @@ -0,0 +1,67 @@ +classdef protocols < handle + %Protocols + % Detailed explanation goes here + + properties (Constant) + end + + properties + list struct = [] + selected struct = struct([]); + end + + methods + function reload(self, device) + self.list = []; + self.selected = struct(); + files = ls("protocols/*.m"); + for f = 1:size(files, 1) + file = files(f, 1:end); + name = strtrim(erase(file, ".m")); + fh = feval(name); + req = fh.requires(); + if ~self.iscompatible(req, device) + continue + end + idx = length(self.list) + 1; + self.list(idx).name = name; + self.list(idx).fh = fh; + self.list(idx).req = req; + end + end + + function r = iscompatible(~, req, dev) + % check device type + if req.devicetype ~= "ANY" && req.devicetype ~= dev.type + r = false; + return + end + % check channel requirements + for idx = 1:length(req.channels) + found = 0; + for lslch = 1:length(dev.lsl.channels) + if req.channels(idx).type == dev.lsl.channels(lslch).type && ... + req.channels(idx).unit == dev.lsl.channels(lslch).unit + found = found + 1; + end + end + if found < req.channels(idx).min + r = false; + return + end + end + r = true; + end + + function r = select(self, name) + for p = 1:length(self.list) + if self.list(p).name == name + self.selected = self.list(p); + r = true; + return + end + end + r = false; + end + end +end diff --git a/components/session.m b/components/session.m index ca38d0b..16af9ca 100644 --- a/components/session.m +++ b/components/session.m @@ -14,12 +14,16 @@ protocolavg double = 0.0; % avg tracked protocol exec time protocolsum double = 0.0; % sum tracked protocol exec time srate double = 0.0; % sample rate + device struct = struct(); % device used in session channels uint32 = []; % channel numbers - data double = zeros(0,0); % session data + fn cell = []; % field names in data and window + data struct = struct(); % session data + datasize uint32 = 0; % rows count in data times double = zeros(0); % timestamps of sesssion data idx uint32 = 0; % current index in data and times firsttime double = 0.0; % first time - window double = zeros(0,0); % current window + window struct = struct(); % current window + windowsize uint32 = 0; % rows count in window windowtimes double = zeros(0); % current window times windowidx uint32 = 0; % current index in window windownum uint32 = 1; % current window num @@ -32,7 +36,6 @@ study string = ""; % name of study subject uint32 = 1; % subject numer run uint32 = 1; % run number - ploth matlab.ui.Figure; end events @@ -43,36 +46,56 @@ end methods + %% Return Channel Counts for each Type + function r = countChannelTypes(self) + r = struct(); + lslchannels = self.device.lsl.channels; + numlslchannels = length(lslchannels); + for ch = self.channels + type = "unknown"; + if ch <= numlslchannels + type = lslchannels(ch).type; + end + if ~isfield(r, type) + r.(type) = 0; + end + r.(type) = r.(type) + 1; + end + end + %% Start a new session function r = start(self, protocol, lengthmax, window, srate, ... - channels, markerinfo, study, subject, run) + device, channels, markerinfo, study, subject, run) if self.running r = false; return; end - if isvalid(self.ploth) - close(self.ploth); - end - numrows = ceil(srate*lengthmax); - numcols = length(channels); - numrowswnd = ceil(srate*window); + self.datasize = ceil(srate*lengthmax); + self.windowsize = ceil(srate*window); self.running = true; self.protocol = protocol; self.protocolmax = 0.0; self.protocolavg = 0.0; self.protocolsum = 0.0; - self.lengthmax = lengthmax; + self.lengthmax = lengthmax; self.srate = srate; + self.device = device; self.channels = channels; - self.data = zeros(numrows, numcols); - self.times = zeros(numrows, 1); - self.feedback = zeros(numrows, 1); + counts = self.countChannelTypes(); + self.data = struct(); + self.window = struct(); + self.fn = fieldnames(counts); + for k = 1:numel(self.fn) + self.data.(self.fn{k}) = zeros(self.datasize, counts.(self.fn{k})); + self.window.(self.fn{k}) = zeros(self.windowsize, counts.(self.fn{k})); + end + self.times = zeros(self.datasize, 1); + self.feedback = zeros(self.datasize, 1); self.idx = 0; - self.window = zeros(numrowswnd, numcols); - self.windowtimes = zeros(numrowswnd, 1); + self.windowtimes = zeros(self.windowsize, 1); self.windowidx = 0; self.windownum = 1; - self.markers = zeros(numrows, 1); + self.markers = zeros(self.datasize, 1); self.markerinfo = markerinfo; self.marker = 0; self.bgcolor = [0 0 0]; @@ -84,6 +107,7 @@ self.starttime = now(); r = true; notify(self, "Started"); + self.update() end %% Stop a running session @@ -100,7 +124,6 @@ r = true; notify(self, "Stopped"); self.save(); - self.plot(); end @@ -134,7 +157,7 @@ function update(self) if ~epochfound; self.marker = 0.0; end if epochold ~= self.marker; notify(self, "Epoch"); end %% stop session if required samples are recorded - if self.idx >= length(self.data) + if self.idx >= self.datasize self.stop(); end %% stop session if time is up @@ -150,28 +173,47 @@ function pushSample(self, sample, ts) if ~self.running return; end - %% save timestamp of first sample + %% increment index for sample + self.idx = self.idx + 1; + %% save timestamp if self.firsttime == 0 self.firsttime = ts; end - relts = ts - self.firsttime; - %% add sample to data - self.idx = self.idx + 1; - self.data(self.idx,:) = sample; - self.times(self.idx,:) = relts; - self.markers(self.idx,:) = self.marker; - %% add sample to window - if self.windowidx < length(self.window) + relts = ts - self.firsttime; + %% shift window + if self.windowidx < self.windowsize self.windowidx = self.windowidx + 1; else - self.window = circshift(self.window, -1); + for k = 1:numel(self.fn) + self.window.(self.fn{k}) = ... + circshift(self.window.(self.fn{k}), -1); + end self.windowtimes = circshift(self.windowtimes, -1); end - self.window(self.windowidx,:) = sample; self.windowtimes(self.windowidx,:) = relts; + self.times(self.idx,:) = relts; + self.markers(self.idx,:) = self.marker; + %% add new sample to data and window + colidx = struct(); + lslchannels = self.device.lsl.channels; + numlslchannels = length(lslchannels); + for i = 1:length(self.channels) + type = "unknown"; + val = sample(i); + ch = self.channels(i); + if ch <= numlslchannels + type = lslchannels(ch).type; + end + if ~isfield(colidx, type) + colidx.(type) = 1; + end + self.data.(type)(self.idx, colidx.(type)) = val; + self.window.(type)(self.windowidx, colidx.(type)) = val; + colidx.(type) = colidx.(type) + 1; + end %% raise window event notify(self, "Window"); - if self.windowidx >= length(self.window) + if self.windowidx >= self.windowsize self.windownum = self.windownum + 1; end end @@ -198,44 +240,30 @@ function save(self) export.subject = self.subject; export.run = self.run; % meta info + export.device = self.device; export.protocol = self.protocol; export.samplerate = self.srate; export.channels = self.channels; export.starttime = datetime(self.starttime,'ConvertFrom','datenum'); export.stoptime = datetime(self.stoptime,'ConvertFrom','datenum'); export.duration = self.length; - export.windowsamples = length(self.window); + export.windowsamples = self.windowsize; % data + for k = 1:numel(self.fn) + export.data.(self.fn{k}) = self.data.(self.fn{k})(1:usedrows,:); + end export.times = self.times(1:usedrows,:); - export.data = self.data(1:usedrows,:); export.feedback = self.feedback(1:usedrows,:); export.marker = self.markers(1:usedrows,:); % export studyname = "unnamed"; - if self.study ~= ""; studyname = self.study; end + if self.study ~= ""; studyname = self.study; end filename = ... studyname + "-" + ... sprintf('%03d', self.subject) + "-" + ... - sprintf('%02d', self.run); + sprintf('%02d', self.run); save("./sessions/" + filename + ".mat", '-struct','export'); end - - function plot(self) - self.ploth = figure('Name', 'Session Plot'); - self.ploth.NumberTitle = 'off'; - nchannels = length(self.channels); - for i = (1:nchannels) - subplot(nchannels+2,1,i); - plot(self.data(:,i)); - title('Channel ' + string(self.channels(i))); - end - subplot(nchannels+2,1,nchannels+1); - plot(self.feedback(:,1)); - title('Feedback'); - subplot(nchannels+2,1,nchannels+2); - plot(self.markers(:,1)); - title('Marker'); - end end end diff --git a/devices/eeg_generic.json b/devices/eeg_generic.json new file mode 100644 index 0000000..e30301c --- /dev/null +++ b/devices/eeg_generic.json @@ -0,0 +1,8 @@ +{ + "name": "Generic", + "type": "EEG", + "lsl": { + "type": "", + "channels": [] + } +} diff --git a/devices/nirs_generic.json b/devices/nirs_generic.json new file mode 100644 index 0000000..d27271d --- /dev/null +++ b/devices/nirs_generic.json @@ -0,0 +1,8 @@ +{ + "name": "Generic", + "type": "NIRS", + "lsl": { + "type": "", + "channels": [] + } +} diff --git a/devices/nirs_nirx_nirsport2.json b/devices/nirs_nirx_nirsport2.json new file mode 100644 index 0000000..1d69478 --- /dev/null +++ b/devices/nirs_nirx_nirsport2.json @@ -0,0 +1,90 @@ +{ + "name": "nirX NIRSport2", + "type": "NIRS", + "lsl": { + "type": "NIRS", + "channels": [ + { "devch": 0, "type": "COUNTER", "unit": "" }, + { "devch": 1, "type": "WL760NM", "unit": "V" }, + { "devch": 2, "type": "WL760NM", "unit": "V" }, + { "devch": 3, "type": "WL760NM", "unit": "V" }, + { "devch": 4, "type": "WL760NM", "unit": "V" }, + { "devch": 5, "type": "WL760NM", "unit": "V" }, + { "devch": 6, "type": "WL760NM", "unit": "V" }, + { "devch": 7, "type": "WL760NM", "unit": "V" }, + { "devch": 8, "type": "WL760NM", "unit": "V" }, + { "devch": 9, "type": "WL760NM", "unit": "V" }, + { "devch": 10, "type": "WL760NM", "unit": "V" }, + { "devch": 11, "type": "WL760NM", "unit": "V" }, + { "devch": 12, "type": "WL760NM", "unit": "V" }, + { "devch": 13, "type": "WL760NM", "unit": "V" }, + { "devch": 14, "type": "WL760NM", "unit": "V" }, + { "devch": 15, "type": "WL760NM", "unit": "V" }, + { "devch": 16, "type": "WL760NM", "unit": "V" }, + { "devch": 17, "type": "WL760NM", "unit": "V" }, + { "devch": 18, "type": "WL760NM", "unit": "V" }, + { "devch": 19, "type": "WL760NM", "unit": "V" }, + { "devch": 20, "type": "WL760NM", "unit": "V" }, + { "devch": 1, "type": "WL850NM", "unit": "V" }, + { "devch": 2, "type": "WL850NM", "unit": "V" }, + { "devch": 3, "type": "WL850NM", "unit": "V" }, + { "devch": 4, "type": "WL850NM", "unit": "V" }, + { "devch": 5, "type": "WL850NM", "unit": "V" }, + { "devch": 6, "type": "WL850NM", "unit": "V" }, + { "devch": 7, "type": "WL850NM", "unit": "V" }, + { "devch": 8, "type": "WL850NM", "unit": "V" }, + { "devch": 9, "type": "WL850NM", "unit": "V" }, + { "devch": 10, "type": "WL850NM", "unit": "V" }, + { "devch": 11, "type": "WL850NM", "unit": "V" }, + { "devch": 12, "type": "WL850NM", "unit": "V" }, + { "devch": 13, "type": "WL850NM", "unit": "V" }, + { "devch": 14, "type": "WL850NM", "unit": "V" }, + { "devch": 15, "type": "WL850NM", "unit": "V" }, + { "devch": 16, "type": "WL850NM", "unit": "V" }, + { "devch": 17, "type": "WL850NM", "unit": "V" }, + { "devch": 18, "type": "WL850NM", "unit": "V" }, + { "devch": 19, "type": "WL850NM", "unit": "V" }, + { "devch": 20, "type": "WL850NM", "unit": "V" }, + { "devch": 1, "type": "HbO", "unit": "μmol/L" }, + { "devch": 2, "type": "HbO", "unit": "μmol/L" }, + { "devch": 3, "type": "HbO", "unit": "μmol/L" }, + { "devch": 4, "type": "HbO", "unit": "μmol/L" }, + { "devch": 5, "type": "HbO", "unit": "μmol/L" }, + { "devch": 6, "type": "HbO", "unit": "μmol/L" }, + { "devch": 7, "type": "HbO", "unit": "μmol/L" }, + { "devch": 8, "type": "HbO", "unit": "μmol/L" }, + { "devch": 9, "type": "HbO", "unit": "μmol/L" }, + { "devch": 10, "type": "HbO", "unit": "μmol/L" }, + { "devch": 11, "type": "HbO", "unit": "μmol/L" }, + { "devch": 12, "type": "HbO", "unit": "μmol/L" }, + { "devch": 13, "type": "HbO", "unit": "μmol/L" }, + { "devch": 14, "type": "HbO", "unit": "μmol/L" }, + { "devch": 15, "type": "HbO", "unit": "μmol/L" }, + { "devch": 16, "type": "HbO", "unit": "μmol/L" }, + { "devch": 17, "type": "HbO", "unit": "μmol/L" }, + { "devch": 18, "type": "HbO", "unit": "μmol/L" }, + { "devch": 19, "type": "HbO", "unit": "μmol/L" }, + { "devch": 20, "type": "HbO", "unit": "μmol/L" }, + { "devch": 1, "type": "HbR", "unit": "μmol/L" }, + { "devch": 2, "type": "HbR", "unit": "μmol/L" }, + { "devch": 3, "type": "HbR", "unit": "μmol/L" }, + { "devch": 4, "type": "HbR", "unit": "μmol/L" }, + { "devch": 5, "type": "HbR", "unit": "μmol/L" }, + { "devch": 6, "type": "HbR", "unit": "μmol/L" }, + { "devch": 7, "type": "HbR", "unit": "μmol/L" }, + { "devch": 8, "type": "HbR", "unit": "μmol/L" }, + { "devch": 9, "type": "HbR", "unit": "μmol/L" }, + { "devch": 10, "type": "HbR", "unit": "μmol/L" }, + { "devch": 11, "type": "HbR", "unit": "μmol/L" }, + { "devch": 12, "type": "HbR", "unit": "μmol/L" }, + { "devch": 13, "type": "HbR", "unit": "μmol/L" }, + { "devch": 14, "type": "HbR", "unit": "μmol/L" }, + { "devch": 15, "type": "HbR", "unit": "μmol/L" }, + { "devch": 16, "type": "HbR", "unit": "μmol/L" }, + { "devch": 17, "type": "HbR", "unit": "μmol/L" }, + { "devch": 18, "type": "HbR", "unit": "μmol/L" }, + { "devch": 19, "type": "HbR", "unit": "μmol/L" }, + { "devch": 20, "type": "HbR", "unit": "μmol/L" } + ] + } +} diff --git a/main.m b/main.m index 4832b5d..ee296be 100644 --- a/main.m +++ b/main.m @@ -19,14 +19,20 @@ % globals global mylsl; global mysession; +global mydevices; +global myprotocols; +global myselectchannels; global mysettings; global myfeedback; % init globals -mylsl = lsl(); -mysession = session(); -mysettings = app(); -myfeedback = feedback(); +mylsl = lsl(); +mysession = session(); +mydevices = devices(); +myprotocols = protocols(); +myselectchannels = selectchannels(); +mysettings = app(); +myfeedback = feedback(); % add listeners to lsl lhsample = addlistener(mylsl, "NewSample", @onNewSample); @@ -72,21 +78,25 @@ function onNewSample(src, ~) mysession.update(); end -function onSessionStarted(~, ~) +function onSessionStarted(src, ~) global mylsl; global myfeedback; + global myprotocols; mylsl.marker = 0; mylsl.trigger(100); myfeedback.showBar(); + myprotocols.selected.fh.init(); end function onSessionStopped(src, ~) global mylsl; global myfeedback; + global myprotocols; mylsl.marker = 0; mylsl.trigger(101); myfeedback.setBackground(src.bgcolor); myfeedback.hideBar(); + myprotocols.selected.fh.finish(src); end function onSessionEpoch(src, ~) @@ -103,21 +113,29 @@ function onSessionEpoch(src, ~) function onSessionWindow(src, ~) global myfeedback; + global myprotocols; prevfeedback = 0.5; if src.idx > 1 prevfeedback = src.feedback(src.idx-1); end + prevmarker = 0; + if src.idx > 1 + prevmarker = src.markers(src.idx-1); + end + tick = tic(); - r = feval (src.protocol, ... + r = myprotocols.selected.fh.process (... src.marker, src.srate, ... - src.idx, src.data(src.idx,:), ... + src.idx, src.data, ... src.windownum, src.window, ... - src.windowidx >= length(src.window), ... - prevfeedback); + src.windowidx >= src.windowsize, ... + prevfeedback, prevmarker); span = toc(tick); + r = min(max(r,0.0),1.0); + myfeedback.setFeedback(r); src.pushFeedback(r, span); end diff --git a/protocols/Gauss.m b/protocols/Gauss.m new file mode 100644 index 0000000..62f1622 --- /dev/null +++ b/protocols/Gauss.m @@ -0,0 +1,189 @@ +function fh = Gauss + fh.requires = @requires; + fh.init = @init; + fh.process = @process; + fh.finish = @finish; +end + +% REQUIREMENTS FOR PROTOCOL +function r = requires() + r.devicetype = "NIRS"; + % required window min and max durations + r.window.mins = 1.0; + r.window.maxs = 10.0; + % requires at least one HbO channel + r.channels(1).type = "HbO"; + r.channels(1).unit = "μmol/L"; + r.channels(1).min = 1; + r.channels(1).max = 64; + % HbR is optional + r.channels(2).type = "HbR"; + r.channels(2).unit = "μmol/L"; + r.channels(2).min = 0; + r.channels(2).max = 64; +end + +% EXECUTED ONCE ON START +function init() + global Filter + ordine = 15; + cutoff = 0.022; + Filter = gaussfir(cutoff, ordine); +end + +% EXECUTED FOR EACH SLIDING WINDOW +function r = process(... + marker, samplerate, samplenum, data, ... + windownum, window, isfullwindow, ... + prevfeedback, prevmarker) + + % IMPORTANT: + % Your algorithm must take less than (1/samplerate) seconds + % in average or else you fall behind schedule and get a drift. + % If you're algorithm requires more time than that then + % run your calculation on every n-th window only and + % repeat your previous feedback for all other windows. + global CounterRS + global DataRS + global RestValue + global Correction + global Filter + + % CONSTANTS + EXPECTED_AMPLITUDE = 0.1; + EXPECTED_MIN_DIFF = -0.4; + EXPECTED_MAX_DIFF = 0.4; + + r = 0.5; % default return + tick = tic(); % start time of execution + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + if marker == 2 + %% RESTING PHASE + + % reset on switch + if prevmarker ~= 2 + CounterRS = 0; + DataRS = []; + end + + % saving the HbO values of the last sample + CounterRS = CounterRS + 1; + DataRS(CounterRS,:) = window.HbO(end,:); + %disp(CounterRS) + + % 5 frames before 30 seconds of rest (to avoid final delays) + if CounterRS == floor(samplerate*30)-5 + %% CALCULATE CORRECTION FACTOR USING AMPLITUDE + % (1) Extract last ~15s of HbO channels of resting phase + % (2) Filter each HbO channel + % (3) Create average HbO channel from all filtered HbO channels + % (4) Sort average HbO channel + % (5) Calculate amplitude using mean of highest and lowest + filtered = DataRS(floor(samplerate*15):end,:); + for ch = 1:size(filtered,2) + filtered(:,ch) = conv(filtered(:,ch), Filter, 'same'); + end + mean_hbo = mean(filtered,2); + mean_hbo = sort(mean_hbo); + mean_top25 = mean(mean_hbo(end-35:end-10)); + mean_low25 = mean(mean_hbo(10:35)); + amplitude = abs(mean_top25 - mean_low25); + Correction = EXPECTED_AMPLITUDE / amplitude; + %disp("Amplitude: " + sprintf('%.3f', amplitude)); + %disp("Correction: " + sprintf('%.3f', Correction)); + + %% AVERAGE OF HBO OF LAST ~5S OF RESTING PHASE + DataFilt = DataRS(floor(samplerate*25):end,:); + for ch = 1:size(DataFilt,2) + DataFilt(:,ch) = conv(DataFilt(:,ch), Filter, 'same'); + end + RestValue = mean(mean(DataFilt,2)); + %disp("Rest Average: " + sprintf('%.3f', RestValue)); + end + + elseif marker == 3 + %% CONCENTRATION PHASE + + % filter each HbO channel in current sliding window + for ch = 1:size(window.HbO,2) + DataFilt(:,ch) = conv(window.HbO(:,ch), Filter, 'same'); + end + + % calculate mean HbO channel and mean HbO over time + mean_hbo = mean(mean(DataFilt,1)); + + % feedback is difference in HbO scaled by correction + feedback = mean_hbo - RestValue; + feedback = feedback * Correction; + + % convert from expected range to [0,1] using + % r = (((X-a)*(d-c)) / (b-a)) + c + % (a, b) = initial interval + % (c, d) = final interval + r = (((feedback-EXPECTED_MIN_DIFF)*(1.0-0.0)) / ... + (EXPECTED_MAX_DIFF-EXPECTED_MIN_DIFF)) + 0.0; + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % time spent + span = toc(tick); + + % create debug output + output = ... + "| sample=" + sprintf('%05d', samplenum) + " " + ... + "| window=" + sprintf('%05d', windownum) + " " + ... + "| marker=" + sprintf('%02d', marker) + " " + ... + "| duration=" + sprintf('%.3f', span)+"s" + " " + ... + "| feedback=" + sprintf('%.3f', r) + " "; + + % add values for marker=3 + if marker == 3 + output = output + ... + "| restavg=" + sprintf('%.3f', RestValue) + " " + ... + "| wndavg=" + sprintf('%.3f', mean_hbo) + " " + ... + "| correction=" + sprintf('%.3f', Correction) + " "; + end + + % show debug output + disp(output + "|"); +end + +% EXECUTED AT THE END OF THE SESSION +function finish(session) + ploth = figure('Name', 'Session Plot'); + ploth.NumberTitle = 'off'; + + nplot = 1; % Current one + nplots = 3; % HbO, Feedback, Marker + if isfield(session.data, "HbR") + nplots = 4; % + HbR + end + + % Plotting unfiltered HbO mean channel + subplot(nplots,1,nplot); + plot(mean(session.data.HbO,2),'r'); + title('HbO [μmol/L]'); + + % Plotting unfiltered HbR mean channel (optional) + if isfield(session.data, "HbR") + nplot = nplot + 1; + subplot(nplots,1,nplot); + plot(mean(session.data.HbR,2),'b'); + title('HbR [μmol/L]'); + end + + % Plotting Feedback values + nplot = nplot + 1; + subplot(nplots,1,nplot); + plot(session.feedback(:,1)); + title('Feedback'); + + % Plotting Marker Values + nplot = nplot + 1; + subplot(nplots,1,nplot); + plot(session.markers(:,1)); + title('Marker'); +end diff --git a/protocols/RecordOnly.m b/protocols/RecordOnly.m new file mode 100644 index 0000000..7116cbe --- /dev/null +++ b/protocols/RecordOnly.m @@ -0,0 +1,52 @@ +function fh = RecordOnly + fh.requires = @requires; + fh.init = @init; + fh.process = @process; + fh.finish = @finish; +end + +% REQUIREMENTS FOR PROTOCOL +function r = requires() + r.devicetype = "ANY"; + r.window.mins = 1.0; + r.window.maxs = 300.0; + r.channels = struct([]); +end + +% EXECUTED ONCE ON START +function init() +end + +% EXECUTED FOR EACH SLIDING WINDOW +function r = process(~, ~, ~, ~, ~, ~, ~, ~, ~) + r = 0.0; +end + +% EXECUTED AT THE END OF THE SESSION +function finish(session) + ploth = figure('Name', 'Session Plot'); + ploth.NumberTitle = 'off'; + nchannels = length(session.channels); + nplots = nchannels+2; + + iplots = 1; + fn = fieldnames(session.data); %TODO: Cache this + for k = 1:numel(fn) + for i = 1:size(session.data.(fn{k}), 2) + subplot(nplots,1,iplots); + plot(session.data.(fn{k})(:,i)); + title('Channel'); + iplots = iplots + 1; + end + + end + + % Plotting Feedback values + subplot(nplots,1,nchannels+1); + plot(session.feedback(:,1)); + title('Feedback'); + % Plotting Marker Values + subplot(nplots,1,nchannels+2); + plot(session.markers(:,1)); + title('Marker'); +end diff --git a/protocols/example1.m b/protocols/example1.m deleted file mode 100644 index 91825b8..0000000 --- a/protocols/example1.m +++ /dev/null @@ -1,57 +0,0 @@ -% Example Algorithm 1 for Demonstration -% marker: current epoch marker -% samplerate: sample rate -% samplenum: current sample number -% sample: current sample values -% windownum: current window number -% window: current window values -% isfullwindow: true once first window is filled -% prevfeedback: previous feedback -% RETURN: normalized value between 0.0 (min) and 1.0 (max) - -function r = example1(... - marker, samplerate, samplenum, sample, ... - windownum, window, isfullwindow, prevfeedback) - - % IMPORTANT: - % Your algorithm must take less than (1/samplerate) seconds - % in average or else you fall behind schedule and get a drift. - % If you're algorithm requires more time than that then - % run your calculation on every n-th window only and - % repeat your previous feedback for all other windows. - - n = 1; - tick = tic(); - - % custom feedback range - minfb = -100; - maxfb = 100; - - % return 0.5 until first full window - if ~isfullwindow - r = 0.5; - - % calculate on every n-th window - elseif mod(windownum, n) == 0 - % simulate 80% computation time (80ms of 100ms for 10Hz) - pause((1.0/double(samplerate))*0.8); - % create dummy feedback value in [minfb, maxfb] - r = double(randi([minfb,maxfb])); - % map from [minfb, maxfb] to [0, 1] - r = (r-minfb) * (1.0/(maxfb-minfb)); - - % skip this sample/window - else - r = prevfeedback; - end - - % time spent - span = toc(tick); - - % debug - disp("Processed sample " + samplenum + ... - " (window=" + windownum + ... - ", marker=" + marker + ... - ", duration=" + sprintf('%.3f', span) + "s" + ... - ", fb=" + sprintf('%.3f', r) + ")"); -end diff --git a/settings/Gauss.mat b/settings/Gauss.mat new file mode 100644 index 0000000000000000000000000000000000000000..6433732cc8f410004053fbb2b9e81a8fd0f5951a GIT binary patch literal 721 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 z000000RR91005A|limCwART%1Sdb?^=g3C@0Nqgl02%-Q000000000000027-IE^u LEC#V90RR910f)KC delta 62705 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 z00000009610002ct(PGv0U;nzbyZkbxp-1dGXMZoJpce20000000000000000O-b( S&D|WAekcJD25tHP0002UshhU| diff --git a/ui/app_exported.m b/ui/app_exported.m index dd08084..5be1d43 100644 --- a/ui/app_exported.m +++ b/ui/app_exported.m @@ -2,63 +2,69 @@ % Properties that correspond to app components properties (Access = public) - UIFigure matlab.ui.Figure - FileMenu matlab.ui.container.Menu - LoadMenu matlab.ui.container.Menu - SaveMenu matlab.ui.container.Menu - LSLSTREAMPanel matlab.ui.container.Panel - GridLayout matlab.ui.container.GridLayout - TYPELabel matlab.ui.control.Label - TYPEEditField matlab.ui.control.EditField - OPENButton matlab.ui.control.Button - CHANNELSLabel_2 matlab.ui.control.Label - CHANNELSFOUNDLabel matlab.ui.control.Label - SAMPLERATEDescLabel matlab.ui.control.Label - SAMPLERATELabel matlab.ui.control.Label - SETTINGSPanel matlab.ui.container.Panel - GridLayout2 matlab.ui.container.GridLayout - SELECTEDCHANNELSEditFieldLabel matlab.ui.control.Label - SELECTEDCHANNELSEditField matlab.ui.control.EditField - WINDOWSIZESEditFieldLabel matlab.ui.control.Label - WINDOWSIZESEditField matlab.ui.control.NumericEditField - SESSIONLENGTHSEditFieldLabel matlab.ui.control.Label - SESSIONLENGTHSEditField matlab.ui.control.NumericEditField - PROTOCOLLabel matlab.ui.control.Label - PROTOCOLDropDown matlab.ui.control.DropDown - STARTButton matlab.ui.control.Button - SESSIONINFOPanel matlab.ui.container.Panel - GridLayout3 matlab.ui.container.GridLayout - SESSIONSTARTEDDescLabel matlab.ui.control.Label - SESSIONSTARTEDLabel matlab.ui.control.Label - SESSIONENDEDDescLabel matlab.ui.control.Label - SESSIONENDEDLabel matlab.ui.control.Label - SESSIONLENGTHSDescLabel matlab.ui.control.Label - SESSIONLENGTHLabel matlab.ui.control.Label - SESSIONSAMPLESLabel matlab.ui.control.Label - SESSIONDRIFTLabel matlab.ui.control.Label - SESSIONSAMPLESDescLabel matlab.ui.control.Label - SESSIONDRIFTDescLabel matlab.ui.control.Label - SESSSIONSTATUSDescLabel matlab.ui.control.Label - SESSIONSTATUSLabel matlab.ui.control.Label - EPOCHSPanel matlab.ui.container.Panel - MARKERTable matlab.ui.control.Table - MARKERAddButton matlab.ui.control.Button - MARKERDelButton matlab.ui.control.Button - COLORButton matlab.ui.control.Button - IDPanel matlab.ui.container.Panel - GridLayout4 matlab.ui.container.GridLayout - SUBJECTEditFieldLabel matlab.ui.control.Label - SUBJECTEditField matlab.ui.control.NumericEditField - RUNEditFieldLabel matlab.ui.control.Label - RUNEditField matlab.ui.control.NumericEditField - STUDYEditFieldLabel matlab.ui.control.Label - STUDYEditField matlab.ui.control.EditField - PROTOCOLTIMEPanel matlab.ui.container.Panel - GridLayout5 matlab.ui.container.GridLayout - PROTOCOLMaxLabel matlab.ui.control.Label - PROTOCOLMaxDescLabel matlab.ui.control.Label - PROTOCOLAvgLabel matlab.ui.control.Label - PROTOCOLAvgDescLabel matlab.ui.control.Label + UIFigure matlab.ui.Figure + FileMenu matlab.ui.container.Menu + LoadMenu matlab.ui.container.Menu + SaveMenu matlab.ui.container.Menu + LSLSTREAMPanel matlab.ui.container.Panel + GridLayout matlab.ui.container.GridLayout + TYPELabel matlab.ui.control.Label + TYPEEditField matlab.ui.control.EditField + OPENButton matlab.ui.control.Button + CHANNELSLabel_2 matlab.ui.control.Label + CHANNELSFOUNDLabel matlab.ui.control.Label + SAMPLERATEDescLabel matlab.ui.control.Label + SAMPLERATELabel matlab.ui.control.Label + SETTINGSPanel matlab.ui.container.Panel + GridLayout2 matlab.ui.container.GridLayout + WINDOWSIZESEditFieldLabel matlab.ui.control.Label + WINDOWSIZESEditField matlab.ui.control.NumericEditField + SESSIONLENGTHSEditFieldLabel matlab.ui.control.Label + SESSIONLENGTHSEditField matlab.ui.control.NumericEditField + PROTOCOLLabel matlab.ui.control.Label + PROTOCOLDropDown matlab.ui.control.DropDown + CHANNELSButton matlab.ui.control.Button + CHANNELSLabel_3 matlab.ui.control.Label + STARTButton matlab.ui.control.Button + SESSIONINFOPanel matlab.ui.container.Panel + GridLayout3 matlab.ui.container.GridLayout + SESSIONSTARTEDDescLabel matlab.ui.control.Label + SESSIONSTARTEDLabel matlab.ui.control.Label + SESSIONENDEDDescLabel matlab.ui.control.Label + SESSIONENDEDLabel matlab.ui.control.Label + SESSIONLENGTHSDescLabel matlab.ui.control.Label + SESSIONLENGTHLabel matlab.ui.control.Label + SESSIONSAMPLESLabel matlab.ui.control.Label + SESSIONDRIFTLabel matlab.ui.control.Label + SESSIONSAMPLESDescLabel matlab.ui.control.Label + SESSIONDRIFTDescLabel matlab.ui.control.Label + SESSSIONSTATUSDescLabel matlab.ui.control.Label + SESSIONSTATUSLabel matlab.ui.control.Label + EPOCHSPanel matlab.ui.container.Panel + MARKERTable matlab.ui.control.Table + MARKERAddButton matlab.ui.control.Button + MARKERDelButton matlab.ui.control.Button + COLORButton matlab.ui.control.Button + IDPanel matlab.ui.container.Panel + GridLayout4 matlab.ui.container.GridLayout + SUBJECTEditFieldLabel matlab.ui.control.Label + SUBJECTEditField matlab.ui.control.NumericEditField + RUNEditFieldLabel matlab.ui.control.Label + RUNEditField matlab.ui.control.NumericEditField + STUDYEditFieldLabel matlab.ui.control.Label + STUDYEditField matlab.ui.control.EditField + PROTOCOLTIMEPanel matlab.ui.container.Panel + GridLayout5 matlab.ui.container.GridLayout + PROTOCOLMaxLabel matlab.ui.control.Label + PROTOCOLMaxDescLabel matlab.ui.control.Label + PROTOCOLAvgLabel matlab.ui.control.Label + PROTOCOLAvgDescLabel matlab.ui.control.Label + DEVICEPanel matlab.ui.container.Panel + GridLayout6 matlab.ui.container.GridLayout + MODELDropDownLabel matlab.ui.control.Label + DEVICEDropDown matlab.ui.control.DropDown + TYPEDropDownLabel matlab.ui.control.Label + TYPEDropDown matlab.ui.control.DropDown end @@ -77,10 +83,10 @@ function onSessionStarted(app, src, ~) app.STARTButton.Text = "STOP"; app.LoadMenu.Enable = false; app.SaveMenu.Enable = false; - app.SELECTEDCHANNELSEditField.Enable = false; app.WINDOWSIZESEditField.Enable = false; app.SESSIONLENGTHSEditField.Enable = false; app.PROTOCOLDropDown.Enable = false; + app.CHANNELSButton.Enable = false; app.SUBJECTEditField.Enable = false; app.RUNEditField.Enable = false; app.STUDYEditField.Enable = false; @@ -99,10 +105,10 @@ function onSessionStopped(app, src, ~) app.STARTButton.Text = "START"; app.LoadMenu.Enable = true; app.SaveMenu.Enable = true; - app.SELECTEDCHANNELSEditField.Enable = true; app.WINDOWSIZESEditField.Enable = true; app.SESSIONLENGTHSEditField.Enable = true; app.PROTOCOLDropDown.Enable = true; + app.CHANNELSButton.Enable = true; app.SUBJECTEditField.Enable = true; app.RUNEditField.Enable = true; app.STUDYEditField.Enable = true; @@ -119,6 +125,9 @@ function onSessionStopped(app, src, ~) app.updateStatus(); end + function onChannelsSelected(app, ~, ~) + app.updateStartButton(); + end end methods (Access = public) @@ -147,7 +156,7 @@ function updateStatus(app) sprintf('%.2f', mysession.length) + " s"; app.SESSIONSAMPLESLabel.Text = ... string(mysession.idx) + "/" + ... - string(length(mysession.data)); + string(mysession.datasize); app.SESSIONDRIFTLabel.Text = ... sprintf('%.2f', drift) + " s"; if drift > 1.0 || drift < -1.0 @@ -165,7 +174,7 @@ function updateStatus(app) app.PROTOCOLAvgLabel.BackgroundColor = 'green'; end end - + function update(app) global mylsl global mysession @@ -189,6 +198,76 @@ function update(app) app.updateStatus(); end end + + function updateStartButton(app) + global myselectchannels + global mylsl + if ~mylsl.streaming + app.STARTButton.Text = "CONNECT LSL FIRST"; + app.STARTButton.Enable = false; + elseif ~myselectchannels.isok + app.STARTButton.Text = "SELECT CHANNELS FIRST"; + app.STARTButton.Enable = false; + else + app.STARTButton.Text = "START"; + app.STARTButton.Enable = true; + end + end + + function updateDevices(app) + global mydevices; + app.DEVICEDropDown.Items = {}; + type = lower(app.TYPEDropDown.Value); + for idx = 1:length(mydevices.(type)) + app.DEVICEDropDown.Items(idx) = ... + cellstr(mydevices.(type)(idx).name); + end + end + + function useDevice(app) + global mydevices; + global myprotocols; + type = convertCharsToStrings(app.TYPEDropDown.Value); + name = convertCharsToStrings(app.DEVICEDropDown.Value); + if mydevices.select(type, name) + disp("SELECTED DEVICE: " + mydevices.selected.name + ... + "(" + mydevices.selected.type + ")"); + app.TYPEEditField.Value = mydevices.selected.lsl.type; + myprotocols.reload(mydevices.selected); + app.PROTOCOLDropDown.Items = {}; + for idx = 1:length(myprotocols.list) + app.PROTOCOLDropDown.Items(idx) = ... + cellstr(myprotocols.list(idx).name); + end + app.useProtocol(); + end + end + + function useProtocol(app) + global myprotocols; + global myselectchannels; + name = convertCharsToStrings(app.PROTOCOLDropDown.Value); + if myprotocols.select(name) + disp("SELECTED PROTOCOL: " + myprotocols.selected.name) + myselectchannels.selected = []; + myselectchannels.initRequired(); + myselectchannels.initSelected(); + end + app.checkWindowSize(); + app.updateStartButton(); + end + + function checkWindowSize(app) + global myprotocols + v = app.WINDOWSIZESEditField.Value; + if ~isempty(myprotocols.selected) + r = myprotocols.selected.fh.requires(); + v = min(max(v, r.window.mins), r.window.maxs); + end + if app.WINDOWSIZESEditField.Value ~= v + app.WINDOWSIZESEditField.Value = v; + end + end end @@ -198,10 +277,16 @@ function update(app) % Code that executes after component creation function startupFcn(app) global mysession; - app.UIFigure.Name = "Settings"; + global myselectchannels; + app.UIFigure.Name = "NINFA v1.1.0"; addlistener(mysession, "Started", @app.onSessionStarted); addlistener(mysession, "Stopped", @app.onSessionStopped); - app.PROTOCOLDropDown.Items = string(ls("protocols/*.m")); + addlistener(myselectchannels, "Done", @app.onChannelsSelected); + for idx = 1:length(devices.types) + app.TYPEDropDown.Items(idx) = cellstr(devices.types(idx)); + end + app.updateDevices(); + app.useDevice(); app.MARKERTable.SelectionType = 'row'; app.MARKERTable.ColumnFormat = { 'short', 'short', 'short', 'logical', 'short', 'short', 'short' }; @@ -210,27 +295,29 @@ function startupFcn(app) % Button pushed function: OPENButton function OPENButtonPushed(app, event) global mylsl + global myselectchannels if ~mylsl.streaming r = mylsl.open(app.TYPEEditField.Value); if r app.tick = tic(); app.OPENButton.Text = "CLOSE"; + app.TYPEDropDown.Enable = false; + app.DEVICEDropDown.Enable = false; app.TYPEEditField.Enable = false; app.CHANNELSFOUNDLabel.Text = int2str(mylsl.lslchannels); - app.SELECTEDCHANNELSEditField.Enable = true; app.WINDOWSIZESEditField.Enable = true; app.SESSIONLENGTHSEditField.Enable = true; app.PROTOCOLDropDown.Enable = true; app.SUBJECTEditField.Enable = true; app.RUNEditField.Enable = true; - app.STUDYEditField.Enable = true; + app.STUDYEditField.Enable = true; + app.CHANNELSButton.Enable = true; app.MARKERTable.Enable = 'on'; app.MARKERAddButton.Enable = true; if size(app.MARKERTable.Data,1) > 0 app.MARKERDelButton.Enable = true; app.COLORButton.Enable = true; end - app.STARTButton.Enable = true; else msgbox("No LSL stream with type '" + ... app.TYPEEditField.Value + ... @@ -238,33 +325,38 @@ function OPENButtonPushed(app, event) end else mylsl.close(); + myselectchannels.close(); app.OPENButton.Text = "OPEN"; app.CHANNELSFOUNDLabel.Text = "-"; app.SAMPLERATELabel.Text = "-"; + app.TYPEDropDown.Enable = true; + app.DEVICEDropDown.Enable = true; app.TYPEEditField.Enable = true; - app.SELECTEDCHANNELSEditField.Enable = false; app.WINDOWSIZESEditField.Enable = false; app.SESSIONLENGTHSEditField.Enable = false; app.PROTOCOLDropDown.Enable = false; app.SUBJECTEditField.Enable = false; app.RUNEditField.Enable = false; app.STUDYEditField.Enable = false; + app.CHANNELSButton.Enable = false; app.MARKERTable.Enable = 'off'; app.MARKERAddButton.Enable = false; app.MARKERDelButton.Enable = false; app.COLORButton.Enable = false; - app.STARTButton.Enable = false; app.SAMPLERATELabel.BackgroundColor = 'none'; end + app.updateStartButton(); end % Button pushed function: STARTButton function STARTButtonPushed(app, event) global mylsl; global mysession; + global myselectchannels; + global mydevices; if ~mysession.running - strchannels = split(app.SELECTEDCHANNELSEditField.Value, ','); - channels = transpose(str2double(strchannels)); + channels = myselectchannels.selected; + device = mydevices.selected; srate = mylsl.sratenom; % prefer claimed samplerate if srate <= 0, srate = mylsl.srate; end % else use measured blocksize = app.WINDOWSIZESEditField.Value * srate; @@ -274,6 +366,7 @@ function STARTButtonPushed(app, event) app.SESSIONLENGTHSEditField.Value, ... app.WINDOWSIZESEditField.Value, ... srate, ... + device, ... channels, ... app.MARKERTable.Data, ... app.STUDYEditField.Value, ... @@ -285,26 +378,6 @@ function STARTButtonPushed(app, event) end - % Value changed function: SELECTEDCHANNELSEditField - function SELECTEDCHANNELSEditFieldValueChanged(app, event) - global mylsl; - newvalue = ""; - values = split(app.SELECTEDCHANNELSEditField.Value, ','); - for k = 1:length(values) - v = values{k}; - v = strip(v, ' '); - [x, s] = str2num(v); - if s && x > 0 && x <= mylsl.lslchannels - newvalue = newvalue + x + ','; - end - end - newvalue = strip(newvalue, ','); - if newvalue == "" - newvalue = "1"; - end - app.SELECTEDCHANNELSEditField.Value = newvalue; - end - % Button pushed function: MARKERAddButton function MARKERAddButtonPushed(app, event) app.MARKERTable.Data = [app.MARKERTable.Data;[0 0 1 1 0 0 0]]; @@ -336,6 +409,7 @@ function MARKERDelButtonPushed(app, event) % Menu selected function: LoadMenu function LoadMenuSelected(app, event) global mylsl; + global myselectchannels; [file, path] = uigetfile("./settings/*.mat"); figure(app.UIFigure); % focus back filepath = string(path) + string(file); @@ -343,11 +417,24 @@ function LoadMenuSelected(app, event) return; end settings = load(filepath); + if isfield(settings, 'devicetype') + app.TYPEDropDown.Value = settings.devicetype; + app.updateDevices(); + end + if isfield(settings, 'devicename') + if any(strcmp(app.DEVICEDropDown.Items, settings.devicename)) + app.DEVICEDropDown.Value = settings.devicename; + app.useDevice(); + else + msgbox("Device '" + settings.devicename + ... + "' was not found on this computer", "Warning", "warn"); + end + end if isfield(settings, 'lsltype') app.TYPEEditField.Value = settings.lsltype; end if isfield(settings, 'channels') - app.SELECTEDCHANNELSEditField.Value = settings.channels; + myselectchannels.selected = settings.channels; end if isfield(settings, 'windowsize') app.WINDOWSIZESEditField.Value = settings.windowsize; @@ -358,6 +445,7 @@ function LoadMenuSelected(app, event) if isfield(settings, 'protocol') if any(strcmp(app.PROTOCOLDropDown.Items, settings.protocol)) app.PROTOCOLDropDown.Value = settings.protocol; + app.useProtocol(); else msgbox("Protocol '" + settings.protocol + ... "' was not found on this computer", "Warning", "warn"); @@ -383,14 +471,18 @@ function LoadMenuSelected(app, event) % Menu selected function: SaveMenu function SaveMenuSelected(app, event) + global mydevices; + global myselectchannels; [file, path] = uiputfile("./settings/*.mat"); figure(app.UIFigure); % focus back if isequal(file,0) || isequal(path,0) return; end filepath = string(path) + string(file); + settings.devicetype = mydevices.selected.type; + settings.devicename = mydevices.selected.name; settings.lsltype = app.TYPEEditField.Value; - settings.channels = app.SELECTEDCHANNELSEditField.Value; + settings.channels = myselectchannels.selected; settings.windowsize = app.WINDOWSIZESEditField.Value; settings.sessionlength = app.SESSIONLENGTHSEditField.Value; settings.protocol = app.PROTOCOLDropDown.Value; @@ -429,6 +521,35 @@ function COLORButtonPushed(app, event) end app.updateColors(); end + + % Value changed function: DEVICEDropDown + function DEVICEDropDownValueChanged(app, event) + app.useDevice(); + end + + % Value changed function: TYPEDropDown + function TYPEDropDownValueChanged(app, event) + app.updateDevices(); + app.useDevice(); + end + + % Button pushed function: CHANNELSButton + function CHANNELSButtonPushed(app, event) + global myselectchannels; + myselectchannels.show(); + %myselectchannels.initRequired(); + %myselectchannels.initSelected(); + end + + % Value changed function: PROTOCOLDropDown + function PROTOCOLDropDownValueChanged(app, event) + app.useProtocol(); + end + + % Value changed function: WINDOWSIZESEditField + function WINDOWSIZESEditFieldValueChanged(app, event) + app.checkWindowSize(); + end end % Component initialization @@ -440,7 +561,7 @@ function createComponents(app) % Create UIFigure and hide until all components are created app.UIFigure = uifigure('Visible', 'off'); app.UIFigure.AutoResizeChildren = 'off'; - app.UIFigure.Position = [100 100 653 680]; + app.UIFigure.Position = [100 100 640 772]; app.UIFigure.Name = 'MATLAB App'; app.UIFigure.Resize = 'off'; @@ -462,11 +583,11 @@ function createComponents(app) app.LSLSTREAMPanel = uipanel(app.UIFigure); app.LSLSTREAMPanel.AutoResizeChildren = 'off'; app.LSLSTREAMPanel.Title = 'LSL STREAM'; - app.LSLSTREAMPanel.Position = [16 510 625 156]; + app.LSLSTREAMPanel.Position = [16 541 608 118]; % Create GridLayout app.GridLayout = uigridlayout(app.LSLSTREAMPanel); - app.GridLayout.ColumnWidth = {'1.5x', '2x', '1x'}; + app.GridLayout.ColumnWidth = {'1.32x', '2x', '1x'}; app.GridLayout.RowHeight = {'1x', '1x', '1x'}; % Create TYPELabel @@ -480,7 +601,6 @@ function createComponents(app) app.TYPEEditField = uieditfield(app.GridLayout, 'text'); app.TYPEEditField.Layout.Row = 1; app.TYPEEditField.Layout.Column = 2; - app.TYPEEditField.Value = 'NIRS'; % Create OPENButton app.OPENButton = uibutton(app.GridLayout, 'push'); @@ -519,48 +639,35 @@ function createComponents(app) app.SETTINGSPanel = uipanel(app.UIFigure); app.SETTINGSPanel.AutoResizeChildren = 'off'; app.SETTINGSPanel.Title = 'SETTINGS'; - app.SETTINGSPanel.Position = [16 340 375 157]; + app.SETTINGSPanel.Position = [16 363 375 165]; % Create GridLayout2 app.GridLayout2 = uigridlayout(app.SETTINGSPanel); app.GridLayout2.RowHeight = {'1x', '1x', '1x', '1x'}; - % Create SELECTEDCHANNELSEditFieldLabel - app.SELECTEDCHANNELSEditFieldLabel = uilabel(app.GridLayout2); - app.SELECTEDCHANNELSEditFieldLabel.HorizontalAlignment = 'center'; - app.SELECTEDCHANNELSEditFieldLabel.Layout.Row = 1; - app.SELECTEDCHANNELSEditFieldLabel.Layout.Column = 1; - app.SELECTEDCHANNELSEditFieldLabel.Text = 'SELECTED CHANNELS'; - - % Create SELECTEDCHANNELSEditField - app.SELECTEDCHANNELSEditField = uieditfield(app.GridLayout2, 'text'); - app.SELECTEDCHANNELSEditField.ValueChangedFcn = createCallbackFcn(app, @SELECTEDCHANNELSEditFieldValueChanged, true); - app.SELECTEDCHANNELSEditField.Enable = 'off'; - app.SELECTEDCHANNELSEditField.Tooltip = {'Enter comma separated numeric values larger than zero and less or equal to LSL channels.'}; - app.SELECTEDCHANNELSEditField.Layout.Row = 1; - app.SELECTEDCHANNELSEditField.Layout.Column = 2; - app.SELECTEDCHANNELSEditField.Value = '2'; - % Create WINDOWSIZESEditFieldLabel app.WINDOWSIZESEditFieldLabel = uilabel(app.GridLayout2); app.WINDOWSIZESEditFieldLabel.HorizontalAlignment = 'center'; - app.WINDOWSIZESEditFieldLabel.Layout.Row = 2; + app.WINDOWSIZESEditFieldLabel.FontSize = 11; + app.WINDOWSIZESEditFieldLabel.Layout.Row = 3; app.WINDOWSIZESEditFieldLabel.Layout.Column = 1; app.WINDOWSIZESEditFieldLabel.Text = 'WINDOW SIZE (S)'; % Create WINDOWSIZESEditField app.WINDOWSIZESEditField = uieditfield(app.GridLayout2, 'numeric'); app.WINDOWSIZESEditField.Limits = [0 3600]; + app.WINDOWSIZESEditField.ValueChangedFcn = createCallbackFcn(app, @WINDOWSIZESEditFieldValueChanged, true); app.WINDOWSIZESEditField.HorizontalAlignment = 'left'; app.WINDOWSIZESEditField.Enable = 'off'; - app.WINDOWSIZESEditField.Layout.Row = 2; + app.WINDOWSIZESEditField.Layout.Row = 3; app.WINDOWSIZESEditField.Layout.Column = 2; - app.WINDOWSIZESEditField.Value = 2; + app.WINDOWSIZESEditField.Value = 1; % Create SESSIONLENGTHSEditFieldLabel app.SESSIONLENGTHSEditFieldLabel = uilabel(app.GridLayout2); app.SESSIONLENGTHSEditFieldLabel.HorizontalAlignment = 'center'; - app.SESSIONLENGTHSEditFieldLabel.Layout.Row = 3; + app.SESSIONLENGTHSEditFieldLabel.FontSize = 11; + app.SESSIONLENGTHSEditFieldLabel.Layout.Row = 4; app.SESSIONLENGTHSEditFieldLabel.Layout.Column = 1; app.SESSIONLENGTHSEditFieldLabel.Text = 'SESSION LENGTH (S)'; @@ -569,43 +676,60 @@ function createComponents(app) app.SESSIONLENGTHSEditField.Limits = [0 3600]; app.SESSIONLENGTHSEditField.HorizontalAlignment = 'left'; app.SESSIONLENGTHSEditField.Enable = 'off'; - app.SESSIONLENGTHSEditField.Layout.Row = 3; + app.SESSIONLENGTHSEditField.Layout.Row = 4; app.SESSIONLENGTHSEditField.Layout.Column = 2; app.SESSIONLENGTHSEditField.Value = 10; % Create PROTOCOLLabel app.PROTOCOLLabel = uilabel(app.GridLayout2); app.PROTOCOLLabel.HorizontalAlignment = 'center'; - app.PROTOCOLLabel.Layout.Row = 4; + app.PROTOCOLLabel.FontSize = 11; + app.PROTOCOLLabel.Layout.Row = 1; app.PROTOCOLLabel.Layout.Column = 1; app.PROTOCOLLabel.Text = 'PROTOCOL'; % Create PROTOCOLDropDown app.PROTOCOLDropDown = uidropdown(app.GridLayout2); app.PROTOCOLDropDown.Items = {}; + app.PROTOCOLDropDown.ValueChangedFcn = createCallbackFcn(app, @PROTOCOLDropDownValueChanged, true); app.PROTOCOLDropDown.Enable = 'off'; app.PROTOCOLDropDown.Tooltip = {'Select the Matlab file that should be executed on each window calculating the next feedback. '}; - app.PROTOCOLDropDown.Layout.Row = 4; + app.PROTOCOLDropDown.Layout.Row = 1; app.PROTOCOLDropDown.Layout.Column = 2; app.PROTOCOLDropDown.Value = {}; + % Create CHANNELSButton + app.CHANNELSButton = uibutton(app.GridLayout2, 'push'); + app.CHANNELSButton.ButtonPushedFcn = createCallbackFcn(app, @CHANNELSButtonPushed, true); + app.CHANNELSButton.Enable = 'off'; + app.CHANNELSButton.Layout.Row = 2; + app.CHANNELSButton.Layout.Column = 2; + app.CHANNELSButton.Text = 'SELECT'; + + % Create CHANNELSLabel_3 + app.CHANNELSLabel_3 = uilabel(app.GridLayout2); + app.CHANNELSLabel_3.HorizontalAlignment = 'center'; + app.CHANNELSLabel_3.Layout.Row = 2; + app.CHANNELSLabel_3.Layout.Column = 1; + app.CHANNELSLabel_3.Text = 'CHANNELS'; + % Create STARTButton app.STARTButton = uibutton(app.UIFigure, 'push'); app.STARTButton.ButtonPushedFcn = createCallbackFcn(app, @STARTButtonPushed, true); app.STARTButton.Enable = 'off'; app.STARTButton.Tooltip = {'Start or stop session'}; - app.STARTButton.Position = [17 13 622 22]; + app.STARTButton.Position = [16 19 608 22]; app.STARTButton.Text = 'START'; % Create SESSIONINFOPanel app.SESSIONINFOPanel = uipanel(app.UIFigure); app.SESSIONINFOPanel.AutoResizeChildren = 'off'; app.SESSIONINFOPanel.Title = 'SESSION INFO'; - app.SESSIONINFOPanel.Position = [17 48 473 115]; + app.SESSIONINFOPanel.Position = [17 56 473 115]; % Create GridLayout3 app.GridLayout3 = uigridlayout(app.SESSIONINFOPanel); - app.GridLayout3.ColumnWidth = {'0.75x', '1x', '0.75x', '1x'}; + app.GridLayout3.ColumnWidth = {'0.7x', '1x', '0.7x', '1x'}; app.GridLayout3.RowHeight = {'1x', '1x', '1x'}; % Create SESSIONSTARTEDDescLabel @@ -693,7 +817,7 @@ function createComponents(app) app.EPOCHSPanel = uipanel(app.UIFigure); app.EPOCHSPanel.AutoResizeChildren = 'off'; app.EPOCHSPanel.Title = 'EPOCHS'; - app.EPOCHSPanel.Position = [16 175 625 157]; + app.EPOCHSPanel.Position = [16 185 608 162]; % Create MARKERTable app.MARKERTable = uitable(app.EPOCHSPanel); @@ -704,14 +828,14 @@ function createComponents(app) app.MARKERTable.CellEditCallback = createCallbackFcn(app, @MARKERTableCellEdit, true); app.MARKERTable.Tooltip = {'Define markers (a value between 1 and 99) for epochs here. An epoch is defined by its start and end time. A trigger will be sent at the beginning of each epoch.'}; app.MARKERTable.Enable = 'off'; - app.MARKERTable.Position = [11 8 494 120]; + app.MARKERTable.Position = [11 13 484 120]; % Create MARKERAddButton app.MARKERAddButton = uibutton(app.EPOCHSPanel, 'push'); app.MARKERAddButton.ButtonPushedFcn = createCallbackFcn(app, @MARKERAddButtonPushed, true); app.MARKERAddButton.Enable = 'off'; app.MARKERAddButton.Tooltip = {'Add an epoch'}; - app.MARKERAddButton.Position = [513 94 100 34]; + app.MARKERAddButton.Position = [504 99 93 34]; app.MARKERAddButton.Text = '+'; % Create MARKERDelButton @@ -719,7 +843,7 @@ function createComponents(app) app.MARKERDelButton.ButtonPushedFcn = createCallbackFcn(app, @MARKERDelButtonPushed, true); app.MARKERDelButton.Enable = 'off'; app.MARKERDelButton.Tooltip = {'Remove last or selected epochs'}; - app.MARKERDelButton.Position = [513 51 100 34]; + app.MARKERDelButton.Position = [504 56 93 34]; app.MARKERDelButton.Text = '-'; % Create COLORButton @@ -727,14 +851,14 @@ function createComponents(app) app.COLORButton.ButtonPushedFcn = createCallbackFcn(app, @COLORButtonPushed, true); app.COLORButton.Enable = 'off'; app.COLORButton.Tooltip = {'Select color for selected epochs'}; - app.COLORButton.Position = [513 8 100 34]; + app.COLORButton.Position = [504 13 93 34]; app.COLORButton.Text = 'COLOR'; % Create IDPanel app.IDPanel = uipanel(app.UIFigure); app.IDPanel.AutoResizeChildren = 'off'; app.IDPanel.Title = 'ID'; - app.IDPanel.Position = [400 340 241 157]; + app.IDPanel.Position = [401 363 223 164]; % Create GridLayout4 app.GridLayout4 = uigridlayout(app.IDPanel); @@ -789,7 +913,7 @@ function createComponents(app) app.PROTOCOLTIMEPanel = uipanel(app.UIFigure); app.PROTOCOLTIMEPanel.AutoResizeChildren = 'off'; app.PROTOCOLTIMEPanel.Title = 'PROTOCOL TIME'; - app.PROTOCOLTIMEPanel.Position = [500 48 141 115]; + app.PROTOCOLTIMEPanel.Position = [495 56 129 115]; % Create GridLayout5 app.GridLayout5 = uigridlayout(app.PROTOCOLTIMEPanel); @@ -823,6 +947,46 @@ function createComponents(app) app.PROTOCOLAvgDescLabel.Layout.Column = 1; app.PROTOCOLAvgDescLabel.Text = 'AVG:'; + % Create DEVICEPanel + app.DEVICEPanel = uipanel(app.UIFigure); + app.DEVICEPanel.AutoResizeChildren = 'off'; + app.DEVICEPanel.Title = 'DEVICE'; + app.DEVICEPanel.Position = [16 673 608 88]; + + % Create GridLayout6 + app.GridLayout6 = uigridlayout(app.DEVICEPanel); + app.GridLayout6.ColumnWidth = {'1.32x', '2x', '1x'}; + + % Create MODELDropDownLabel + app.MODELDropDownLabel = uilabel(app.GridLayout6); + app.MODELDropDownLabel.HorizontalAlignment = 'center'; + app.MODELDropDownLabel.Layout.Row = 2; + app.MODELDropDownLabel.Layout.Column = 1; + app.MODELDropDownLabel.Text = 'MODEL'; + + % Create DEVICEDropDown + app.DEVICEDropDown = uidropdown(app.GridLayout6); + app.DEVICEDropDown.Items = {}; + app.DEVICEDropDown.ValueChangedFcn = createCallbackFcn(app, @DEVICEDropDownValueChanged, true); + app.DEVICEDropDown.Layout.Row = 2; + app.DEVICEDropDown.Layout.Column = 2; + app.DEVICEDropDown.Value = {}; + + % Create TYPEDropDownLabel + app.TYPEDropDownLabel = uilabel(app.GridLayout6); + app.TYPEDropDownLabel.HorizontalAlignment = 'center'; + app.TYPEDropDownLabel.Layout.Row = 1; + app.TYPEDropDownLabel.Layout.Column = 1; + app.TYPEDropDownLabel.Text = 'TYPE'; + + % Create TYPEDropDown + app.TYPEDropDown = uidropdown(app.GridLayout6); + app.TYPEDropDown.Items = {}; + app.TYPEDropDown.ValueChangedFcn = createCallbackFcn(app, @TYPEDropDownValueChanged, true); + app.TYPEDropDown.Layout.Row = 1; + app.TYPEDropDown.Layout.Column = 2; + app.TYPEDropDown.Value = {}; + % Show the figure after all components are created app.UIFigure.Visible = 'on'; end diff --git a/ui/selectchannels.m b/ui/selectchannels.m new file mode 100644 index 0000000..cadcb8d --- /dev/null +++ b/ui/selectchannels.m @@ -0,0 +1,309 @@ +classdef selectchannels < handle + %LSL CHANNEL SELECTION + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + properties(Constant) + figwidth = 512; + figheight = 512; + padding = 8; + buttonheight = 24; + panelwidth = selectchannels.figwidth-2*selectchannels.padding; + tablewidth = selectchannels.panelwidth-2*selectchannels.padding; + panelheightrequired = 128; + panelheightchannels = selectchannels.figheight - ... + 4*selectchannels.padding - ... + selectchannels.panelheightrequired - ... + selectchannels.buttonheight; + tableheightrequired = selectchannels.panelheightrequired - ... + 2*selectchannels.padding - 16; + tableheightchannels = selectchannels.panelheightchannels - ... + 2*selectchannels.padding - 16; + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + properties + hFig matlab.ui.Figure; + hRequiredPanel matlab.ui.container.Panel; + hChannelsPanel matlab.ui.container.Panel; + hRequired matlab.ui.control.Table; + hChannels matlab.ui.control.Table; + hButton matlab.ui.control.Button; + hStyleOk matlab.ui.style.Style; + hStyleNotOk matlab.ui.style.Style; + selected uint32 = []; + isok logical = false; + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + events + Done + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + methods (Access = private) + + % returns true if channel matches a requirement or no requirements + function r = isChannelVisible(self, channel) + lenreqs = size(self.hRequired.Data, 1); + if lenreqs == 0 + r = true; + return + end + for idx = 1:lenreqs + if self.hRequired.Data(idx, 4) == channel.type && ... + self.hRequired.Data(idx, 5) == channel.unit + r = true; + return; + end + end + r = false; + end + + % updates ok status + function updateOK(self) + global myprotocols; + global mydevices; + chreq = myprotocols.selected.fh.requires().channels; + chlsl = mydevices.selected.lsl.channels; + self.isok = ~isempty(self.selected); + for idxreq = 1:length(chreq) + found = 0; + for idxlsl = [self.selected] + if chreq(idxreq).type == chlsl(idxlsl).type && ... + chreq(idxreq).unit == chlsl(idxlsl).unit + found = found + 1; + end + end + min = chreq(idxreq).min; + max = chreq(idxreq).max; + if found < min || found > max + self.isok = false; + if isvalid(self.hRequired) + self.hRequired.Data(idxreq, 3) = found; + addStyle(self.hRequired, ... + self.hStyleNotOk, 'cell', [idxreq 3]); + end + else + if isvalid(self.hRequired) + self.hRequired.Data(idxreq, 3) = found; + addStyle(self.hRequired, ... + self.hStyleOk, 'cell', [idxreq 3]); + end + end + end + if isvalid(self.hChannelsPanel) + self.hChannelsPanel.Title = "SELECTED: " + ... + length(self.selected); + end + if isvalid(self.hButton) + self.hButton.Enable = self.isok; + end + end + + % executed when checkbox is changed + function onSelectedChanged(self, ~, ~) + newselected = []; + for idx = 1:size(self.hChannels.Data, 1) + row = self.hChannels.Data(idx,:); + if row(1) == "1" + lslidx = str2double(row(2)); + newselected(end+1) = lslidx; + end + end + self.selected = newselected; + end + + % executed on OK button + function onButtonClicked(self, ~, ~) + notify(self, 'Done'); + self.close(); + end + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + methods + function r = get.selected(self) + r = self.selected; + end + + function set.selected(self,val) + self.selected = val; + self.updateOK(); + end + + function show(self) + % window already open + if isvalid(self.hFig) + self.initRequired(); + self.initSelected(); + figure(self.hFig); + return; + end + + % create figure + self.hFig = uifigure(); + self.hFig.Visible = 'off'; + self.hFig.Name = 'SELECT LSL CHANNELS'; + %self.hFig.Color = [0.0 0.0 0.0]; + self.hFig.MenuBar = 'none'; + self.hFig.Units = 'pixels'; + self.hFig.NumberTitle = 'off'; + self.hFig.Position = [0, 0, ... + selectchannels.figwidth, ... + selectchannels.figheight]; + + % create required panel + self.hRequiredPanel = uipanel(self.hFig); + self.hRequiredPanel.AutoResizeChildren = 'on'; + self.hRequiredPanel.Title = 'REQUIRED'; + self.hRequiredPanel.Position = [ + selectchannels.padding, ... + selectchannels.figheight - ... + selectchannels.padding - ... + selectchannels.panelheightrequired, ... + selectchannels.panelwidth, ... + selectchannels.panelheightrequired + ]; + + % create channels panel + self.hChannelsPanel = uipanel(self.hFig); + self.hChannelsPanel.AutoResizeChildren = 'on'; + self.hChannelsPanel.Title = 'SELECTED: 0'; + self.hChannelsPanel.Position = [ + selectchannels.padding, ... + selectchannels.buttonheight + 2*selectchannels.padding, ... + selectchannels.panelwidth, ... + selectchannels.panelheightchannels + ]; + + % create required table + self.hRequired = uitable(self.hRequiredPanel); + self.hRequired.ColumnName = {'MIN'; 'MAX'; 'SEL'; 'TYPE'; 'UNIT'}; + self.hRequired.ColumnWidth = {50, 50, 45, 'auto', 100}; + self.hRequired.ColumnFormat = { + 'short', 'short', 'short', 'char', 'char' }; + self.hRequired.RowName = {}; + self.hRequired.ColumnEditable = [false false false false false]; + self.hRequired.Position = [... + selectchannels.padding, ... + selectchannels.padding, ... + selectchannels.tablewidth, ... + selectchannels.tableheightrequired]; + self.hRequired.SelectionType = 'cell'; + + % create channels table + self.hChannels = uitable(self.hChannelsPanel); + self.hChannels.ColumnName = {''; 'LSL CH'; 'DEV CH'; 'TYPE'; 'UNIT'}; + self.hChannels.ColumnWidth = {25, 60, 60, 'auto', 100}; + self.hChannels.ColumnFormat = { + 'logical', 'short', 'short', 'char', 'char' }; + self.hChannels.RowName = {}; + self.hChannels.ColumnEditable = [true false false false false]; + self.hChannels.Position = [... + selectchannels.padding, ... + selectchannels.padding, ... + selectchannels.tablewidth, ... + selectchannels.tableheightchannels]; + self.hChannels.CellEditCallback = @self.onSelectedChanged; + self.hChannels.SelectionType = 'cell'; + + % create center style + s = uistyle(); + s.HorizontalAlignment = 'center'; + addStyle(self.hChannels, s, 'column', [2;3]); + addStyle(self.hRequired, s, 'column', [1;2;3]); + + % create ok button + self.hButton = uibutton(self.hFig, 'push'); + self.hButton.ButtonPushedFcn = @self.onButtonClicked; + self.hButton.FontWeight = 'bold'; + self.hButton.Text = 'OK'; + self.hButton.Position = [ + selectchannels.padding, ... + selectchannels.padding, ... + selectchannels.panelwidth, ... + selectchannels.buttonheight]; + + % init ok style + self.hStyleOk = uistyle(); + self.hStyleOk.BackgroundColor = 'green'; + self.hStyleOk.HorizontalAlignment = 'center'; + + % init notok style + self.hStyleNotOk = uistyle(); + self.hStyleNotOk.BackgroundColor = 'red'; + self.hStyleNotOk.HorizontalAlignment = 'center'; + + % init tables data + self.initRequired(); + self.initSelected(); + + % show + self.hFig.Visible = 'on'; + end + + function close(self) + if isvalid(self.hFig) + close(self.hFig); + end + end + + function initRequired(self) + if isempty(self.hFig) || ~isvalid(self.hFig) + return + end + global myprotocols; + req = myprotocols.selected.fh.requires(); + self.hRequired.Data = strings([0,5]); + for idx = 1:length(req.channels) + self.hRequired.Data(idx,:) = [ + req.channels(idx).min, ... + req.channels(idx).max, ... + 0, ... + req.channels(idx).type, ... + req.channels(idx).unit + ]; + end + end + + function initSelected(self) + if isempty(self.hFig) || ~isvalid(self.hFig) + return; + end + global mylsl; + global mydevices; + tblidx = 1; + lenreqs = size(self.hRequired.Data, 1); + self.hChannels.Data = strings([0,5]); + for idx = 1:mylsl.lslchannels + isselected = ismember(idx, self.selected); + isselectedstr = convertCharsToStrings(num2str(isselected)); + if idx <= size(mydevices.selected.lsl.channels, 1) && ... + self.isChannelVisible(mydevices.selected.lsl.channels(idx)) + self.hChannels.Data(tblidx,:) = [ + isselectedstr, ... + idx, ... + mydevices.selected.lsl.channels(idx).devch, ... + mydevices.selected.lsl.channels(idx).type, ... + mydevices.selected.lsl.channels(idx).unit + ]; + tblidx = tblidx + 1; + elseif lenreqs == 0 + self.hChannels.Data(tblidx,:) = [ + isselectedstr, ... + idx, ... + "", ... + "", ... + "" + ]; + tblidx = tblidx + 1; + end + end + self.updateOK(); + end + end +end