Пример #1
0
def listmode_from_gate_out(path, scanner, nb_sub):
    full_data = None
    for i in tqdm(range(nb_sub)):
        path_ = path.replace('?', str(i))
        data = np.load(path_)[:, :7]
        if full_data is None:
            full_data = np.array(data)
        else:
            full_data = np.vstack((full_data, data))
    if isinstance(scanner, nef.PetEcatScanner):
        lors = Lors(full_data)
        listmode = Listmode(np.ones((lors.length, ), dtype=np.float32), lors)
        row = nef.EcatCrystalPosToIndex(scanner)(lors.data[:, :3])
        col = nef.EcatCrystalPosToIndex(scanner)(lors.data[:, 3:])
        lors_data1 = nef.EcatIndexToCrystalPos(scanner)(row)
        lors_data2 = nef.EcatIndexToCrystalPos(scanner)(col)
        lors = np.hstack((lors_data1, lors_data2))
        return Listmode(np.ones((lors.shape[0], ), dtype=np.float32), lors)
    elif isinstance(scanner, nef.PetCylindricalScanner):
        lors = Lors(full_data)
        listmode = Listmode(np.ones((lors.length, ), dtype=np.float32), lors)
        ind1 = nef.CylindricalCrystalPosToIndex(scanner)(lors.data[:, :3])
        ind2 = nef.CylindricalCrystalPosToIndex(scanner)(lors.data[:, 3:])
        lors_data1 = nef.CylindricalIndexToCrystalPos(scanner)(ind1)
        lors_data2 = nef.CylindricalIndexToCrystalPos(scanner)(ind2)
        lors_data = np.hstack((lors_data1, lors_data2))
        return listmode.update(lors=nef.Lors(lors_data))
    else:
        raise NotImplementedError
Пример #2
0
def pre_lors_atten(transmission_image, p1, p2, config):
    lors = np.hstack((np.hstack(
        (p1, p2)), np.ones((p1.shape[0], 1), dtype=np.float32)))
    projector = nef.Projector()
    u_map_projector = nef.correction.UmapProjector(projector)
    value = u_map_projector(transmission_image * 1.2, nef.Lors(lors)).data
    return value
Пример #3
0
def get_lors(P1, P2):
    lors = np.ones((P1.shape[0] * P2.shape[0], 7), dtype=np.float32)
    lors[:, 0] = np.tile(P1[:, 0].reshape(-1, 1), P2.shape[0]).flatten()
    lors[:, 1] = np.tile(P1[:, 1].reshape(-1, 1), P2.shape[0]).flatten()
    lors[:, 2] = np.tile(P1[:, 2].reshape(-1, 1), P2.shape[0]).flatten()
    lors[:, 3] = np.tile(P2[:, 0], P1.shape[0])
    lors[:, 4] = np.tile(P2[:, 1], P1.shape[0])
    lors[:, 5] = np.tile(P2[:, 2], P1.shape[0])
    return nef.Lors(lors)
Пример #4
0
 def get_raw_codz_and_bins(self):
     time = self.listmode.data[:, 1]
     value = self.listmode.data[:, 0]
     centerz = get_centerz(self.listmode.lors.data)
     num_interval = int(np.max(time) / 0.1) + 1
     codz = np.zeros((num_interval + 1, ))
     bins = []
     for i in range(num_interval + 1):
         index = np.where((time >= i * 0.1) & (time < (i + 1) * 0.1))[0]
         codz[i] = np.sum(centerz[index[0]:index[-1] + 1] *
                          value[index[0]:index[-1] + 1]) / index.size
         bins.append(
             nef.Listmode(self.listmode.data[index, 0].reshape(-1, 1),
                          nef.Lors(self.listmode.lors.data[index, :])))
     return codz, bins
Пример #5
0
 def __call__(self):
     codz, bins = self.get_raw_codz_and_bins()
     codz = codz - np.min(codz)
     amplitudes = find_amplitudes(codz)
     listmode_parts = []
     for i in range(8):
         index_in_bins = np.where((codz >= amplitudes[i])
                                  & (codz < amplitudes[i + 1]))[0]
         if index_in_bins.size > 0:
             value = bins[index_in_bins[0]].data
             lors_data = bins[index_in_bins[0]].lors.data
             for k in range(1, index_in_bins.size):
                 value = np.vstack((value, bins[index_in_bins[k]].data))
                 lors_data = np.vstack(
                     (lors_data, bins[index_in_bins[k]].lors.data))
         listmode_parts.append(nef.Listmode(value, nef.Lors(lors_data)))
     return listmode_parts
Пример #6
0
    def __call__(self,
                 num: int,
                 filename: str,
                 random_interval: int = None) -> object:

        fst_pos_all = np.zeros((0, 3))
        snd_pos_all = np.zeros((0, 3))
        tof_all = np.array([])
        val_all = np.array([])
        for ind in nef.utils.tqdm(range(num)):
            filename_ = filename.replace('?', str(ind))
            time_, crystal_id = self.loader(filename_)
            fst_ind = np.where(time_[1:] - time_[:-1] < self.time_window)[0]
            snd_ind = fst_ind + 1
            fst_crystal_id = crystal_id[fst_ind]
            snd_crystal_id = crystal_id[snd_ind]
            tof_dist = (time_[snd_ind] - time_[fst_ind]) * 0.3
            tof_all = np.hstack((tof_all, tof_dist))
            fst_pos = nef.CylindricalIndexToCrystalPos(
                self.scanner)(fst_crystal_id)
            snd_pos = nef.CylindricalIndexToCrystalPos(
                self.scanner)(snd_crystal_id)
            fst_pos_all = np.vstack((fst_pos_all, fst_pos))
            snd_pos_all = np.vstack((snd_pos_all, snd_pos))

            if random_interval is None:
                val_all = np.hstack(
                    (val_all, np.ones(fst_ind.size))).astype(np.float32)
            elif random_interval == 0:
                N = self.scanner.nb_all_crystal
                single_rate = np.zeros(N)
                for ind in range(N):
                    single_rate[ind] = np.sum(crystal_id == ind)
                val_all = 1 - single_rate[fst_crystal_id] * single_rate[
                    snd_crystal_id] * 2 * self.time_window / (time_[-1] -
                                                              time_[0])
            else:
                if ind % random_interval == 0:
                    N = self.scanner.nb_all_crystal
                    mat_coin = coo_matrix((N, N), dtype=np.float32)
                    mat_rand = coo_matrix((N, N), dtype=np.float32)
                    for ind in nef.utils.tqdm(range(0, num, random_interval)):
                        filename_ = filename.replace('?', str(ind))
                        time_, crystal_id = self.loader(filename_)
                        fst_ind = np.where(
                            time_[1:] - time_[:-1] < self.time_window)[0]
                        snd_ind = fst_ind + 1
                        mat_coin += coo_matrix(
                            (np.ones(fst_ind.size),
                             (crystal_id[fst_ind], crystal_id[snd_ind])),
                            (N, N),
                            dtype=np.float32).tocsr()
                        panel_id = crystal_id // self.scanner.nb_crystal_per_rsector
                        time_rand = time_ + panel_id * 5 * self.time_window
                        ind_sort = np.argsort(time_rand)
                        time_rand = time_rand[ind_sort]
                        crystal_id_rand = crystal_id[ind_sort]
                        fst_ind = np.where(
                            time_rand[1:] -
                            time_rand[:-1] < self.time_window)[0]
                        snd_ind = fst_ind + 1
                        fst_crystal_id_rand = crystal_id_rand[fst_ind]
                        snd_crystal_id_rand = crystal_id_rand[snd_ind]
                        mat_rand += coo_matrix(
                            (np.ones(fst_crystal_id_rand.size),
                             (fst_crystal_id_rand, snd_crystal_id_rand)),
                            (N, N),
                            dtype=np.float32).tocsr()
                vals_ = np.zeros(fst_ind.size)
                for ind in range(vals_.size):
                    vals_[ind] = np.nan_to_num(
                        1 -
                        mat_rand[fst_crystal_id[ind], snd_crystal_id[ind]] /
                        mat_coin[fst_crystal_id[ind], snd_crystal_id[ind]])
                val_all = np.hstack((val_all, vals_.astype(np.float32)))
                mat_coin.sum_duplicates()
                mat_rand.sum_duplicates()
        lors_data = np.hstack(
            (fst_pos_all, snd_pos_all, tof_all.reshape(-1,
                                                       1))).astype(np.float32)
        return nef.Listmode(val_all.ravel(), nef.Lors(lors_data))
Пример #7
0
# encoding: utf-8
'''
@author: Minghao Guo
@contact: [email protected]
@software: nef
@file: toy_data.py
@date: 5/8/2019
@desc:
'''
import srfnef as nef
import numpy as np

block = nef.Block([20.0, 33.4, 33.4], [1, 10, 10])
scanner = nef.PetEcatScanner(99.0, 119.0, 1, 16, 0.0, block)
shape = [90, 90, 10]
center = [0., 0., 0.]
size = [180., 180., 33.4]

lors = nef.Lors(np.load(nef.config.DATABASE_DIR + '/toy_cases/lors.npy'))

listmode = nef.LorsToListmode()(lors) * 0.0

image = nef.Image(np.zeros(shape, dtype=np.float32), center, size)
Пример #8
0
    def __call__(self, image: Image):
        from srfnef import EcatIndexToCrystalPos
        if self.mode == 'full':
            declare_eager_execution()
            ind2pos = EcatIndexToCrystalPos(self.scanner)
            ind = np.arange(self.scanner.nb_crystals)
            pos1 = pos2 = ind2pos(ind)
            pos1_ = np.kron(pos1, [1] * pos2.size)
            pos2_ = np.kron(pos2, [[1]] * pos1.size).reshape(-1, 3)
            lors_data = np.hstack((pos1_, pos2_))
            listmode = LorsToListmode()(nef.Lors(lors_data))
            return Emap(**BackProject(
                mode='tf-eager')(listmode, image).asdict())
        elif self.mode == 'block':
            declare_eager_execution()
            single_block_scanner = self.scanner.update(nb_blocks_per_ring=1)
            ind2pos = EcatIndexToCrystalPos(single_block_scanner)
            ind = np.arange(self.scanner.nb_crystals_per_block *
                            self.scanner.nb_rings)
            pos1 = pos2 = ind2pos(ind)
            pos1_x = np.kron(pos1[:, 0], [1] * ind.size)
            pos1_y = np.kron(pos1[:, 1], [1] * ind.size)
            pos1_z = np.kron(pos1[:, 2], [1] * ind.size)
            pos1_ = np.vstack((pos1_x, pos1_y, pos1_z)).transpose()

            emap_data = np.zeros(image.shape, np.float32)
            emap_tf = Emap(data=tf.Variable(emap_data),
                           center=image.center,
                           size=image.size)
            for d in tqdm(range(self.scanner.nb_blocks_per_ring)):
                angle = d * self.scanner.angle_per_block
                print(angle)
                pos2_x = np.kron(pos2[:, 0], [[1]] * ind.size).ravel()
                pos2_y = np.kron(pos2[:, 1], [[1]] * ind.size).ravel()
                pos2_z = np.kron(pos2[:, 2], [[1]] * ind.size).ravel()
                pos2_ = np.vstack(
                    (pos2_x * np.cos(angle) - pos2_y * np.sin(angle),
                     pos2_x * np.sin(angle) + pos2_y * np.cos(angle),
                     pos2_z)).transpose()
                lors_data = np.hstack((pos1_, pos2_)).astype(np.float32)
                listmode = LorsToListmode()(nef.Lors(lors_data))
                listmode_tf = listmode.update(data=tf.Variable(listmode.data),
                                              lors=nef.Lors(
                                                  tf.Variable(lors_data)))
                _emap = BackProject(mode='tf')(listmode_tf, emap_tf)
                for i in range(self.scanner.nb_blocks_per_ring):
                    _emap_rotate_data = self._rotate_tf(
                        _emap.data, i * self.scanner.angle_per_block)
                    tf.compat.v1.assign_add(emap_tf.data, _emap_rotate_data)
            emap_data = emap_tf.data.numpy()
            return emap_tf.update(data=emap_data,
                                  center=image.center,
                                  size=image.size)

        elif self.mode == 'block-full':
            declare_eager_execution()
            single_block_scanner = self.scanner.update(nb_blocks_per_ring=1)
            ind2pos = EcatIndexToCrystalPos(single_block_scanner)
            ind = np.arange(self.scanner.nb_crystals_per_block *
                            self.scanner.nb_rings)
            pos1 = pos2 = ind2pos(ind)

            emap_data = np.zeros(image.shape, np.float32)
            emap_tf = Emap(data=tf.Variable(emap_data),
                           center=image.center,
                           size=image.size)
            for i in tqdm(range(self.scanner.nb_blocks_per_ring)):
                angle1 = i * self.scanner.angle_per_block
                pos1_x = np.kron(pos1[:, 0], [1] * ind.size)
                pos1_y = np.kron(pos1[:, 1], [1] * ind.size)
                pos1_z = np.kron(pos1[:, 2], [1] * ind.size)
                pos1_ = np.vstack(
                    (pos1_x * np.cos(angle1) - pos1_y * np.sin(angle1),
                     pos1_x * np.sin(angle1) + pos1_y * np.cos(angle1),
                     pos1_z)).transpose()
                for j in range(self.scanner.nb_blocks_per_ring):
                    angle2 = j * self.scanner.angle_per_block
                    pos2_x = np.kron(pos2[:, 0], [[1]] * ind.size).ravel()
                    pos2_y = np.kron(pos2[:, 1], [[1]] * ind.size).ravel()
                    pos2_z = np.kron(pos2[:, 2], [[1]] * ind.size).ravel()
                    pos2_ = np.vstack(
                        (pos2_x * np.cos(angle2) - pos2_y * np.sin(angle2),
                         pos2_x * np.sin(angle2) + pos2_y * np.cos(angle2),
                         pos2_z)).transpose()

                    lors_data = np.hstack((pos1_, pos2_)).astype(np.float32)
                    listmode = LorsToListmode()(nef.Lors(lors_data))
                    listmode_tf = listmode.update(
                        data=tf.Variable(listmode.data),
                        lors=nef.Lors(tf.Variable(lors_data)))
                    _emap = BackProject(mode='tf')(listmode_tf, emap_tf)
                    tf.compat.v1.assign_add(emap_tf.data, _emap.data)
            emap_data = emap_tf.data.numpy()
            return emap_tf.update(data=emap_data,
                                  center=image.center,
                                  size=image.size)
        elif self.mode == 'rsector':
            return self.update(mode='block')(image)
        elif self.mode == 'rsector-full':
            return self.update(mode='block-full')(image)
        else:
            raise NotImplementedError