def get_envelope_map(self, sigma2, rho, env_lb=None, env_ub=None, minFreq=None, bfactor=None, rotavg=True): N = self.cryodata.N N_D = float(self.cryodata.N_D_Train) num_batches = float(self.cryodata.num_batches) psize = self.params['pixel_size'] mean_corr = self.correlation_history.get_mean().reshape((N, N)) mean_power = self.power_history.get_mean().reshape((N, N)) mean_mask = self.mask_history.get_mean().reshape((N, N)) mask_w = self.mask_history.get_wsum() * (N_D / num_batches) if rotavg: mean_corr = cryoem.rotational_average(mean_corr, normalize=True, doexpand=True) mean_power = cryoem.rotational_average(mean_power, normalize=True, doexpand=True) mean_mask = cryoem.rotational_average(mean_mask, normalize=False, doexpand=True) if isinstance(sigma2, n.ndarray): sigma2 = sigma2.reshape((N, N)) if bfactor is not None: coords = gencoords(N, 2).reshape((N**2, 2)) freqs = n.sqrt(n.sum(coords**2, axis=1)) / (psize * N) prior_envelope = ctf.envelope_function(freqs, bfactor).reshape( (N, N)) else: prior_envelope = 1.0 obsw = (mask_w * mean_mask / sigma2) exp_env = (mean_corr * obsw + prior_envelope * rho) / (mean_power * obsw + rho) if minFreq is not None: # Only consider envelope parameters for frequencies above a threshold minRad = minFreq * 2.0 * psize _, _, minRadMask = gencoords(N, 2, minRad, True) exp_env[minRadMask.reshape((N, N))] = 1.0 if env_lb is not None or env_ub is not None: n.clip(exp_env, env_lb, env_ub, out=exp_env) return exp_env
def eval(self, M, compute_gradient=True, fM=None, **kwargs): cparams = self.params cryodata = self.cryodata resolution = cparams['resolution'] posvar = float(cparams['centered_var']) / resolution**2 coords = n.require(geom.gencoords(M.shape[0],3).reshape(M.size,3), \ dtype=M.dtype) stats = cryodata.get_data_stats() N_D_Train = stats['N_D_Train'] outputs = {} Msum = n.sum(M, dtype=n.float64) com_num = n.dot(M.reshape((1, -1)), coords) com = com_num / Msum nlogP = n.sum(com**2) / (2 * posvar * N_D_Train) if compute_gradient: dcom = (coords.reshape(M.size, 3) / Msum) - (com_num.reshape(1, 3) / Msum**2) dnlogP = n.dot(dcom, com.T) / (posvar * N_D_Train) return nlogP, dnlogP.reshape(M.shape), outputs else: return nlogP, outputs
def generate_phantom_density(N, window, sigma, num_blobs, seed=None): if seed is not None: n.random.seed(seed) M = n.zeros((N, N, N), dtype=n.float32) coords = gencoords(N, 3).reshape((N**3, 3)) inside_window = n.sum(coords**2, axis=1).reshape((N, N, N)) < window**2 curr_c = n.array([0.0, 0.0, 0.0]) curr_n = 0 while curr_n < num_blobs: csigma = sigma * n.exp(0.25 * n.random.randn()) radM = n.sum((coords - curr_c.reshape((1, 3)))**2, axis=1).reshape( (N, N, N)) inside = n.logical_and(radM < (3 * csigma)**2, inside_window) # M[inside] = 1 M[inside] += n.exp(-0.5 * (radM[inside] / csigma**2)) curr_n += 1 curr_dir = n.random.randn(3) curr_dir /= n.sum(curr_dir**2) curr_c += 2.0 * csigma * curr_dir curr_w = n.sqrt(n.sum(curr_c**2)) while curr_w > window: curr_n_dir = curr_c / curr_w curr_r_dir = (2 * n.dot(curr_dir, curr_n_dir)) * curr_n_dir - curr_dir curr_c = curr_n_dir + (curr_w - window) * curr_r_dir curr_w = n.sqrt(n.sum(curr_c**2)) return M
def window_images(self,rad = 0.99): N = self.get_num_pixels() coords = geom.gencoords(N,2).reshape((N**2,2)) Cs = n.sum(coords**2,axis=1).reshape((N,N)) > (rad*N/2.0 - 1.5)**2 for img in self: img[Cs] = 0
def eval(self, M, compute_gradient=True, fM=None, **kwargs): cparams = self.params cryodata = self.cryodata resolution = cparams['resolution'] posvar = float(cparams['centered_var'])/resolution**2 coords = n.require(geom.gencoords(M.shape[0],3).reshape(M.size,3), \ dtype=M.dtype) stats = cryodata.get_data_stats() N_D_Train = stats['N_D_Train'] outputs = {} Msum = n.sum(M, dtype=n.float64) com_num = n.dot(M.reshape((1,-1)),coords) com = com_num / Msum nlogP = n.sum(com**2)/(2*posvar*N_D_Train) if compute_gradient: dcom = (coords.reshape(M.size,3) / Msum) - (com_num.reshape(1,3) / Msum**2) dnlogP = n.dot(dcom,com.T)/(posvar*N_D_Train) return nlogP, dnlogP.reshape(M.shape), outputs else: return nlogP, outputs
def compute_CAR_matrix(N, C): # print N, C print 'Computing CAR matrix...', ; sys.stdout.flush() midC = ((C.shape[0] - 1) / 2, (C.shape[1] - 1) / 2, (C.shape[2] - 1) / 2) assert C[midC[0], midC[1], midC[2]] == 0 coords = geom.gencoords(C.shape[0], 3, ).reshape(C.shape + (3,)) nzC = C != 0.0 ijs = [] vs = [] for (i, j, k) in itools.product(xrange(N), xrange(N), xrange(N)): out_ind = i * N ** 2 + j * N + k in_coords = (coords + n.array([i, j, k]).reshape((1, 1, 1, 3))).reshape((-1, 3)) in_inds = in_coords[:, 0] * N ** 2 + in_coords[:, 1] * N + in_coords[:, 2] valid_ins = nzC.reshape((-1,)) for ell in range(3): valid_ins = n.logical_and(valid_ins, in_coords[:, ell] >= 0) valid_ins = n.logical_and(valid_ins, in_coords[:, ell] < C.shape[ell]) nvalid = n.sum(valid_ins) ijs.append(n.vstack([out_ind * n.ones(nvalid), in_inds[valid_ins]])) vs.append(C[valid_ins.reshape(C.shape)]) W = spsp.csr_matrix((n.concatenate(vs), n.hstack(ijs)), shape=(N ** 3, N ** 3), dtype=n.float32) del vs del ijs print 'done.' return W
def compute_CAR_matrix(N,C): # print N, C print 'Computing CAR matrix...', ; sys.stdout.flush() midC = ((C.shape[0]-1)/2, (C.shape[1]-1)/2, (C.shape[2]-1)/2) assert C[midC[0],midC[1],midC[2]] == 0 coords = geom.gencoords(C.shape[0],3,).reshape(C.shape + (3,)) nzC = C != 0.0 ijs = [] vs = [] for (i,j,k) in itools.product(xrange(N),xrange(N),xrange(N)): out_ind = i*N**2 + j*N + k in_coords = (coords + n.array([i,j,k]).reshape((1,1,1,3))).reshape((-1,3)) in_inds = in_coords[:,0]*N**2 + in_coords[:,1]*N + in_coords[:,2] valid_ins = nzC.reshape((-1,)) for ell in range(3): valid_ins = n.logical_and(valid_ins,in_coords[:,ell] >= 0) valid_ins = n.logical_and(valid_ins,in_coords[:,ell] < C.shape[ell]) nvalid = n.sum(valid_ins) ijs.append(n.vstack([ out_ind*n.ones(nvalid), in_inds[valid_ins] ])) vs.append(C[valid_ins.reshape(C.shape)]) W = spsp.csr_matrix((n.concatenate(vs),n.hstack(ijs)),shape=(N**3,N**3),dtype=n.float32) del vs del ijs print 'done.' return W
def window(v, func='hanning', params=None): """ applies a windowing function to the 3D volume v (inplace, as reference) """ N = v.shape[0] D = v.ndim if any([d != N for d in list(v.shape)]) or D != 3: raise Exception("Error: Volume is not Cube.") def apply_seperable_window(v, w): v *= n.reshape(w, (-1, 1, 1)) v *= n.reshape(w, (1, -1, 1)) v *= n.reshape(w, (1, 1, -1)) if func == "hanning": w = n.hanning(N) apply_seperable_window(v, w) elif func == 'hamming': w = n.hamming(N) apply_seperable_window(v, w) elif func == 'gaussian': raise Exception('Unimplimented') elif func == 'circle': c = gencoords(N, 3) if params == None: r = N / 2 - 1 else: r = params[0] * (N / 2 * 1) v *= (n.sum(c**2, 1) < (r**2)).reshape((N, N, N)) elif func == 'box': v[:, 0, 0] = 0.0 v[0, :, 0] = 0.0 v[0, 0, :] = 0.0 else: raise Exception("Error: Window Type Not Supported")
def window (v, func='hanning', params=None): """ applies a windowing function to the 3D volume v (inplace, as reference) """ N = v.shape[0] D = v.ndim if any( [ d != N for d in list(v.shape) ] ) or D != 3: raise Exception("Error: Volume is not Cube.") def apply_seperable_window (v, w): v *= n.reshape(w,(-1,1,1)) v *= n.reshape(w,(1,-1,1)) v *= n.reshape(w,(1,1,-1)) if func=="hanning": w = n.hanning(N) apply_seperable_window(v,w) elif func=='hamming': w = n.hamming(N) apply_seperable_window(v,w) elif func=='gaussian': raise Exception('Unimplimented') elif func=='circle': c = gencoords(N,3) if params==None: r = N/2 -1 else: r = params[0]*(N/2*1) v *= (n.sum(c**2,1) < ( r ** 2 ) ).reshape((N,N,N)) elif func=='box': v[:,0,0] = 0.0 v[0,:,0] = 0.0 v[0,0,:] = 0.0 else: raise Exception("Error: Window Type Not Supported")
def generate_phantom_density(N,window,sigma,num_blobs,seed=None): if seed is not None: n.random.seed(seed) M = n.zeros((N,N,N),dtype=n.float32) coords = gencoords(N,3).reshape((N**3,3)) inside_window = n.sum(coords**2,axis=1).reshape((N,N,N)) < window**2 curr_c = n.array([0.0, 0.0 ,0.0]) curr_n = 0 while curr_n < num_blobs: csigma = sigma*n.exp(0.25*n.random.randn()) radM = n.sum((coords - curr_c.reshape((1,3)))**2,axis=1).reshape((N,N,N)) inside = n.logical_and(radM < (3*csigma)**2,inside_window) # M[inside] = 1 M[inside] += n.exp(-0.5*(radM[inside]/csigma**2)) curr_n += 1 curr_dir = n.random.randn(3) curr_dir /= n.sum(curr_dir**2) curr_c += 2.0*csigma*curr_dir curr_w = n.sqrt(n.sum(curr_c**2)) while curr_w > window: curr_n_dir = curr_c/curr_w curr_r_dir = (2*n.dot(curr_dir,curr_n_dir))*curr_n_dir - curr_dir curr_c = curr_n_dir + (curr_w - window)*curr_r_dir curr_w = n.sqrt(n.sum(curr_c**2)) return M
def window_images(self, rad=0.99): N = self.get_num_pixels() coords = geom.gencoords(N, 2).reshape((N**2, 2)) Cs = n.sum(coords**2, axis=1).reshape( (N, N)) > (rad * N / 2.0 - 1.5)**2 for img in self: img[Cs] = 0
def compute_shift_phases(pts,N,rad): xy = geom.gencoords(N,2,rad) N_T = xy.shape[0] N_S = pts.shape[0] S = n.empty((N_S,N_T),dtype=n.complex64) for (i,(sx,sy)) in enumerate(pts): S[i] = n.exp(2.0j*n.pi/N * (xy[:,0] * sx + xy[:,1] * sy)) return S
def compute_shift_phases(pts, N, rad): xy = geom.gencoords(N, 2, rad) N_T = xy.shape[0] N_S = pts.shape[0] S = n.empty((N_S, N_T), dtype=n.complex64) for (i, (sx, sy)) in enumerate(pts): S[i] = n.exp(2.0j * n.pi / N * (xy[:, 0] * sx + xy[:, 1] * sy)) return S
def rotational_expand(vals,N,D,interp_order=1): interp_coords = n.sqrt(n.sum(gencoords(N,D).reshape((N**D,D))**2,axis=1)).reshape((1,) + D*(N,)) if n.iscomplexobj(vals): rotexp = 1.0j*spinterp.map_coordinates(vals.imag, interp_coords, order=interp_order, mode='nearest') rotexp += spinterp.map_coordinates(vals.real, interp_coords, order=interp_order, mode='nearest') else: rotexp = spinterp.map_coordinates(vals, interp_coords, order=interp_order, mode='nearest') return rotexp
def get_envelope_map(self,sigma2,rho,env_lb=None,env_ub=None,minFreq=None,bfactor=None,rotavg=True): N = self.cryodata.N N_D = float(self.cryodata.N_D_Train) num_batches = float(self.cryodata.num_batches) psize = self.params['pixel_size'] mean_corr = self.correlation_history.get_mean().reshape((N,N)) mean_power = self.power_history.get_mean().reshape((N,N)) mean_mask = self.mask_history.get_mean().reshape((N,N)) mask_w = self.mask_history.get_wsum() * (N_D / num_batches) if rotavg: mean_corr = cryoem.rotational_average(mean_corr,normalize=True,doexpand=True) mean_power = cryoem.rotational_average(mean_power,normalize=True,doexpand=True) mean_mask = cryoem.rotational_average(mean_mask,normalize=False,doexpand=True) if isinstance(sigma2,n.ndarray): sigma2 = sigma2.reshape((N,N)) if bfactor is not None: coords = gencoords(N,2).reshape((N**2,2)) freqs = n.sqrt(n.sum(coords**2,axis=1))/(psize*N) prior_envelope = ctf.envelope_function(freqs,bfactor).reshape((N,N)) else: prior_envelope = 1.0 obsw = (mask_w * mean_mask / sigma2) exp_env = (mean_corr * obsw + prior_envelope*rho) / (mean_power * obsw + rho) if minFreq is not None: # Only consider envelope parameters for frequencies above a threshold minRad = minFreq*2.0*psize _, _, minRadMask = gencoords(N, 2, minRad, True) exp_env[minRadMask.reshape((N,N))] = 1.0 if env_lb is not None or env_ub is not None: n.clip(exp_env,env_lb,env_ub,out=exp_env) return exp_env
def rotational_average(M, maxRadius=None, doexpand=False, normalize=True, return_cnt=False): N = M.shape[0] D = len(M.shape) assert D >= 2, 'Cannot rotationally average a 1D array' pts = gencoords(N, D).reshape((N**D, D)) r = n.sqrt(n.sum(pts**2, axis=1)).reshape(M.shape) ir = n.require(n.floor(r), dtype='uint32') f = r - ir if maxRadius is None: maxRadius = n.ceil(n.sqrt(D) * N / D) if maxRadius < n.max(ir) + 2: valid_ir = ir + 1 < maxRadius ir = ir[valid_ir] f = f[valid_ir] M = M[valid_ir] if n.iscomplexobj(M): raps = 1.0j*n.bincount(ir, weights=(1-f)*M.imag, minlength=maxRadius) + \ n.bincount(ir+1, weights=f*M.imag, minlength=maxRadius) raps += n.bincount(ir, weights=(1-f)*M.real, minlength=maxRadius) + \ n.bincount(ir+1, weights=f*M.real, minlength=maxRadius) else: raps = n.bincount(ir, weights=(1-f)*M, minlength=maxRadius) + \ n.bincount(ir+1, weights=f*M, minlength=maxRadius) raps = raps[0:maxRadius] if normalize or return_cnt: cnt = n.bincount(ir, weights=(1-f), minlength=maxRadius) + \ n.bincount(ir+1, weights=f, minlength=maxRadius) cnt = cnt[0:maxRadius] if normalize: raps[cnt <= 0] = 0 raps[cnt > 0] /= cnt[cnt > 0] if doexpand: raps = rotational_expand(raps, N, D) if return_cnt: return raps, cnt else: return raps
def compute_density_moments(M, mu=None): N = M.shape[0] absM = (M**2).reshape((N**3, 1)) absM /= n.sum(absM) coords = gencoords(N, 3).reshape((N**3, 3)) if mu == None: wcoords = coords.reshape((N**3, 3)) * absM mu = n.sum(wcoords, axis=0).reshape((1, 3)) wccoords = n.sqrt(absM / N**3) * (coords - mu) covar = n.dot(wccoords.T, wccoords) return mu, covar
def compute_density_moments(M,mu=None): N = M.shape[0] absM = (M**2).reshape((N**3,1)) absM /= n.sum(absM) coords = gencoords(N,3).reshape((N**3,3)) if mu == None: wcoords = coords.reshape((N**3,3)) * absM mu = n.sum(wcoords,axis=0).reshape((1,3)) wccoords = n.sqrt(absM/N**3) * (coords - mu) covar = n.dot(wccoords.T,wccoords) return mu, covar
def rotate_density(M,R,t=None, upsamp=1.0): assert len(M.shape) == 3 N = M.shape[0] Nup = int(n.round(N*upsamp)) # print "Upsampling by", upsamp, "to", Nup, "^3" coords = gencoords(Nup,3).reshape((Nup**3,3)) / float(upsamp) if t is None: interp_coords = n.transpose(n.dot(coords, R.T)).reshape((3,Nup,Nup,Nup)) + N/2 else: interp_coords = n.transpose(n.dot(coords, R.T) + t).reshape((3,Nup,Nup,Nup)) + N/2 out = spinterp.map_coordinates(M,interp_coords,order=1) return out
def float_images(self,rad = 0.99): N = self.get_num_pixels() coords = geom.gencoords(N,2).reshape((N**2,2)) Cs = n.sum(coords**2,axis=1).reshape((N,N)) > (rad*N/2.0 - 1.5)**2 vals = [] for img in self: corner_pixels = img[Cs] float_val = n.mean(corner_pixels) img -= float_val vals.append(float_val) return vals
def float_images(self, rad=0.99): N = self.get_num_pixels() coords = geom.gencoords(N, 2).reshape((N**2, 2)) Cs = n.sum(coords**2, axis=1).reshape( (N, N)) > (rad * N / 2.0 - 1.5)**2 vals = [] for img in self: corner_pixels = img[Cs] float_val = n.mean(corner_pixels) img -= float_val vals.append(float_val) return vals
def rotational_expand(vals, N, D, interp_order=1): interp_coords = n.sqrt(n.sum(gencoords(N, D).reshape((N**D, D))**2, axis=1)).reshape((1, ) + D * (N, )) if n.iscomplexobj(vals): rotexp = 1.0j * spinterp.map_coordinates( vals.imag, interp_coords, order=interp_order, mode='nearest') rotexp += spinterp.map_coordinates(vals.real, interp_coords, order=interp_order, mode='nearest') else: rotexp = spinterp.map_coordinates(vals, interp_coords, order=interp_order, mode='nearest') return rotexp
def rotational_average(M,maxRadius=None, doexpand=False, normalize=True, return_cnt=False): N = M.shape[0] D = len(M.shape) assert D >= 2, 'Cannot rotationally average a 1D array' pts = gencoords(N,D).reshape((N**D,D)) r = n.sqrt(n.sum(pts**2,axis=1)).reshape(M.shape) ir = n.require(n.floor(r),dtype='uint32') f = r - ir if maxRadius is None: maxRadius = n.ceil(n.sqrt(D)*N/D) if maxRadius < n.max(ir)+2: valid_ir = ir+1 < maxRadius ir = ir[valid_ir] f = f[valid_ir] M = M[valid_ir] if n.iscomplexobj(M): raps = 1.0j*n.bincount(ir, weights=(1-f)*M.imag, minlength=maxRadius) + \ n.bincount(ir+1, weights=f*M.imag, minlength=maxRadius) raps += n.bincount(ir, weights=(1-f)*M.real, minlength=maxRadius) + \ n.bincount(ir+1, weights=f*M.real, minlength=maxRadius) else: raps = n.bincount(ir, weights=(1-f)*M, minlength=maxRadius) + \ n.bincount(ir+1, weights=f*M, minlength=maxRadius) raps = raps[0:maxRadius] if normalize or return_cnt: cnt = n.bincount(ir, weights=(1-f), minlength=maxRadius) + \ n.bincount(ir+1, weights=f, minlength=maxRadius) cnt = cnt[0:maxRadius] if normalize: raps[cnt <= 0] = 0 raps[cnt > 0] /= cnt[cnt > 0] if doexpand: raps = rotational_expand(raps,N,D) if return_cnt: return raps, cnt else: return raps
def rotate_density(M, R, t=None, upsamp=1.0): assert len(M.shape) == 3 N = M.shape[0] Nup = int(n.round(N * upsamp)) # print "Upsampling by", upsamp, "to", Nup, "^3" coords = gencoords(Nup, 3).reshape((Nup**3, 3)) / float(upsamp) if t is None: interp_coords = n.transpose(n.dot(coords, R.T)).reshape( (3, Nup, Nup, Nup)) + N / 2 else: interp_coords = n.transpose(n.dot(coords, R.T) + t).reshape( (3, Nup, Nup, Nup)) + N / 2 out = spinterp.map_coordinates(M, interp_coords, order=1) return out
def estimate_noise_variance(self,esttype='robust',zerosub=False,rad = 1.0): N = self.get_num_pixels() Cs = n.sum(geom.gencoords(N,2).reshape((N**2,2))**2,axis=1).reshape((N,N)) > (rad*N/2.0 - 1.5)**2 vals = [] for img in self: cvals = img[Cs] vals.append(cvals) if esttype == 'robust': if zerosub: var = (1.4826*n.median(n.abs(n.asarray(vals) - n.median(vals))))**2 else: var = (1.4826*n.median(n.abs(vals)))**2 elif esttype == 'mle': var = n.mean(n.asarray(vals)**2,dtype=n.float64) if zerosub: var -= n.mean(vals,dtype=n.float64)**2 return var
def get_W(self,N,car_type): if self.car_type != car_type or self.car_N != N: self.car_type = car_type self.car_N = N self.car_C = None if car_type.startswith('gauss'): sigma = float(car_type[5:]) Csz = 2*round(3*sigma) + 1 midpt = (Csz-1)/2 self.car_C = n.exp((-0.5/sigma**2)*n.sum(geom.gencoords(Csz,3).reshape((Csz,Csz,Csz,3))**2,axis=3)) self.car_C[midpt,midpt,midpt] = 0.0 self.car_C /= self.car_C.sum() else: assert False, 'Unrecognized car_type' self.car_W = compute_CAR_matrix(N,self.car_C) return self.car_W
def get_W(self, N, car_type): if self.car_type != car_type or self.car_N != N: self.car_type = car_type self.car_N = N self.car_C = None if car_type.startswith('gauss'): sigma = float(car_type[5:]) Csz = 2 * round(3 * sigma) + 1 midpt = (Csz - 1) / 2 self.car_C = n.exp( (-0.5 / sigma ** 2) * n.sum(geom.gencoords(Csz, 3).reshape((Csz, Csz, Csz, 3)) ** 2, axis=3)) self.car_C[midpt, midpt, midpt] = 0.0 self.car_C /= self.car_C.sum() else: assert False, 'Unrecognized car_type' self.car_W = compute_CAR_matrix(N, self.car_C) return self.car_W
def compute_fsc(VF1,VF2,maxrad,width=1.0,thresholds = [0.143,0.5]): assert VF1.shape == VF2.shape N = VF1.shape[0] r = n.sqrt(n.sum(gencoords(N,3).reshape((N,N,N,3))**2,axis=3)) prev_rad = -n.inf fsc = [] rads = [] resInd = len(thresholds)*[None] for i,rad in enumerate(n.arange(1.5,maxrad*N/2.0,width)): cxyz = n.logical_and(r >= prev_rad,r < rad) cF1 = VF1[cxyz] cF2 = VF2[cxyz] if len(cF1) == 0: break cCorr = n.vdot(cF1,cF2) / n.sqrt(n.vdot(cF1,cF1)*n.vdot(cF2,cF2)) for j,thr in enumerate(thresholds): if cCorr < thr and resInd[j] is None: resInd[j] = i fsc.append(cCorr.real) rads.append(rad/(N/2.0)) prev_rad = rad fsc = n.array(fsc) rads = n.array(rads) resolutions = [] for rI,thr in zip(resInd,thresholds): if rI is None: resolutions.append(rads[-1]) elif rI == 0: resolutions.append(n.inf) else: x = (thr - fsc[rI])/(fsc[rI-1] - fsc[rI]) resolutions.append(x*rads[rI-1] + (1-x)*rads[rI]) return rads, fsc, thresholds, resolutions
def compute_fsc(VF1, VF2, maxrad, width=1.0, thresholds=[0.143, 0.5]): assert VF1.shape == VF2.shape N = VF1.shape[0] r = n.sqrt(n.sum(gencoords(N, 3).reshape((N, N, N, 3))**2, axis=3)) prev_rad = -n.inf fsc = [] rads = [] resInd = len(thresholds) * [None] for i, rad in enumerate(n.arange(1.5, maxrad * N / 2.0, width)): cxyz = n.logical_and(r >= prev_rad, r < rad) cF1 = VF1[cxyz] cF2 = VF2[cxyz] if len(cF1) == 0: break cCorr = n.vdot(cF1, cF2) / n.sqrt(n.vdot(cF1, cF1) * n.vdot(cF2, cF2)) for j, thr in enumerate(thresholds): if cCorr < thr and resInd[j] is None: resInd[j] = i fsc.append(cCorr.real) rads.append(rad / (N / 2.0)) prev_rad = rad fsc = n.array(fsc) rads = n.array(rads) resolutions = [] for rI, thr in zip(resInd, thresholds): if rI is None: resolutions.append(rads[-1]) elif rI == 0: resolutions.append(n.inf) else: x = (thr - fsc[rI]) / (fsc[rI - 1] - fsc[rI]) resolutions.append(x * rads[rI - 1] + (1 - x) * rads[rI]) return rads, fsc, thresholds, resolutions
def estimate_noise_variance(self, esttype='robust', zerosub=False, rad=1.0): N = self.get_num_pixels() Cs = n.sum(geom.gencoords(N, 2).reshape((N**2, 2))**2, axis=1).reshape( (N, N)) > (rad * N / 2.0 - 1.5)**2 vals = [] for img in self: cvals = img[Cs] vals.append(cvals) if esttype == 'robust': if zerosub: var = (1.4826 * n.median(n.abs(n.asarray(vals) - n.median(vals))))**2 else: var = (1.4826 * n.median(n.abs(vals)))**2 elif esttype == 'mle': var = n.mean(n.asarray(vals)**2, dtype=n.float64) if zerosub: var -= n.mean(vals, dtype=n.float64)**2 return var
def set_data(self,cparams,minibatch): self.params = cparams self.minibatch = minibatch factoredRI = cparams.get('likelihood_factored_slicing',True) max_freq = cparams['max_frequency'] psize = cparams['pixel_size'] rad_cutoff = cparams.get('rad_cutoff', 1.0) rad = min(rad_cutoff,max_freq*2.0*psize) self.xy, self.trunc_xy, self.truncmask = gencoords(self.N, 2, rad, True) self.trunc_freq = n.require(self.trunc_xy / (self.N*psize), dtype=n.float32) self.N_T = self.trunc_xy.shape[0] interp_change = self.rad != rad or self.factoredRI != factoredRI if interp_change: print "Iteration {0}: freq = {3}, rad = {1}, N_T = {2}".format(cparams['iteration'], rad, self.N_T, max_freq) self.rad = rad self.factoredRI = factoredRI # Setup the quadrature schemes if not factoredRI: self.set_proj_quad(rad) else: self.set_slice_quad(rad) self.set_inplane_quad(rad) # Check shift quadrature self.set_shift_quad(rad) # Setup inlier model self.inlier_sigma2 = cparams['sigma']**2 base_sigma2 = self.cryodata.noise_var if isinstance(self.inlier_sigma2,n.ndarray): self.inlier_sigma2 = self.inlier_sigma2.reshape(self.truncmask.shape) self.inlier_sigma2_trunc = self.inlier_sigma2[self.truncmask != 0] self.inlier_const = (self.N_T/2.0)*n.log(2.0*n.pi) + 0.5*n.sum(n.log(self.inlier_sigma2_trunc)) else: self.inlier_sigma2_trunc = self.inlier_sigma2 self.inlier_const = (self.N_T/2.0)*n.log(2.0*n.pi*self.inlier_sigma2) # Compute the likelihood for the image content outside of rad _,_,fspace_truncmask = gencoords(self.fspace_stack.get_num_pixels(), 2, rad*self.fspace_stack.get_num_pixels()/self.N, True) self.imgpower = n.empty((self.minibatch['N_M'],),dtype=density.real_t) self.imgpower_trunc = n.empty((self.minibatch['N_M'],),dtype=density.real_t) for idx,Idx in enumerate(self.minibatch['img_idxs']): Img = self.fspace_stack.get_image(Idx) self.imgpower[idx] = n.sum(Img.real**2) + n.sum(Img.imag**2) Img_trunc = Img[fspace_truncmask.reshape(Img.shape) == 0] self.imgpower_trunc[idx] = n.sum(Img_trunc.real**2) + n.sum(Img_trunc.imag**2) like_trunc = 0.5*self.imgpower_trunc/base_sigma2 self.inlier_like_trunc = like_trunc self.inlier_const += ((self.N**2 - self.N_T)/2.0)*n.log(2.0*n.pi*base_sigma2) # Setup the envelope function envelope = self.params.get('exp_envelope',None) if envelope is not None: envelope = envelope.reshape((-1,)) envelope = envelope[self.truncmask != 0] envelope = n.require(envelope,dtype=n.float32) else: bfactor = self.params.get('learn_like_envelope_bfactor',500.0) if bfactor is not None: freqs = n.sqrt(n.sum(self.trunc_xy**2,axis=1))/(psize*self.N) envelope = ctf.envelope_function(freqs,bfactor) self.envelope = envelope
def compute_full_ctf(rots, N, psize, akv, csf, wgh, dfmid1, dfmid2, angastf, dscale, bfactor): freqs = geom.gencoords(N, 2) / (N * psize) return compute_ctf(freqs, rots, akv, csf, wgh, dfmid1, dfmid2, angastf, dscale, bfactor)
wgh = 0.07 cs = 2.0 df1, df2, angast = 44722, 49349, 45.0 * (n.pi / 180.0) dscale = 1.0 v1 = compute_ctf(fcoords, rots, akv, cs, wgh, df1, df2, angast, dscale).reshape((-1, )) v2 = compute_ctf(rotfcoords, None, akv, cs, wgh, df1, df2, angast, dscale).reshape((-1, )) # This being small confirms that using the rots parameter is equivalent to rotating the coordinates print n.abs(v1 - v2).max() N = 512 psz = 5.6 rad = 0.25 fcoords = geom.gencoords(N, 2, rad) / (N * psz) ctf1_rot = compute_full_ctf(rots, N, psz, akv, cs, wgh, df1, df2, angast, dscale, None) ctf2_full = compute_full_ctf(None, N, psz, akv, cs, wgh, df1, df2, angast, dscale, None) P_rot = coops.compute_inplanerot_matrix(rots, N, 'lanczos', 10, rad) ctf2_rot = P_rot.dot(ctf2_full).reshape((-1, )) P_null = coops.compute_inplanerot_matrix(n.array([0]), N, 'linear', 2, rad) ctf1_rot = P_null.dot(ctf1_rot).reshape((-1, )) roterr = ctf1_rot - ctf2_rot relerr = n.abs(roterr) / n.maximum(n.abs(ctf1_rot), n.abs(ctf2_rot)) # This being small confirms that compute_inplane_rotmatrix and rots use the same rotation convention
def compute_full_ctf(rots,N,psize,akv,csf,wgh,dfmid1,dfmid2,angastf,dscale,bfactor): freqs = geom.gencoords(N,2)/(N*psize) return compute_ctf(freqs,rots,akv,csf,wgh,dfmid1,dfmid2,angastf,dscale,bfactor)
akv = 200 wgh=0.07 cs=2.0 df1, df2, angast = 44722,49349,45.0*(n.pi/180.0) dscale = 1.0 v1 = compute_ctf(fcoords,rots,akv,cs,wgh,df1,df2,angast,dscale).reshape((-1,)) v2 = compute_ctf(rotfcoords,None,akv,cs,wgh,df1,df2,angast,dscale).reshape((-1,)) # This being small confirms that using the rots parameter is equivalent to rotating the coordinates print n.abs(v1-v2).max() N = 512 psz = 5.6 rad = 0.25 fcoords = geom.gencoords(N, 2, rad) / (N*psz) ctf1_rot = compute_full_ctf(rots,N,psz,akv,cs,wgh,df1,df2,angast,dscale,None) ctf2_full = compute_full_ctf(None,N,psz,akv,cs,wgh,df1,df2,angast,dscale,None) P_rot = coops.compute_inplanerot_matrix(rots,N,'lanczos',10,rad) ctf2_rot = P_rot.dot(ctf2_full).reshape((-1,)) P_null = coops.compute_inplanerot_matrix(n.array([0]),N,'linear',2,rad) ctf1_rot = P_null.dot(ctf1_rot).reshape((-1,)) roterr = ctf1_rot - ctf2_rot relerr = n.abs(roterr)/n.maximum(n.abs(ctf1_rot),n.abs(ctf2_rot)) # This being small confirms that compute_inplane_rotmatrix and rots use the same rotation convention print relerr.max(), relerr.mean()
def set_data(self, cparams, minibatch): self.params = cparams self.minibatch = minibatch factoredRI = cparams.get('likelihood_factored_slicing', True) max_freq = cparams['max_frequency'] psize = cparams['pixel_size'] rad_cutoff = cparams.get('rad_cutoff', 1.0) rad = min(rad_cutoff, max_freq * 2.0 * psize) self.xy, self.trunc_xy, self.truncmask = gencoords( self.N, 2, rad, True) self.trunc_freq = n.require(self.trunc_xy / (self.N * psize), dtype=n.float32) self.N_T = self.trunc_xy.shape[0] interp_change = self.rad != rad or self.factoredRI != factoredRI if interp_change: print "Iteration {0}: freq = {3}, rad = {1}, N_T = {2}".format( cparams['iteration'], rad, self.N_T, max_freq) self.rad = rad self.factoredRI = factoredRI # Setup the quadrature schemes if not factoredRI: self.set_proj_quad(rad) else: self.set_slice_quad(rad) self.set_inplane_quad(rad) # Check shift quadrature self.set_shift_quad(rad) # Setup inlier model self.inlier_sigma2 = cparams['sigma']**2 base_sigma2 = self.cryodata.noise_var if isinstance(self.inlier_sigma2, n.ndarray): self.inlier_sigma2 = self.inlier_sigma2.reshape( self.truncmask.shape) self.inlier_sigma2_trunc = self.inlier_sigma2[self.truncmask != 0] self.inlier_const = (self.N_T / 2.0) * n.log( 2.0 * n.pi) + 0.5 * n.sum(n.log(self.inlier_sigma2_trunc)) else: self.inlier_sigma2_trunc = self.inlier_sigma2 self.inlier_const = (self.N_T / 2.0) * n.log( 2.0 * n.pi * self.inlier_sigma2) # Compute the likelihood for the image content outside of rad _, _, fspace_truncmask = gencoords( self.fspace_stack.get_num_pixels(), 2, rad * self.fspace_stack.get_num_pixels() / self.N, True) self.imgpower = n.empty((self.minibatch['N_M'], ), dtype=density.real_t) self.imgpower_trunc = n.empty((self.minibatch['N_M'], ), dtype=density.real_t) for idx, Idx in enumerate(self.minibatch['img_idxs']): Img = self.fspace_stack.get_image(Idx) self.imgpower[idx] = n.sum(Img.real**2) + n.sum(Img.imag**2) Img_trunc = Img[fspace_truncmask.reshape(Img.shape) == 0] self.imgpower_trunc[idx] = n.sum(Img_trunc.real**2) + n.sum( Img_trunc.imag**2) like_trunc = 0.5 * self.imgpower_trunc / base_sigma2 self.inlier_like_trunc = like_trunc self.inlier_const += ( (self.N**2 - self.N_T) / 2.0) * n.log(2.0 * n.pi * base_sigma2) # Setup the envelope function envelope = self.params.get('exp_envelope', None) if envelope is not None: envelope = envelope.reshape((-1, )) envelope = envelope[self.truncmask != 0] envelope = n.require(envelope, dtype=n.float32) else: bfactor = self.params.get('learn_like_envelope_bfactor', 500.0) if bfactor is not None: freqs = n.sqrt(n.sum(self.trunc_xy**2, axis=1)) / (psize * self.N) envelope = ctf.envelope_function(freqs, bfactor) self.envelope = envelope