def bipolarize_data(data, labels): bipolar_electrodes = [] if isinstance(data, dict): single_trials = True bipolar_data = {} for key in data.keys(): bipolar_data[key] = np.zeros(data[key].shape) else: single_trials = False bipolar_electrodes_num = calc_bipolar_electrodes_number(labels) bipolar_data = np.zeros((bipolar_electrodes_num, data.shape[1], data.shape[2])) bipolar_data_index = 0 for index in range(len(labels) - 1): elc1_name = labels[index].strip() elc2_name = labels[index + 1].strip() elc_group1, _ = utils.elec_group_number(elc1_name) elc_group2, _ = utils.elec_group_number(elc2_name) if elc_group1 == elc_group2: elec_name = '{}-{}'.format(elc2_name, elc1_name) bipolar_electrodes.append(elec_name) if single_trials: for key in data.keys(): bipolar_data[key][:, bipolar_data_index, :] = (data[key][:, index, :] + data[key][:, index + 1, :]) / 2. else: bipolar_data[bipolar_data_index, :, :] = (data[index, :, :] + data[index + 1, :, :]) / 2. bipolar_data_index += 1 if single_trials: for key in data.keys(): bipolar_data[key] = scipy.delete(bipolar_data[key], range(bipolar_data_index, len(labels)), 1) return bipolar_data, bipolar_electrodes
def fix_bipolar_labels(labels): ret = [] for label in labels: elc1, elc2 = str(label).split(' ') group, num1 = utils.elec_group_number(elc1, False) _, num2 = utils.elec_group_number(elc2, False) ret.append('{}{}-{}{}'.format(group, num2, group, num1)) return ret
def read_morphed_electrodes(subjects_electrodes, subject_to='colin27', bipolar=True, prefix='morphed_'): fol = utils.make_dir(op.join(MMVT_DIR, subject_to, 'electrodes')) bipolar_output_fname = op.join( fol, '{}electrodes_bipolar_positions.npz'.format(prefix)) monopolar_output_fname = op.join( fol, '{}electrodes_positions.npz'.format(prefix)) bad_electrodes, bad_subjects = [], set() template_bipolar_electrodes, template_electrodes = defaultdict( list), defaultdict(list) morphed_electrodes_fname = op.join(MMVT_DIR, subject_to, 'electrodes', 'morphed_electrodes.pkl') if False: #op.isfile(morphed_electrodes_fname): template_bipolar_electrodes, template_electrodes = utils.load( morphed_electrodes_fname) else: for subject, electodes_names in subjects_electrodes.items(): electrodes_pos = {} for elecs_bipolar_names in electodes_names: electrodes_found = True for elec_name in elecs_bipolar_names: elec_input_fname = op.join( MMVT_DIR, subject, 'electrodes', 'ela_morphed', '{}_ela_morphed.npz'.format(elec_name)) if not op.isfile(elec_input_fname): print('{} {} not found!'.format(subject, elec_name)) bad_electrodes.append('{}_{}'.format( subject, elec_name)) bad_subjects.add(subject) electrodes_found = False break else: d = np.load(elec_input_fname) electrodes_pos[elec_name] = d['pos'] template_electrodes[subject].append((elec_name, d['pos'])) if not electrodes_found: continue elc1, elc2 = elecs_bipolar_names (group, num1), (_, num2) = utils.elec_group_number( elc1), utils.elec_group_number(elc2) if num1 > num2: elc1, elc2 = elc2, elc1 num1, num2 = num2, num1 bipolar_elec_name = '{}{}-{}'.format(group, num2, num1) pos1, pos2 = electrodes_pos[elc1], electrodes_pos[elc2] bipolar_pos = pos1 + (pos2 - pos1) / 2 template_bipolar_electrodes[subject].append( (bipolar_elec_name, bipolar_pos)) utils.save(template_bipolar_electrodes, morphed_electrodes_fname) save_electrodes(template_electrodes, monopolar_output_fname) save_electrodes(template_bipolar_electrodes, bipolar_output_fname) print('Bad subjects:') print(bad_subjects) return monopolar_output_fname, bipolar_output_fname
def calc_bipolar_electrodes_number(labels): bipolar_data_index = 0 for index in range(len(labels) - 1): elc1_name = labels[index].strip() elc2_name = labels[index + 1].strip() elc_group1, _ = utils.elec_group_number(elc1_name) elc_group2, _ = utils.elec_group_number(elc2_name) if elc_group1 == elc_group2: bipolar_data_index += 1 return bipolar_data_index
def electrodes_csv_to_npy(ras_file, output_file, bipolar=False, delimiter=','): data = np.genfromtxt(ras_file, dtype=str, delimiter=delimiter) data = fix_str_items_in_csv(data) # Check if the electrodes coordinates has a header try: header = data[0, 1:].astype(float) except: data = np.delete(data, (0), axis=0) electrodes_types = grid_or_depth(data) # pos = data[:, 1:].astype(float) if bipolar: # names = [] # pos_biploar, pos_org = [], [] # for index in range(data.shape[0]-1): # elc_group1, elc_num1 = utils.elec_group_number(data[index, 0]) # elc_group2, elc_num12 = utils.elec_group_number(data[index+1, 0]) # if elc_group1==elc_group2: # names.append('{}-{}'.format(data[index+1, 0],data[index, 0])) # pos_biploar.append(pos[index] + (pos[index+1]-pos[index])/2) # pos_org.append([pos[index], pos[index+1]]) # pos = np.array(pos_biploar) # pos_org = np.array(pos_org) depth_data = data[electrodes_types == DEPTH, :] pos = depth_data[:, 1:4].astype(float) pos_depth, names_depth, dists_depth, pos_org = [], [], [], [] for index in range(depth_data.shape[0]-1): elc1_name = depth_data[index, 0].strip() elc2_name = depth_data[index + 1, 0].strip() elc_group1, elc_num1 = utils.elec_group_number(elc1_name) elc_group2, elc_num12 = utils.elec_group_number(elc2_name) if elc_group1 == elc_group2: elec_name = '{}-{}'.format(elc2_name, elc1_name) names_depth.append(elec_name) pos_depth.append(pos[index] + (pos[index+1]-pos[index])/2) pos_org.append([pos[index], pos[index+1]]) # There is no point in calculating bipolar for grid electrodes grid_data = data[electrodes_types == GRID, :] names_grid, pos_grid = get_names_dists_non_bipolar_electrodes(grid_data) names = np.concatenate((names_depth, names_grid)) pos = utils.vstack(pos_depth, pos_grid) # No need in pos_org for grid electordes pos_org.extend([() for _ in pos_grid]) else: names, pos = get_names_dists_non_bipolar_electrodes(data) pos_org = [] if len(set(names)) != len(names): raise Exception('Duplicate electrodes names!') if pos.shape[0] != len(names): raise Exception('pos dim ({}) != names dim ({})'.format(pos.shape[0], len(names))) # print(np.hstack((names.reshape((len(names), 1)), pos))) np.savez(output_file, pos=pos, names=names, pos_org=pos_org)
def get_labels(x=None, mat_fname=''): if mat_fname != '': x = utils.read_mat_file_into_bag(mat_fname) if x is None: raise Exception('x is None!') labels = x['Label'] labels = labels.reshape((len(labels))) fix_labels = [] for label in labels: label = label[0] elecs = label.split('-') group, elc1_name = utils.elec_group_number(elecs[0], False) _, elc2_name = utils.elec_group_number(elecs[1], False) fix_labels.append('{0}{2}-{0}{1}'.format(group, elc1_name, elc2_name)) return sorted(fix_labels, key=utils.natural_keys)
def create_stim_electrodes_positions(subject, args, stim_labels=None): from src.preproc import electrodes as ep stim_labels, bipolar = get_stim_labels(subject, args, stim_labels) output_file_name = 'electrodes{}_stim_{}_positions.npz'.format('_bipolar' if bipolar else '', args.stim_channel) output_file = op.join(MMVT_DIR, subject, 'electrodes', output_file_name) # if op.isfile(output_file): # return f = np.load(op.join(MMVT_DIR, subject, 'electrodes', 'electrodes_positions.npz')) org_pos, org_labels = f['pos'], f['names'] if bipolar: pos, dists = [], [] for stim_label in stim_labels: group, num1, num2 = utils.elec_group_number(stim_label, True) stim_label1 = '{}{}'.format(group, num1) stim_label2 = '{}{}'.format(group, num2) label_ind1 = np.where(org_labels == stim_label1)[0] label_ind2 = np.where(org_labels == stim_label2)[0] elc_pos = org_pos[label_ind1] + (org_pos[label_ind2] - org_pos[label_ind1]) / 2 pos.append(elc_pos.reshape((3))) dist = np.linalg.norm(org_pos[label_ind2] - org_pos[label_ind1]) dists.append(dist) pos = np.array(pos) else: pos = [pos for (pos, label) in zip(org_pos, org_labels) if label in stim_labels] dists = [np.linalg.norm(p2 - p1) for p1, p2 in zip(pos[:-1], pos[1:])] elcs_oris = calc_ori(stim_labels, bipolar, pos) electrodes_types = ep.calc_electrodes_type(stim_labels, dists, bipolar) np.savez(output_file, pos=pos, names=stim_labels, dists=dists, electrodes_types=electrodes_types, electrodes_oris=elcs_oris, bipolar=bipolar)
def calc_ori(stim_labels, bipolar, pos): elcs_oris = np.zeros((len(stim_labels), 3)) for ind in range(len(stim_labels) - 1): # todo: really need to change elec_group_number to return always 2 values if bipolar: group1, _, _ = utils.elec_group_number(stim_labels[ind], bipolar) group2, _, _ = utils.elec_group_number(stim_labels[ind + 1], bipolar) else: group1, _ = utils.elec_group_number(stim_labels[ind], bipolar) group2, _ = utils.elec_group_number(stim_labels[ind + 1], bipolar) ori = 1 if group1 == group2 else -1 elc_pos = pos[ind] next_pos = pos[ind + ori] dist = np.linalg.norm(next_pos - elc_pos) elcs_oris[ind] = ori * (next_pos - elc_pos) / dist elcs_oris[-1] = -1 * (pos[-2] - pos[-1]) / np.linalg.norm(pos[-2] - pos[-1]) return elcs_oris
def read_xls(xls_fname, subject_to='colin27', atlas='aparc.DKTatlas', overwrite=False, check_morph_file=False): bipolar = True template_header = nib.load( op.join(SUBJECTS_DIR, subject_to, 'mri', 'T1.mgz')).header subjects_electrodes = defaultdict(list) electrodes_colors = defaultdict(list) for line in utils.xlsx_reader(xls_fname, skip_rows=1): subject, _, elec_name, _, anat_group = line subject = subject.replace('\'', '') if subject == '': break if check_morph_file: electrodes_fname = op.join( MMVT_DIR, subject, 'electrodes', 'electrodes_morph_to_{}.txt'.format(subject_to)) if not op.isfile(electrodes_fname): continue elec_group, num1, num2 = utils.elec_group_number(elec_name, bipolar) if '{}{}-{}'.format(elec_group, num2, num1) != elec_name: num1, num2 = str(num1).zfill(2), str(num2).zfill(2) if '{}{}-{}'.format(elec_group, num2, num1) != elec_name: raise Exception('Wrong group or numbers!') for num in [num1, num2]: subjects_electrodes[subject].append('{}{}'.format(elec_group, num)) electrodes_colors[subject].append((elec_name, int(anat_group))) subjects = list(subjects_electrodes.keys()) bad_subjects = [] for subject in subjects: atlas = utils.fix_atlas_name(subject, atlas, SUBJECTS_DIR) if not utils.both_hemi_files_exist( op.join(SUBJECTS_DIR, subject, 'label', '{}.{}.annot'.format( '{hemi}', atlas))): anat.create_annotation(subject, atlas) if not utils.both_hemi_files_exist( op.join(SUBJECTS_DIR, subject, 'label', '{}.{}.annot'.format('{hemi}', atlas))): print('No atlas for {}!'.format(atlas)) bad_subjects.append((subject, 'No atlas')) continue try: ela_morph_electrodes.calc_elas(subject, subject_to, subjects_electrodes[subject], bipolar=False, atlas=atlas, overwrite=overwrite) except: err = utils.print_last_error_line() bad_subjects.append((subject, err)) continue print(bad_subjects)
def grid_or_depth(data): pos = data[:, 1:].astype(float) dists = defaultdict(list) group_type = {} electrodes_group_type = [None] * pos.shape[0] for index in range(data.shape[0] - 1): elc_group1, _ = utils.elec_group_number(data[index, 0]) elc_group2, _ = utils.elec_group_number(data[index + 1, 0]) if elc_group1 == elc_group2: dists[elc_group1].append(np.linalg.norm(pos[index + 1] - pos[index])) for group, group_dists in dists.items(): #todo: not sure this is the best way to check it. Strip with 1xN will be mistaken as a depth if np.max(group_dists) > 2 * np.median(group_dists): group_type[group] = GRID else: group_type[group] = DEPTH for index in range(data.shape[0]): elc_group, _ = utils.elec_group_number(data[index, 0]) electrodes_group_type[index] = group_type.get(elc_group, DEPTH) return np.array(electrodes_group_type)
def load_file(fname): d = mu.load_mat_to_bag(fname) channel_list = [] for c in mu.matlab_cell_str_to_list(d.channel_list): elecs = [ '{}{}'.format(*utils.elec_group_number(e)) for e in c.split(' ') ] channel_list.append('{1}-{0}'.format(*elecs)) fs = d.fs[0][0] time = d.T.squeeze() stim = np.array(d.stim, dtype=np.int) theta = d.Theta return channel_list, fs, time, stim, theta
def create_stim_electrodes_positions(subject, args, stim_labels=None): from src.preproc import electrodes as ep stim_labels, bipolar = get_stim_labels(subject, args, stim_labels) output_file_name = 'electrodes{}_stim_{}_positions.npz'.format( '_bipolar' if bipolar else '', args.stim_channel) output_file = op.join(MMVT_DIR, subject, 'electrodes', output_file_name) # if op.isfile(output_file): # return f = np.load( op.join(MMVT_DIR, subject, 'electrodes', 'electrodes_positions.npz')) org_pos, org_labels = f['pos'], f['names'] if bipolar: pos, dists, new_labels = [], [], [] for stim_label in stim_labels: group, num1, num2 = utils.elec_group_number(stim_label, True) if group == '' or num1 == '' or num2 == '': print("Can't calc {} pos!".format(stim_label)) continue new_labels.append(stim_label) stim_label1 = '{}{}'.format(group, num1) stim_label2 = '{}{}'.format(group, num2) label_ind1 = np.where(org_labels == stim_label1)[0] label_ind2 = np.where(org_labels == stim_label2)[0] elc_pos = org_pos[label_ind1] + (org_pos[label_ind2] - org_pos[label_ind1]) / 2 pos.append(elc_pos.reshape((3))) dist = np.linalg.norm(org_pos[label_ind2] - org_pos[label_ind1]) dists.append(dist) pos = np.array(pos) else: new_labels = stim_labels pos = [ pos for (pos, label) in zip(org_pos, org_labels) if label in stim_labels ] dists = [np.linalg.norm(p2 - p1) for p1, p2 in zip(pos[:-1], pos[1:])] stim_labels = new_labels elcs_oris = calc_ori(stim_labels, bipolar, pos) electrodes_types = ep.calc_electrodes_types(stim_labels, pos) np.savez(output_file, pos=pos, names=stim_labels, dists=dists, electrodes_types=electrodes_types, electrodes_oris=elcs_oris, bipolar=bipolar) return output_file
def load_file(fname): test() d = mu.load_mat_to_bag(fname) channel_list = [] for c in mu.matlab_cell_str_to_list(d.channel_list): elecs = [ '{}{}'.format(*utils.elec_group_number(e)) for e in c.split(' ') ] channel_list.append('{1}-{0}'.format(*elecs)) # channel_list.extend(elecs) fs = d.fs[0][0] time = d.T10.squeeze() stim = np.array(d.stim10, dtype=np.int) print('number of stims: {}'.format( len(np.where(np.diff(stim.squeeze()) == 1)[0] + 1))) theta = d.Theta10 return channel_list, fs, time, stim, theta
def load_electrodes_matlab_stim_file2(args): from src.preproc import stim args = elecs.read_cmd_args(utils.Bag(subject=args.subject, bipolar=True)) args = pu.add_default_args(args, { 'error_radius': 3, 'elec_length': 4, 'file_frefix': '' }) subject = args.subject[0] mat_fname = op.join(elecs.ELECTRODES_DIR, subject, 'MG106_HGP_sess2_3.mat') d = mu.load_mat_to_bag(mat_fname) labels = mu.matlab_cell_str_to_list(d.Label) labels = [l.replace(' ', '-') for l in labels] labels = [ '{0}{1}-{0}{2}'.format(*utils.elec_group_number(l, bipolar=True)) for l in labels ] time = d.time2.squeeze() data = d.Data2 data = data.reshape((*data.shape, 1)) args.stim_channel = 'sess2' args.bipolar = '-' in labels[0] elecs.convert_electrodes_coordinates_file_to_npy(subject, bipolar=False) output_file = stim.create_stim_electrodes_positions(subject, args, labels) data_fname = op.join( elecs.MMVT_DIR, subject, 'electrodes', 'electrodes{}_data.npy'.format('_bipolar' if args.bipolar else '')) meta_fname = op.join( elecs.MMVT_DIR, subject, 'electrodes', 'electrodes{}_meta_data.npz'.format( '_bipolar' if args.bipolar else '')) np.save(data_fname, data) np.savez(meta_fname, names=labels, conditions=['rest'], time=time) print('Saving data in {} and {}'.format(data_fname, meta_fname))
def read_morphed_electrodes(xls_fname, subject_to='colin27', bipolar=True, prefix='', postfix=''): output_fname = '{}electrodes{}_positions.npz'.format( prefix, '_bipolar' if bipolar else '', postfix) electrodes_colors = defaultdict(list) bad_electrodes = [] template_electrodes = defaultdict(list) morphed_electrodes_fname = op.join(MMVT_DIR, subject_to, 'electrodes', 'morphed_electrodes.pkl') if op.isfile(morphed_electrodes_fname): template_electrodes, electrodes_colors = utils.load( morphed_electrodes_fname) else: for line in utils.xlsx_reader(xls_fname, skip_rows=1): subject, _, elec_name, _, anat_group = line subject = subject.replace('\'', '') if subject == '': break elec_group, num1, num2 = utils.elec_group_number( elec_name, bipolar) if '{}{}-{}'.format(elec_group, num2, num1) != elec_name: num1, num2 = str(num1).zfill(2), str(num2).zfill(2) if '{}{}-{}'.format(elec_group, num2, num1) != elec_name: raise Exception('Wrong group or numbers!') elecs_pos = [] for num in num1, num2: elec_input_fname = op.join( MMVT_DIR, subject, 'electrodes', '{}{}_ela_morphed.npz'.format(elec_group, num)) if not op.isfile(elec_input_fname): print('{} not found!'.format(elec_input_fname)) bad_electrodes.append('{}_{}{}'.format( subject, elec_group, num)) else: d = np.load(elec_input_fname) elecs_pos.append(d['pos']) num1, num2 = (num1, num2) if num2 > num1 else (num2, num1) if len(elecs_pos) == 2: bipolar_ele_pos = np.mean(elecs_pos, axis=0) elec_name = '{}_{}{}-{}'.format(subject, elec_group, num1, num2) template_electrodes[subject].append( (elec_name, bipolar_ele_pos)) electrodes_colors[subject].append((elec_name, int(anat_group))) utils.save((template_electrodes, electrodes_colors), morphed_electrodes_fname) write_electrode_colors(subject_to, electrodes_colors) fol = utils.make_dir(op.join(MMVT_DIR, subject_to, 'electrodes')) output_fname = op.join(fol, output_fname) elecs_coordinates = np.array( utils.flat_list_of_lists([[e[1] for e in template_electrodes[subject]] for subject in template_electrodes.keys()])) elecs_names = utils.flat_list_of_lists( [[e[0] for e in template_electrodes[subject]] for subject in template_electrodes.keys()]) print('Saving {} electrodes in {}:'.format(subject_to, output_fname)) print(elecs_names) np.savez(output_fname, pos=elecs_coordinates, names=elecs_names, pos_org=[]) print('Bad electrodes:') print(bad_electrodes) return template_electrodes, electrodes_colors
def read_morphed_electrodes(electrodes, template_system, subjects_dir, mmvt_dir, overwrite=False, subjects_electrodes={}, convert_to_bipolar=False): subject_to = 'fsaverage' if template_system == 'ras' else 'colin27' if template_system == 'mni' else template_system fol = utils.make_dir(op.join(mmvt_dir, subject_to, 'electrodes')) output_fname = op.join(fol, 'template_electrodes.pkl') if op.isfile(output_fname) and not overwrite: print('{} already exist!'.format(output_fname)) return subject_to_mri = subject_to #'cvs_avg35_inMNI152' if subject_to == 'fsaverage' else subject_to t1_header = nib.load(op.join(subjects_dir, subject_to_mri, 'mri', 'T1.mgz')).header brain_mask_fname = op.join(subjects_dir, subject_to_mri, 'mri', 'brainmask.mgz') brain_mask = nib.load(brain_mask_fname).get_data() if op.isfile( brain_mask_fname) else None trans = t1_header.get_vox2ras_tkr() template_electrodes = defaultdict(list) bad_subjects, good_subjects = [], [] for subject in electrodes.keys(): if subject == subject_to: continue if len(subjects_electrodes ) != 0 and subject not in subjects_electrodes: continue subject_electrodes = trans_morphed_electrodes_to_tkreg( subject, subject_to, electrodes, trans, brain_mask, subjects_electrodes) if subject_electrodes is None or len(subject_electrodes) == 0: bad_subjects.append(subject) else: template_electrodes[subject] = subject_electrodes good_subjects.append(subject) if convert_to_bipolar: bipolar_template_electrodes = defaultdict(list) for subject, elcs_tups in template_electrodes.items(): pairs = utils.pair_list(elcs_tups) for pair in pairs: # todo: check that the pair is actually two nei electrodes new_bipolar_pos = np.mean([pair[0][1], pair[1][1]], axis=0) group1, num1 = utils.elec_group_number( '_'.join(pair[0][0].split('_')[1:]), False, False) group2, num2 = utils.elec_group_number( '_'.join(pair[1][0].split('_')[1:]), False, False) if group1 != group2 or abs(int(num1) - int(num2)) != 1: print('Wrong pair! {} {} {}'.format(group1, num1, num2)) else: num1, num2 = (num1, num2) if int(num2) > int(num1) else (num2, num1) bipolar_template_electrodes[subject].append( ('{}_{}{}-{}'.format(subject, group1, num1, num2), new_bipolar_pos)) utils.save(template_electrodes, output_fname) print('read_morphed_electrodes: {}'.format(op.isfile(output_fname))) print('{}/{} good subjects'.format(len(good_subjects), len(electrodes))) print('good subjects: {}'.format(good_subjects)) print('bad subjects: {}'.format(bad_subjects)) return bipolar_template_electrodes if convert_to_bipolar else template_electrodes
def read_electrodes_from_cell(cell): electrodes = [] for elc_name in cell.replace(' ', '').split(','): group, num = utils.elec_group_number(elc_name) electrodes.append('{}{}'.format(group, num)) return electrodes
def get_elec_group(elec_name, bipolar): g = utils.elec_group_number(elec_name, bipolar) return g[0]