def reconst_f(output_dir, b_sph=None): params_file = os.path.join(output_dir, 'params.pickle') data_file = os.path.join(output_dir, 'data.pickle') baseparams = pickle.load(open(params_file, 'rb')) data = pickle.load(open(data_file, 'rb')) gtab = data.gtab S_data = data.raw[data.slice] S_data_list = [S_data] if hasattr(data, 'ground_truth'): S_data_list.append(data.ground_truth[data.slice]) l_labels = np.sum(gtab.bvals > 0) imagedims = S_data.shape[:-1] b_vecs = gtab.bvecs[gtab.bvals > 0,...] if b_sph is None: b_sph = load_sphere(vecs=b_vecs.T) qball_sphere = dipy.core.sphere.Sphere(xyz=b_vecs) basemodel = CsaOdfModel(gtab, **baseparams['base']) fs = [] for S in S_data_list: f = basemodel.fit(S).odf(qball_sphere) f = np.clip(f, 0, np.max(f, -1)[..., None]) f = np.array(f.reshape(-1, l_labels).T, order='C') normalize_odf(f, b_sph.b) fs.append(f) return tuple(fs)
def __init__(self, *args, dataterm="W1", gradnorm="frobenius", **kwargs): ModelHARDI.__init__(self, *args, **kwargs) self.gradnorm = 'nuclear' if gradnorm == "spectral" else "frobenius" c = self.constvars imagedims = c['imagedims'] n_image = c['n_image'] d_image = c['d_image'] l_labels = c['l_labels'] m_gradients = c['m_gradients'] s_manifold = c['s_manifold'] xvars = [('u', (n_image, l_labels)), ('w', (m_gradients, n_image, d_image, s_manifold))] yvars = [('p', (n_image, d_image, l_labels)), ('g', (m_gradients, n_image, d_image, s_manifold)), ('q', (n_image, ))] self.dataterm = dataterm if self.dataterm == "W1": xvars.append(('w0', (m_gradients, n_image, s_manifold))) yvars.append(('p0', (n_image, l_labels))) yvars.append(('g0', (m_gradients, n_image, s_manifold))) elif self.dataterm != "quadratic": raise Exception("Dataterm unknown: %s" % self.dataterm) self.x = Variable(*xvars) self.y = Variable(*yvars) # start with a uniform distribution in each voxel self.state = (self.x.new(), self.y.new()) x = self.x.vars(self.state[0], named=True) x['u'][:] = 1.0 / np.einsum('k->', c['b']) f = self.data.odf f_flat = f.reshape(-1, l_labels).T f = np.array(f_flat.reshape((l_labels, ) + imagedims), order='C') normalize_odf(f, c['b']) self.f = np.array(f.reshape(l_labels, -1).T, order='C') logging.info("HARDI setup ({l_labels} labels; " \ "img: {imagedims}; lambda={lbd:.3g}) ready.".format( lbd=c['lbd'], l_labels=c['l_labels'], imagedims="x".join(map(str,c['imagedims']))))
def __init__(self, *args, dataterm="W1", gradnorm="frobenius", **kwargs): ModelHARDI_SHM.__init__(self, *args, **kwargs) self.gradnorm = 'nuclear' if gradnorm == "spectral" else "frobenius" c = self.constvars b_sph = self.data.b_sph imagedims = c['imagedims'] n_image = c['n_image'] d_image = c['d_image'] l_labels = c['l_labels'] m_gradients = c['m_gradients'] s_manifold = c['s_manifold'] l_shm = c['l_shm'] xvars = [('u', (n_image, l_labels)), ('v', (n_image, l_shm)), ('w', (m_gradients, n_image, d_image, s_manifold))] yvars = [('p', (n_image, d_image, l_labels)), ('g', (m_gradients, n_image, d_image, s_manifold)), ('q0', (n_image, )), ('q1', (n_image, l_labels))] self.dataterm = dataterm if self.dataterm == "W1": xvars.append(('w0', (m_gradients, n_image, s_manifold))) yvars.append(('p0', (n_image, l_labels))) yvars.append(('g0', (m_gradients, n_image, s_manifold))) elif self.dataterm != "quadratic": raise Exception("Dataterm unknown: %s" % self.dataterm) self.x = Variable(*xvars) self.y = Variable(*yvars) # start with a uniform distribution in each voxel self.state = (self.x.new(), self.y.new()) x = self.x.vars(self.state[0], named=True) x['u'][:] = 1.0 / np.einsum('k->', c['b']) x['v'][:, 0] = .5 / np.sqrt(np.pi) f = self.data.odf f_flat = f.reshape(-1, l_labels).T f = np.array(f_flat.reshape((l_labels, ) + imagedims), order='C') normalize_odf(f, c['b']) self.f = np.array(f.reshape(l_labels, -1).T, order='C')
def synth_unimodal_odfs(qball_sphere, sphere_vol, directions, cutoff=2 * np.pi, const_width=3, tightness=4.9): verts = qball_sphere.vertices l_labels = verts.shape[0] # `const_width` unimodals for each entry of `directions` val_base = 1e-6 * 290 vals = [tightness * val_base, val_base, val_base] vecs = normalize( np.array( [[np.sin(phi * np.pi / 180.0), np.cos(phi * np.pi / 180.0), 0] for phi in directions]).T).T voxels = [ multi_tensor_odf(verts, np.array((vals, vals)), [v, v], [50, 50]) for v in vecs ] if cutoff < 1.5 * np.pi: # cut off support of distribution functions for v, vox in zip(vecs, voxels): for k in range(l_labels): v_diff1 = verts[k] - v v_diff2 = verts[k] + v if np.einsum('n,n->', v_diff1, v_diff1) > cutoff**2 \ and np.einsum('n,n->', v_diff2, v_diff2) > cutoff**2: vox[k] = 0 fin = np.zeros((l_labels, const_width * len(voxels)), order='C') for i, vox in enumerate(voxels): i1 = i * const_width i2 = (i + 1) * const_width fin[:, i1:i2] = np.tile(vox, (const_width, 1)).T normalize_odf(fin, sphere_vol) return fin
def setup_solver_cvx(self): if self.dataterm != "W1": raise Exception("Only W1 dataterm is implemented in CVX") c = self.constvars imagedims = c['imagedims'] n_image = c['n_image'] d_image = c['d_image'] l_labels = c['l_labels'] m_gradients = c['m_gradients'] s_manifold = c['s_manifold'] l_shm = c['l_shm'] f_flat = self.data.odf.reshape(-1, l_labels).T f = np.array(f_flat.reshape((l_labels, ) + imagedims), order='C') normalize_odf(f, c['b']) f_flat = f.reshape(l_labels, n_image) self.cvx_x = Variable( ('p', (l_labels, d_image, n_image)), ('g', (n_image, m_gradients, s_manifold, d_image)), ('q0', (n_image, )), ('q1', (l_labels, n_image)), ('p0', (l_labels, n_image)), ('g0', (n_image, m_gradients, s_manifold)), ) self.cvx_y = Variable( ('u', (n_image, l_labels)), ('v', (n_image, l_shm)), ('w', (m_gradients, n_image, d_image, s_manifold)), ('w0', (m_gradients, n_image, s_manifold)), ('misc', (n_image * m_gradients, )), ) p, g, q0, q1, p0, g0 = [ cvxVariable(*a['shape']) for a in self.cvx_x.vars() ] self.cvx_vars = p + sum(g, []) + [q0, q1, p0] + g0 self.cvx_obj = cvx.Maximize(-cvx.vec(f_flat).T * cvx.vec(cvx.diag(c['b']) * p0) - cvx.sum(q0)) div_op = sparse_div_op(imagedims) self.cvx_dual = True self.cvx_constr = [] # u_constr for i in range(n_image): for k in range(l_labels): self.cvx_constr.append( c['b'][k]*(q0[i] + p0[k,i] \ - cvxOp(div_op, p[k], i)) - q1[k,i] >= 0) # v_constr for i in range(n_image): for k in range(l_shm): Yk = cvx.vec(c['Y'][:, k]) self.cvx_constr.append(-Yk.T * q1[:, i] == 0) # w_constr for j in range(m_gradients): Aj = c['A'][j, :, :] Bj = c['B'][j, :, :] Pj = c['P'][j, :] for i in range(n_image): for t in range(d_image): for l in range(s_manifold): self.cvx_constr.append( Aj*g[i][j][l,t] == sum([Bj[l,m]*p[Pj[m]][t,i] \ for m in range(3)])) # w0_constr for j in range(m_gradients): Aj = c['A'][j, :, :] Bj = c['B'][j, :, :] Pj = c['P'][j, :] for i in range(n_image): self.cvx_constr.append(Aj * g0[i][j, :].T == Bj * p0[Pj, i]) # additional inequality constraints for i in range(n_image): for j in range(m_gradients): self.cvx_constr.append(cvx.norm(g[i][j], 2) <= c['lbd']) self.cvx_constr.append(cvx.norm(g0[i][j, :], 2) <= 1.0)