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
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
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)
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
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
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))
# 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)
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