====== EEG Remarking Status Channel ====== "Remarking" is part of the preprocessing pipeline. For more see [[:tools:eeg_7t_preprocessingpipeline|EEG Preprocessing Pipeline for 7T/BrainMechR01]] ===== Why ===== The BioSemi device used in [[:tools:loefeeg]] records in [[https://www.biosemi.com/faq/file_format.htm|24-bits]] on the [[https://www.biosemi.com/faq/trigger_signals.htm|Status Channel (16 available for task)]]. Matlab and python read in 32-bits. Task "trigger"/"TTL" values in the ''Status'' channel are read in offset from what is sent/intended-to-be-recorded. More info about the BDF format on [[https://www.fieldtriptoolbox.org/getting_started/biosemi/#the-bdf-fileformat|fieldtriptoolbox's page]], and for more on bit masking, see mne python's [[https://mne.tools/dev/generated/mne.io.read_raw_bdf.html#:~:text=to%20retrieve%20correct%20event%20values%20(bits%201-16)%2C%20one%20could%20do|read_bdf documentation]]. Also see [[https://wiki.besa.de/index.php?title=Reading_BioSemi_data_with_BESA|BESA's note on "negative logic"]] (maybe why our status channel has negative values). Additionally, tasks may send more information than desired for analsyis. E.g. we may want to group all prep events into a single type but the task sends different triggers for various types of prep events. Remarking would collapse all of these (say values 100-150) into a single event code (say 100). ===== Code ===== TODO: example matlab code? link to github functions (fix_stim_channel). def correct_ttl(x): """mne expects 8bit channel. biosemi has 24 bit. go down to 16 and adjust >>> correct_ttl(np.array([16128],dtype='int64')) # first stim ch val np.array([0],dtype='int16') """ return x.astype(np.int32) - 127**2 + 1 v = x - 16128 # np.log2(16128+256)==14 v[v == 65536] = 0 # 65536==2**16 return v def add_stim_corrected(raw): """ >>> raw = mne.io.read_raw_bdf('/Volumes/Hera/Raw/EEG/SPA/12192_20251024/12192_20251024_rest.bdf') >>> add_stim_corrected(raw) """ raw.load_data() stim_raw = raw.pick_channels(["Status"]).get_data() info = mne.create_info(["StatusCorrected"], raw.info["sfreq"], ["stim"]) stim_vals = correct_ttl(stim_raw[0]).reshape(stim_raw.shape) stim = mne.io.RawArray(stim_vals, info) raw.add_channels([stim], force_update_info=True) def read_events(bdf): "read events by making a new channel" ## read in eeg and get separate stim channel info eeg = mne.io.read_raw_bdf(bdf) # eeg.describe() # 247808 (484.0 s) == 512Hz # events = mne.find_events(eeg, shortest_event=2) util.add_stim_corrected(eeg) events = mne.find_events(eeg, stim_channel="StatusCorrected", shortest_event=2) return (events, eeg.info)