Source code for nsds_lab_to_nwb.components.stimulus.tokenizers.tone_tokenizer

from nsds_lab_to_nwb.common.io import read_mat_file
from nsds_lab_to_nwb.components.stimulus.tokenizers.base_tokenizer import BaseTokenizer


[docs]class ToneTokenizer(BaseTokenizer): """ Tokenize into discrete tone pip stimulus trials. """ def __init__(self, block_name, stim_configs): BaseTokenizer.__init__(self, block_name, stim_configs) self.tokenizer_type = 'ToneTokenizer' # list of ('column_name', 'column_description') self.custom_trial_columns = [('sb', 'Stimulus (s) or baseline (b) period'), ('frq', 'Stimulus Frequency'), ('amp', 'Stimulus Amplitude')] def _load_stim_parameters(self): stim_params_path = self.stim_configs['stim_params_path'] stim_vals = tone_stimulus_values(stim_params_path) return stim_vals def _tokenize(self, stim_vals, stim_onsets, *, audio_start_time, audio_end_time, rec_end_time): stim_dur = self.stim_configs['duration'] bl_start = self.stim_configs['baseline_start'] bl_end = self.stim_configs['baseline_end'] if not (stim_dur < bl_start and bl_start < bl_end): raise ValueError('Baseline period should start after the stimulus.' f'Got stim duration={stim_dur}, baseline_start={bl_start} ' f'and baseline_end={bl_end}, relative to stim onsets.') trial_list = [] none_str = 'nan' # for indicating baseline frq and amp # period before the first stimulus starts trial_list.append(dict(start_time=0.0, stop_time=stim_onsets[0], sb='b', frq=none_str, amp=none_str)) for i, onset in enumerate(stim_onsets): frq = str(stim_vals[i, 1]) amp = str(stim_vals[i, 0]) # actual stimulus (always starts at stim_onset) start_time = onset stop_time = onset + stim_dur trial_list.append(dict(start_time=start_time, stop_time=stop_time, sb='s', frq=frq, amp=amp)) # in-trial baseline period start_time = onset + bl_start stop_time = onset + bl_end trial_list.append(dict(start_time=start_time, stop_time=stop_time, sb='b', frq=none_str, amp=none_str)) # period after the end of last stim trial until recording stops if stop_time < rec_end_time: start_time = stop_time trial_list.append(dict(start_time=start_time, stop_time=rec_end_time, sb='b', frq=none_str, amp=none_str)) return trial_list
[docs]def tone_stimulus_values(mat_file_path): """adapted from mars.configs.block_directory Parameters ---------- mat_file_path : path full path to a .mat file that contains stim_values. Returns ------- stim_vals : ndarray (n, 2) a 2D array with two columns (NOTE: changed from legacy behavior) `stim_vals[:, 0]` are the amplitudes, `stim_vals[:, 1]` are the frequencies of the tones. """ sio = read_mat_file(mat_file_path) stim_vals = sio['stimVls'][:].astype(int) # check dimension shape = stim_vals.shape if not (len(shape) == 2) and (2 in shape): # should be a 2D array, with 2 columns or 2 rows raise ValueError('stim_vals dimension mismatch') if shape[0] == 2: # changed from legacy behavior (now 2 columns; was 2 rows in mars) stim_vals = stim_vals.T # this offset value comes from mars; what is this? # variable naming (amp_offset) was by JHB and could be wrong amp_offset = 8 stim_vals[:, 0] = stim_vals[:, 0] + amp_offset return stim_vals