def _load(self, fname, name, is_roi=False): try: extension = "" parts = fname.split(".", 1) if len(parts) > 1: extension = parts[1] self.debug("Loading: %s (%s)", fname, extension) if extension == 'mat': mat, _rows, _cols = load_matrix(fname) extra = MatrixExtra(name, mat) self.ivm.add_extra(name, extra) elif extension == 'csv': df = pd.read_csv(fname) extra = DataFrameExtra(name, df) self.ivm.add_extra(name, extra) elif extension in ('nii', 'nii.gz'): self.debug("Nifti data") qpdata = load(fname) # Remember this is from a temporary file so need to copy the actual data qpdata = NumpyData(qpdata.raw(), grid=qpdata.grid, name=self._output_prefix + name, roi=is_roi) self._output_data_items.append(name) self.ivm.add(qpdata) except: self.warn("Failed to load: %s", fname) traceback.print_exc()
def testRoiFloats(self): """ Check that ROIs can contain float data so long as the numbers are really integers """ qpd = NumpyData(self.ints.astype(np.float), grid=self.grid, name="test", roi=True) self.assertTrue(issubclass(qpd.raw().dtype.type, np.floating)) self.assertTrue(qpd.roi)
def reg_4d(cls, reg_data, ref_data, options, queue): """ 4D Registration The default implementation simply registers each volume of the data independently. However, implementations can supply their own more optimal implementation if appropriate :param reg_data: 4D QpData containing data to register. :param ref_data: 3D QpData containing reference data. :param options: Method options as dictionary :param queue: Queue object which method may put progress information on to. Progress should be given as a number between 0 and 1. :return Tuple of three items. First, A QpData containing registered data Second, if options contains ``output-transform : True``, sequence of transformations found, one for each volume in ``reg_data``. Each is either a QpData object containing a sequence of 3 warp images or an Extra object containing a transformation matrix If ``output-transform`` is not given or not supported, returns None instead. Third, log information from the registration as a string. """ if reg_data.ndim != 4: raise QpException("reg_4d expected 4D data") if options.get("output-space", "ref") == "ref": output_space = ref_data else: output_space = reg_data out_data = np.zeros(list(output_space.grid.shape) + [reg_data.nvols]) transforms = [] log = "Default 4D registration using multiple 3d registrations\n" for vol in range(reg_data.shape[-1]): log += "Registering volume %i of %i\n" % (vol+1, reg_data.shape[-1]) reg_vol = NumpyData(reg_data.volume(vol), grid=reg_data.grid, name="regvol") #self.debug("Vol %i of %i" % (vol+1, reg_data.shape[-1])) if vol == options.get("ignore-idx", -1): # Ignore this index (e.g. because it is the same as the ref volume) if options.get("output-space", "ref") != "reg": raise QpException("Can't ignore an index unless the output space is the registration data") out_data[..., vol] = reg_vol.raw() transforms.append(None) else: #self.debug("Calling reg_3d", cls, cls.reg_3d) # We did not remove output-space from the options so regdata should # come back in the appropriate space regdata, transform, vol_log = cls.reg_3d(reg_vol, ref_data, options, queue) out_data[..., vol] = regdata.raw() transforms.append(transform) log += vol_log queue.put(float(vol)/reg_data.shape[-1]) return NumpyData(out_data, grid=output_space.grid, name=reg_data.name), transforms, log
def testSet2dt(self): qpd = NumpyData(self.floats, grid=self.grid, name="test") qpd.set_2dt() self.assertEqual(qpd.nvols, GRIDSIZE) self.assertEqual(qpd.ndim, 4) d = qpd.raw() for idx in range(GRIDSIZE): vol = d[..., idx] self.assertEqual(vol.shape[0], GRIDSIZE) self.assertEqual(vol.shape[1], GRIDSIZE) self.assertEqual(vol.shape[2], 1) self.assertTrue(np.allclose(np.squeeze(vol), self.floats[:, :, idx]))
def testRename(self): shape = [GRIDSIZE, GRIDSIZE, GRIDSIZE] grid = DataGrid(shape, np.identity(4)) qpd = NumpyData(np.random.rand(*shape), name="test", grid=grid) self.ivm.add(qpd) self.ivm.rename("test", "test2") self.assertEqual(len(self.ivm.data), 1) self.assertEqual(len(self.ivm.rois), 0) self.assertTrue(self.ivm.current_data is None) self.assertTrue(self.ivm.current_roi is None) self.assertEqual(self.ivm.main, self.ivm.data["test2"]) self.assertTrue(np.all(self.ivm.data["test2"].raw() == qpd.raw()))
def _load(self): if self._desc is not None: res = self._imgs.itemData(self._imgs.currentIndex()) atlas = self._registry.loadAtlas(self._desc.atlasID, loadSummary=False, resolution=res) is_roi = self._desc.atlasType == "label" new_name = self._load_options.option("name").value add_name = self._load_options.option("data").value add = self._load_options.option("add").value == "add" load_all = self._load_options.option("regions").value == "all" vol = None if not load_all: indexes = self._label_table.selectionModel().selectedRows() vol = int(self._label_model.item(indexes[0].row(), 0).text()) new_data = fslimage_to_qpdata(atlas, vol=vol, name=new_name, roi=is_roi) if add and add_name in self.ivm.data: # User wants to add the region to an existing data set if load_all: raise QpException( "Cannot add data to existing data set when loading all regions" ) orig_data = self.ivm.data[add_name] if not orig_data.grid.matches(new_data.grid): raise QpException( "Can't add data to existing data set - grids do not match" ) if is_roi and not orig_data.roi: raise QpException( "Can't add data to existing data set - it is not an ROI" ) new_data = NumpyData(orig_data.raw() + new_data.raw(), grid=new_data.grid, name=add_name, roi=is_roi) self.ivm.add(new_data, make_current=True)
def get_summary_stats(self, data, roi=None, hist_bins=20, hist_range=None, slice_loc=None): """ Get summary statistics :param data: QpData instance for the data to get stats from :param roi: Restrict data to within this roi :return: Sequence of summary stats dictionary, roi labels """ # Checks if either ROI or data is None if roi is not None: roi = roi.resample(data.grid) else: roi = NumpyData(np.ones(data.grid.shape[:3]), data.grid, "temp", roi=True) if data is None: stat1 = { 'mean': [0], 'median': [0], 'std': [0], 'max': [0], 'min': [0] } return stat1, list(roi.regions.keys()), np.array([0, 0]), np.array( [0, 1]) stat1 = {'mean': [], 'median': [], 'std': [], 'max': [], 'min': []} hist1 = [] hist1x = [] if slice_loc is None: data_arr = data.raw() roi_arr = roi.raw() else: data_arr, _, _, _ = data.slice_data(slice_loc) roi_arr, _, _, _ = roi.slice_data(slice_loc) regions = [] for region, name in roi.regions.items(): # get data for a single label of the roi in_roi = data_arr[roi_arr == region] if in_roi.size > 0: mean, med, std = np.mean(in_roi), np.median(in_roi), np.std( in_roi) mx, mn = np.max(in_roi), np.min(in_roi) else: mean, med, std, mx, mn = 0, 0, 0, 0, 0 stat1['mean'].append(mean) stat1['median'].append(med) stat1['std'].append(std) stat1['max'].append(mx) stat1['min'].append(mn) regions.append(name) y, x = np.histogram(in_roi, bins=hist_bins, range=hist_range) hist1.append(y) hist1x.append(x) return stat1, regions, hist1, hist1x