diff --git a/mne/gui/_ieeg_locate_gui.py b/mne/gui/_ieeg_locate_gui.py index 001b7ff9c82..d6789f586d8 100644 --- a/mne/gui/_ieeg_locate_gui.py +++ b/mne/gui/_ieeg_locate_gui.py @@ -63,24 +63,27 @@ def _load_image(img, name, verbose=True): logger.info(f'Loading {img}') _check_fname(img, overwrite='read', must_exist=True, name=name) img = nib.load(img) - # get data reoriented to RAS and transform - orig_data = np.array(img.dataobj) + # get data + orig_data = np.array(img.dataobj).astype(np.float32) + # reorient data to RAS + ornt = nib.orientations.axcodes2ornt( + nib.orientations.aff2axcodes(img.affine)).astype(int) + ras_ornt = nib.orientations.axcodes2ornt('RAS') + ornt_trans = nib.orientations.ornt_transform(ornt, ras_ornt) + img_data = nib.orientations.apply_orientation(orig_data, ornt_trans) orig_mgh = nib.MGHImage(orig_data, img.affine) - vox_ras_t = orig_mgh.header.get_vox2ras_tkr() - canonical_img = nib.as_closest_canonical(orig_mgh) - # canonical voxels->real world->original voxels - canonical_ras_t = canonical_img.affine - canonical_orig_t = np.dot(canonical_ras_t, np.linalg.inv(orig_mgh.affine)) - canonical_fs_t = np.dot(canonical_orig_t, vox_ras_t) - img_data = np.array(canonical_img.dataobj) - return img_data, canonical_fs_t + aff_trans = nib.orientations.inv_ornt_aff(ornt_trans, img.shape) + vox_ras_t = np.dot(orig_mgh.header.get_vox2ras_tkr(), aff_trans) + return img_data, vox_ras_t class ComboBox(QComboBox): """Dropdown menu that emits a click when popped up.""" + clicked = QtCore.pyqtSignal() def showPopup(self): + """Override show popup method to emit click.""" self.clicked.emit() super(ComboBox, self).showPopup() @@ -163,7 +166,7 @@ def _load_image_data(self, ct): """Get MRI and CT data to display and transforms to/from vox/RAS.""" self._mri_data, self._vox_ras_t = _load_image( op.join(self._subject_dir, 'mri', 'brain.mgz'), - 'MRI Image', reorient=True, verbose=self._verbose) + 'MRI Image', verbose=self._verbose) self._ras_vox_t = np.linalg.inv(self._vox_ras_t) self._brain_on = True @@ -173,7 +176,7 @@ def _load_image_data(self, ct): [0, self._voxel_sizes[0], 0, self._voxel_sizes[1]]] # ready ct - self._ct_data, vox_ras_t = _load_image(ct, 'CT', reorient=True) + self._ct_data, vox_ras_t = _load_image(ct, 'CT', verbose=self._verbose) if self._mri_data.shape != self._ct_data.shape or \ not np.allclose(self._vox_ras_t, vox_ras_t, rtol=1e-6): raise ValueError('CT is not aligned to MRI, got ' @@ -227,6 +230,7 @@ def color_ch_radius(ch_image, xf, yf, group, radius): def _load_ch_coords(self, info): """Load previously determined electrode contact locations.""" ch_coords = np.array([ch['loc'][:3] for ch in info['chs']]) + head_mri_t = invert_transform(self._mri_head_t) chs = dict() for idx, ch_coord in enumerate(ch_coords): ch_name = info['chs'][idx]['ch_name'] @@ -249,8 +253,7 @@ def _load_ch_coords(self, info): 'this is to use saved locations from this GUI or you may ' ' want to remove previous channel locations with ' '`inst.set_montage(None)` **will erase previous data**.') - chs[ch_name] = apply_trans( - invert_transform(self._mri_head_t), ch_coord) + chs[ch_name] = apply_trans(head_mri_t, ch_coord) * 1000 # mm -> m return chs def _save_ch_coords(self): @@ -279,7 +282,7 @@ def _plot_images(self): ct_min, ct_max = np.nanmin(self._ct_data), np.nanmax(self._ct_data) self._ct_cutoff = int(round(np.quantile( self._ct_data[~np.isnan(self._ct_data)], _CT_MIN_DEFAULT))) \ - if self._brain_on else ct_min # cut off by default if brain is on + if self._brain_on else int(round(ct_min)) # cut off if brain is on ct_cmap = 'autumn_r' if self._brain_on else 'gray' for axis in range(3): self._plt._axes[axis].clear()