def test_complex_to_complex_2d(verbose): fft = fftpack.complex_to_complex_2d((6, 10)) n = fft.n() vc = flex.complex_double(flex.grid(n)) vd = flex.double(flex.grid((n[0], 2 * n[1]))) for i in range(vc.size()): vc[i] = complex(2 * i, 2 * i + 1) for i in range(vd.size()): vd[i] = i vct = fft.forward(vc) vdt = fft.forward(vd) for t in (vct, vdt): assert t.origin() == (0, 0) assert t.all() == fft.n() assert t.focus() == fft.n() if (verbose): show_cseq(vc) assert_complex_eq_real(vc, vd) vct = fft.backward(vc) vdt = fft.backward(vd) for t in (vct, vdt): assert t.origin() == (0, 0) assert t.all() == fft.n() assert t.focus() == fft.n() if (verbose): show_cseq(vc) assert_complex_eq_real(vc, vd) s = vd.size() // 2 for i in range(vd.size()): assert approx_equal(vd[i], s * i)
def background_correct(data, raw_asic): prime_asic = get_factorizable_block(raw_asic) print "Working on block", prime_asic block = data.matrix_copy_block(i_row=prime_asic[0], i_column=prime_asic[1], n_rows=prime_asic[2] - prime_asic[0], n_columns=prime_asic[3] - prime_asic[1]) complex_data = flex.polar(block.as_double(), flex.double(flex.grid(block.focus()))) from scitbx import fftpack fft = fftpack.complex_to_complex_2d(block.focus()) # input data here fft.forward(complex_data) # your manipulation here low_pass_filter(complex_data) fft.backward(complex_data) # real data filtered_data = flex.real(complex_data) / (fft.n()[0] * fft.n()[1]) corrected_data = block - filtered_data.iround() requested_block = data.matrix_copy_block(i_row=raw_asic[0], i_column=raw_asic[1], n_rows=raw_asic[2] - raw_asic[0], n_columns=raw_asic[3] - raw_asic[1]) requested_block.matrix_paste_block_in_place( block=corrected_data, i_row=prime_asic[0] - raw_asic[0], i_column=prime_asic[1] - raw_asic[1]) return requested_block
def test_complex_to_complex_2d(verbose): fft = fftpack.complex_to_complex_2d((6,10)) n = fft.n() vc = flex.complex_double(flex.grid(n)) vd = flex.double(flex.grid((n[0], 2*n[1]))) for i in xrange(vc.size()): vc[i] = complex(2*i, 2*i+1) for i in xrange(vd.size()): vd[i] = i vct = fft.forward(vc) vdt = fft.forward(vd) for t in (vct, vdt): assert t.origin() == (0,0) assert t.all() == fft.n() assert t.focus() == fft.n() if (verbose): show_cseq(vc) assert_complex_eq_real(vc, vd) vct = fft.backward(vc) vdt = fft.backward(vd) for t in (vct, vdt): assert t.origin() == (0,0) assert t.all() == fft.n() assert t.focus() == fft.n() if (verbose): show_cseq(vc) assert_complex_eq_real(vc, vd) s = vd.size() // 2 for i in xrange(vd.size()): assert approx_equal(vd[i], s*i)
def background_correct(data, raw_asic): prime_asic = get_factorizable_block(raw_asic) print "Working on block",prime_asic block = data.matrix_copy_block( i_row=prime_asic[0],i_column=prime_asic[1], n_rows=prime_asic[2]-prime_asic[0], n_columns=prime_asic[3]-prime_asic[1]) complex_data = flex.polar(block.as_double(),flex.double(flex.grid(block.focus()))) from scitbx import fftpack fft = fftpack.complex_to_complex_2d(block.focus()) # input data here fft.forward(complex_data) # your manipulation here low_pass_filter(complex_data) fft.backward(complex_data) # real data filtered_data = flex.real(complex_data)/(fft.n()[0]*fft.n()[1]) corrected_data = block - filtered_data.iround() requested_block = data.matrix_copy_block( i_row=raw_asic[0],i_column=raw_asic[1], n_rows=raw_asic[2]-raw_asic[0], n_columns=raw_asic[3]-raw_asic[1]) requested_block.matrix_paste_block_in_place( block = corrected_data, i_row = prime_asic[0] - raw_asic[0], i_column = prime_asic[1] - raw_asic[1] ) return requested_block
def tst_rotation_fft(args): filename = args[0] filename2 = args[1] beta = float(args[2]) nmax = 20 nlm_array = math.nlm_array(nmax) coefs = easy_pickle.load(filename) nlm_array.load_coefs(nlm_array.nlm(), coefs) this_nlm_array = math.nlm_array(nmax) coefs = easy_pickle.load(filename2) this_nlm_array.load_coefs(nlm_array.nlm(), coefs) beta = smath.pi * beta cc_obj = correlation(nlm_array, this_nlm_array, nmax, beta) mm = cc_obj.mm_coef(0) fft_input = flex.complex_double(flex.grid(2 * nmax + 1, 2 * nmax + 1)) fft_r = tst_rotation(args) for ii in range(mm.size()): fft_input[ii] = mm[ii] # print ii, mm[ii], fft_r[ii]/1681.0 fft = fftpack.complex_to_complex_2d(2 * nmax + 1, 2 * nmax + 1) result = fft.backward(fft_input) out = open("fft_" + str(beta) + ".dat", 'w') for ii in range(2 * nmax + 1): for jj in range(2 * nmax + 1): print >> out, ii * 9, jj * 9, abs(result[(ii, jj)]) print >> out out.close()
def build_scat_pat(data): print "DO FFT" np,np = data.focus() flex_grid=flex.grid(np,np) fft_input=flex.complex_double(flex_grid) for ii in range( fft_input.size() ): fft_input[ii] = complex( data[ii],0 ) fft_obj = fftpack.complex_to_complex_2d( (np,np) ) result = fft_obj.forward( fft_input ) result = flex.abs( result ) result = result*result result = reorder_and_cut_data(result,np,np/10) return result
def tst_rotation(args): filename = args[0] filename2 = args[1] beta = float(args[2]) ngrid = 40 nmax = 20 nlm_array = math.nlm_array(nmax) coefs = easy_pickle.load(filename) nlm_array.load_coefs(nlm_array.nlm(), coefs) this_nlm_array = math.nlm_array(nmax) coefs = easy_pickle.load(filename2) this_nlm_array.load_coefs(nlm_array.nlm(), coefs) beta = smath.pi * beta cc_obj = correlation(nlm_array, this_nlm_array, nmax, beta) fft_input = flex.complex_double(flex.grid(2 * nmax + 1, 2 * nmax + 1)) count = 0 radian = 180.0 / smath.pi out = open("scan_" + str(beta) + ".dat", 'w') for ii in range(ngrid + 1): for jj in range(ngrid + 1): alpha = ii * smath.pi * 2.0 / ngrid gama = jj * smath.pi * 2.0 / ngrid cc = cc_obj.calc_correlation(alpha, beta, gama) fft_input[count] = cc count = count + 1 print >> out, alpha * radian, gama * radian, abs(cc) print >> out out.close() fft = fftpack.complex_to_complex_2d(2 * nmax + 1, 2 * nmax + 1) result = fft.forward(fft_input) #return result result = fft.backward(result) out = open("fft_fake_" + str(beta) + ".dat", 'w') for ii in range(2 * nmax + 1): for jj in range(2 * nmax + 1): print >> out, ii * 9, jj * 9, abs(result[(jj, ii)]) print >> out out.close()
def background_correct_padded_block(data, raw_asic): Pad = padded_unpadded(data,raw_asic) block = Pad.get_padded_input_data() complex_data = flex.polar(block.as_double(),flex.double(flex.grid(block.focus()))) from scitbx import fftpack fft = fftpack.complex_to_complex_2d(block.focus()) # input data here fft.forward(complex_data) # your manipulation here low_pass_filter(complex_data) fft.backward(complex_data) # real data filtered_data = flex.real(complex_data)/(fft.n()[0]*fft.n()[1]) # XXX change this depending on float/int data type: corrected_data = block - filtered_data.iround() return Pad.get_unpadded_result_data(corrected_data)
def scan( self ): fft = fftpack.complex_to_complex_2d( self.ngrid, self.ngrid ) inversion = False for beta in self.beta: self.cc_obj.set_beta( beta ) mm = self.cc_obj.mm_coef(0,inversion) if( self.pad > 0): mm = self.cc_obj.mm_coef(self.pad, inversion) fft_input= mm scores = fft.backward( fft_input ).as_1d() self.scores = self.scores.concatenate( -flex.norm( scores ) ) self.best_indx = flex.min_index( self.scores ) self.best_score = math.sqrt( -self.scores[ self.best_indx ]) if self.check_inversion: ### Inversion of the Spherical Harmonics ### inversion = True inversion_scores = flex.double() for beta in self.beta: self.cc_obj.set_beta( beta ) mm = self.cc_obj.mm_coef(0,inversion) if( self.pad > 0): mm = self.cc_obj.mm_coef(self.pad, inversion) fft_input= mm.deep_copy() scores = fft.backward( fft_input ).as_1d() inversion_scores = inversion_scores.concatenate( -flex.norm( scores ) ) inv_best_indx = flex.min_index( inversion_scores ) inv_best_score = math.sqrt(-inversion_scores[ inv_best_indx ] ) if( inv_best_score < self.best_score ): self.score = inversion_scores self.best_indx = inv_best_indx self.best_score = inv_best_score self.inversion = True else: self.inversion = False b=self.best_indx//(self.ngrid*self.ngrid) a=(self.best_indx - self.ngrid*self.ngrid*b ) // self.ngrid g=self.best_indx - self.ngrid*self.ngrid*b - self.ngrid*a b = self.beta[b] g = math.pi*2.0 *( float(g)/(self.ngrid-1) ) a = math.pi*2.0 *( float(a)/(self.ngrid-1) ) self.best_ea = (a, b, g ) self.find_top( self.topn ) if( self.refine ): self.refined = [] self.refined_moving_nlm = [] self.refined_score = flex.double() for t in self.top_align: r = self.run_simplex( t ) self.refined.append ( r ) self.refined_score.append( self.get_cc( self.target( r ) ) ) self.refined_moving_nlm.append( self.cc_obj.rotate_moving_obj( r[0],r[1], r[2], self.inversion ) ) orders=flex.sort_permutation( self.refined_score, True ) self.best_score = -self.refined_score[orders[0]] # show the refined results if( self.show_result ): print("refined results:") for ii in range( self.topn ): o = orders[ii] o = ii print(ii, ":", list( self.refined[o] ), ":", self.refined_score[o]) ea = self.refined[ orders[0] ] self.best_ea = (ea[0], ea[1], ea[2] ) self.moving_nlm = self.cc_obj.rotate_moving_obj( ea[0],ea[1], ea[2], self.inversion )
def tst_fft_proj(pdbfile, nmax=20): dx = 1.0 projection_obj = projection.projection(pdbfile, dx=dx, fraction=0.5) dq = projection_obj.get_dq() image = projection_obj.project() output = open('prj1.dat', 'w') for pt in image: print >> output, pt[0], pt[1], pt[2] output.close() values = projection_obj.get_value() np = projection_obj.get_np() flex_grid = flex.grid(np, np) fft_input = flex.complex_double(flex_grid) for ii in range(fft_input.size()): fft_input[ii] = complex(values[ii], 0) fft_obj = fftpack.complex_to_complex_2d((np, np)) result = fft_obj.forward(fft_input) sp_image = flex.vec3_double() for ii in range(np): for jj in range(np): kk = ii ll = jj if kk > np / 2: kk = kk - np if ll > np / 2: ll = ll - np sp_image.append( [kk + np / 2, ll + np / 2, abs(result[(ii, jj)])**2.0]) Nq = np / 2 Nphi = Nq c2_image, normalized_sp = from_I_to_C2(sp_image, Nq, Nphi, N=np, further_reduct=True) image = normalized_sp NP = int(smath.sqrt(image.size())) N = NP / 2 sp_n = N grid_2d = math.two_d_grid(N, nmax) grid_2d.clean_space(image) grid_2d.construct_space_sum() zernike_2d_mom = math.two_d_zernike_moments(grid_2d, nmax) sp_moments = zernike_2d_mom.moments() # sp_reconst = image_tools.generate_image2(nmax, sp_moments, normalized_sp, sp_n) # c2_image, normalized_sp = from_I_to_C2(sp_reconst, Nq, Nphi, N=np) sp_out = open('sp_image.dat', 'w') for pt in sp_image: print >> sp_out, (pt[0] - sp_n) * dq, (pt[1] - sp_n) * dq, pt[2] sp_out.close() c2_output = open('c2.dat', 'w') for pt in c2_image: print >> c2_output, pt[0], pt[1], pt[2] c2_output.close() image = c2_image NP = int(smath.sqrt(image.size())) N = NP / 2 c2_n = N # grid_2d = math.two_d_grid(N, nmax) # grid_2d.clean_space( image ) # grid_2d.construct_space_sum() # zernike_2d_mom = math.two_d_zernike_moments( grid_2d, nmax ) # c2_moments = zernike_2d_mom.moments() # coefs = ( c2_moments ) nls = math.nl_array(nmax).nl() # for nl, c2m in zip( nls, coefs ): # print nl, c2m sp_moments[0] = 0 nmax4c2 = 2 * nmax Inm = math.nl_c_array(nmax4c2) coef_table = image_tools.calc_integral_triple_zernike2d(nmax4c2) Inm.load_coefs(nls, sp_moments) cnm = image_tools.calc_Cnm_from_Inm(Inm, coef_table, nmax4c2) cnm_coef = cnm.coefs() # for nl, mm,mmm in zip( nls, c2_moments, cnm_coef ): # print abs(mm), abs(mmm) #cnm_coef = c2_moments c2_reconst = image_tools.generate_image2(nmax, cnm_coef, c2_image, c2_n) c2_r = open('c2r.dat', 'w') for pt in c2_reconst: print >> c2_r, pt[0], pt[1], pt[2] c2_r.close() exit()
def lewis(template, img): """The lewis() function computes the normalised cross-correlation (NCC) of an image, @p img, and a template, @p template. Both image and template must be two-dimensional, real, and finite. The image must be larger than the template, which in turn should contain more than one pixel, and the template must have positive variance. The function returns the correlation coefficients in the range [-1, +1]. See Lewis, J. P. (1995) "Fast Template Matching", Vision Interface, 120-123. @note This function should be equivalent to MATLAB's normxcorr2() function. @param img Two-dimensional intensity image @param template Two-dimensional intensity template @return Correlation coefficients """ import math import numpy from sys import float_info from scitbx import fftpack from scitbx.array_family import flex # Assert that image and template are two-dimensional arrays, and # that the template is no larger than image. Assert that template # is not flat. XXX Check for real and finite, too? assert len(img.focus()) == 2 and len(template.focus()) == 2 assert img.focus()[0] >= template.focus()[0] and img.focus()[1] >= template.focus()[1] assert template.sample_standard_deviation() > 0 # For conformance with MATLAB's normxcorr2() and geck 342320: for # numerical robustness, ensure that both image and template are # always non-negative. img_nn = img - min(0, flex.min(img)) template_nn = template - min(0, flex.min(template)) # Calculate the terms of the denominator of gamma. Must guard # against negative variance of the image due to inaccuracies in the # one-pass formula. img_sum = _summed_area_table(img_nn, template_nn.focus()[0], template_nn.focus()[1]) img_ssq = _summed_area_table(flex.pow2(img_nn), template_nn.focus()[0], template_nn.focus()[1]) f_sigma = img_ssq - img_sum * img_sum / (template_nn.focus()[0] * template_nn.focus()[1]) f_sigma.set_selected(f_sigma < 0, 0) f_sigma = flex.sqrt(f_sigma) t_sigma = (template_nn - flex.mean(template_nn)).norm() gamma_denominator = f_sigma * t_sigma # Zero-pad the image to permit partial overlap of template and # image, and embed the time-reversed template in a zero-padded array # of the same size. Zero-padding means the entire template is # always overlapping the image, and terms involving the template # mean cancel in the expansion of the numerator of gamma. # # Note: the NCC demands the template to be time-reversed, which can # be accomplished by conjugation in the frequency domain. An # implementation following that approach would however require # special care to be taken for the first rows and columns: # # from numpy import roll # t_embed.matrix_paste_block_in_place( # block=template_nn, # i_row=full[0] - template_nn.focus()[0], # i_column=full[1] - template_nn.focus()[1]) # t_embed = flex.double(roll( # roll(t_embed.as_numpy_array(), 1, axis=0), 1, axis=1)) # # Calculate correlation in frequency domain. XXX Could use spatial # domain calculation in cases where it's faster (see MATLAB's # implementation). full = (img_nn.focus()[0] + template_nn.focus()[0] - 1, img_nn.focus()[1] + template_nn.focus()[1] - 1) f_embed = flex.double(flex.grid(full)) f_embed.matrix_paste_block_in_place(block=img_nn, i_row=0, i_column=0) f_prime = flex.complex_double(reals=f_embed, imags=flex.double(flex.grid(full))) t_embed = flex.double(flex.grid(full)) t_embed.matrix_paste_block_in_place(block=template_nn.matrix_rot90(2), i_row=0, i_column=0) t_prime = flex.complex_double(reals=t_embed, imags=flex.double(flex.grid(full))) fft = fftpack.complex_to_complex_2d(full) fft.forward(f_prime) fft.forward(t_prime) gamma_numerator = f_prime * t_prime fft.backward(gamma_numerator) gamma_numerator = flex.real(gamma_numerator) / (fft.n()[0] * fft.n()[1]) - img_sum * flex.mean(template_nn) # For conformance with MATLAB: set the NCC to zero in regions where # the image has zero variance over the extent of the template. If, # due to small variances in the image or the template, a correlation # coefficient falls outside the range [-1, 1], set it to zero to # reflect the undefined 0/0 condition. tol = math.sqrt(math.ldexp(float_info.epsilon, math.frexp(flex.max(flex.abs(gamma_denominator)))[1] - 1)) sel = gamma_denominator <= tol gamma = gamma_numerator.set_selected(sel, 0) / gamma_denominator.set_selected(sel, 1) gamma.set_selected(flex.abs(gamma) > 1 + math.sqrt(float_info.epsilon), 0) return gamma
def scan(self): fft = fftpack.complex_to_complex_2d(self.ngrid, self.ngrid) inversion = False for beta in self.beta: self.cc_obj.set_beta(beta) mm = self.cc_obj.mm_coef(0, inversion) if self.pad > 0: mm = self.cc_obj.mm_coef(self.pad, inversion) fft_input = mm scores = fft.backward(fft_input).as_1d() self.scores = self.scores.concatenate(-flex.norm(scores)) self.best_indx = flex.min_index(self.scores) self.best_score = smath.sqrt(-self.scores[self.best_indx]) if self.check_inversion: ### Inversion of the Spherical Harmonics ### inversion = True inversion_scores = flex.double() for beta in self.beta: self.cc_obj.set_beta(beta) mm = self.cc_obj.mm_coef(0, inversion) if self.pad > 0: mm = self.cc_obj.mm_coef(self.pad, inversion) fft_input = mm.deep_copy() scores = fft.backward(fft_input).as_1d() inversion_scores = inversion_scores.concatenate(-flex.norm(scores)) inv_best_indx = flex.min_index(inversion_scores) inv_best_score = smath.sqrt(-inversion_scores[inv_best_indx]) if inv_best_score < self.best_score: self.score = inversion_scores self.best_indx = inv_best_indx self.best_score = inv_best_score self.inversion = True else: self.inversion = False b = self.best_indx // (self.ngrid * self.ngrid) a = (self.best_indx - self.ngrid * self.ngrid * b) // self.ngrid g = self.best_indx - self.ngrid * self.ngrid * b - self.ngrid * a b = self.beta[b] g = smath.pi * 2.0 * (float(g) / (self.ngrid - 1)) a = smath.pi * 2.0 * (float(a) / (self.ngrid - 1)) self.best_ea = (a, b, g) self.find_top(self.topn) if self.refine: self.refined = [] self.refined_moving_nlm = [] self.refined_score = flex.double() for t in self.top_align: r = self.run_simplex(t) self.refined.append(r) self.refined_score.append(self.get_cc(self.target(r))) self.refined_moving_nlm.append(self.cc_obj.rotate_moving_obj(r[0], r[1], r[2], self.inversion)) orders = flex.sort_permutation(self.refined_score, True) self.best_score = -self.refined_score[orders[0]] # show the refined results if self.show_result: print "refined results:" for ii in range(self.topn): o = orders[ii] o = ii print ii, ":", list(self.refined[o]), ":", self.refined_score[o] ea = self.refined[orders[0]] self.best_ea = (ea[0], ea[1], ea[2]) self.moving_nlm = self.cc_obj.rotate_moving_obj(ea[0], ea[1], ea[2], self.inversion)