Beispiel #1
0
 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()
Beispiel #2
0
 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)
Beispiel #3
0
    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
Beispiel #4
0
 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]))
Beispiel #5
0
 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()))
Beispiel #6
0
    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