def algorithm_4(f_obs, F, phase_source, max_cycles=100, auto_converge_eps=1.e-7, use_cpp=True): """ Phased simultaneous search (alg4) """ fc, f_masks = F[0], F[1:] fc = fc.deep_copy() F = [fc] + F[1:] # C++ version if (use_cpp): return mosaic_ext.alg4([f.data() for f in F], f_obs.data(), phase_source.data(), max_cycles, auto_converge_eps) # Python version (1.2-3 times slower, but much more readable!) cntr = 0 x_prev = None while True: f_obs_cmpl = f_obs.phase_transfer(phase_source=phase_source) A = [] b = [] for j, Fj in enumerate(F): A_rows = [] for n, Fn in enumerate(F): Gjn = flex.real(Fj.data() * flex.conj(Fn.data())) A_rows.append(flex.sum(Gjn)) Hj = flex.real(Fj.data() * flex.conj(f_obs_cmpl.data())) b.append(flex.sum(Hj)) A.extend(A_rows) A = matrix.sqr(A) A_1 = A.inverse() b = matrix.col(b) x = A_1 * b # fc_d = flex.complex_double(phase_source.indices().size(), 0) for i, f in enumerate(F): fc_d += f.data() * x[i] phase_source = phase_source.customized_copy(data=fc_d) x_ = x[:] # cntr += 1 if (cntr > max_cycles): break if (x_prev is None): x_prev = x_[:] else: max_diff = flex.max( flex.abs(flex.double(x_prev) - flex.double(x_))) if (max_diff <= auto_converge_eps): break x_prev = x_[:] return x_
def update_target_and_grads(self, x): self.x = x s = 1 #180/math.pi i_model = flex.double(self.i_obs.data().size(), 0) for n, kn in enumerate(self.x): for m, km in enumerate(self.x): tmp = self.F[n].data() * flex.conj(self.F[m].data()) i_model += kn * km * flex.real(tmp) #pn = self.F[n].phases().data()*s #pm = self.F[m].phases().data()*s #Fn = flex.abs(self.F[n].data()) #Fm = flex.abs(self.F[m].data()) #i_model += kn*km*Fn*Fm*flex.cos(pn-pm) diff = i_model - self.i_obs.data() t = flex.sum(diff * diff) / 4 # g = flex.double() for j in range(len(self.F)): tmp = flex.double(self.i_obs.data().size(), 0) for m, km in enumerate(self.x): tmp += km * flex.real( self.F[j].data() * flex.conj(self.F[m].data())) #pj = self.F[j].phases().data()*s #pm = self.F[m].phases().data()*s #Fj = flex.abs(self.F[j].data()) #Fm = flex.abs(self.F[m].data()) #tmp += km * Fj*Fm*flex.cos(pj-pm) g.append(flex.sum(diff * tmp)) self.t = t self.g = g # if self.use_curvatures: d = flex.double() for j in range(len(self.F)): tmp1 = flex.double(self.i_obs.data().size(), 0) tmp2 = flex.double(self.i_obs.data().size(), 0) for m, km in enumerate(self.x): zz = flex.real(self.F[j].data() * flex.conj(self.F[m].data())) tmp1 += km * zz tmp2 += zz #pj = self.F[j].phases().data()*s #pm = self.F[m].phases().data()*s #Fj = flex.abs(self.F[j].data()) #Fm = flex.abs(self.F[m].data()) #tmp += km * Fj*Fm*flex.cos(pj-pm) d.append(flex.sum(tmp1 * tmp1 + tmp2)) self.d = d
def __init__(O, f_obs, i_obs, i_sig, i_calc=None, f_calc=None, wa=0.1, wb=0): assert [i_calc, f_calc].count(None) == 1 if (i_calc is None): from cctbx.array_family import flex i_calc = flex.norm(f_calc) from cctbx import xray raw = xray.targets_shelxl_wght_ls_kwt_b_dv( f_obs=f_obs, i_obs=i_obs, i_sig=i_sig, ic=i_calc, wa=wa, wb=wb) assert len(raw) == 5 O.scale_factor, \ O.weights, \ O.target, \ O.i_gradients, \ O.i_curvatures = raw if (f_calc is None): O.f_gradients = None O.f_hessians = None else: g = O.i_gradients c = O.i_curvatures O.f_gradients = 2 * g * f_calc a = flex.real(f_calc) b = flex.imag(f_calc) aa = 2 * g + 4 * a * a * c bb = 2 * g + 4 * b * b * c ab = 4 * a * b * c O.f_hessians = flex.vec3_double(aa, bb, ab)
def update_target_and_grads(self, x): self.x = x self.tgo.update(self.x) self.t = self.tgo.target() self.g = self.tgo.gradient() # # Reference implementation in Python # s = 1 #180/math.pi # i_model = flex.double(self.i_obs.data().size(),0) # for n, kn in enumerate(self.x): # for m, km in enumerate(self.x): # tmp = self.F[n].data()*flex.conj(self.F[m].data()) # i_model += kn*km*flex.real(tmp) # #pn = self.F[n].phases().data()*s # #pm = self.F[m].phases().data()*s # #Fn = flex.abs(self.F[n].data()) # #Fm = flex.abs(self.F[m].data()) # #i_model += kn*km*Fn*Fm*flex.cos(pn-pm) # diff = i_model - self.i_obs.data() # #print (flex.min(diff), flex.max(diff)) # t = flex.sum(diff*diff)/4 # # # g = flex.double() # for j in range(len(self.F)): # tmp = flex.double(self.i_obs.data().size(),0) # for m, km in enumerate(self.x): # tmp += km * flex.real( self.F[j].data()*flex.conj(self.F[m].data()) ) # #pj = self.F[j].phases().data()*s # #pm = self.F[m].phases().data()*s # #Fj = flex.abs(self.F[j].data()) # #Fm = flex.abs(self.F[m].data()) # #tmp += km * Fj*Fm*flex.cos(pj-pm) # g.append(flex.sum(diff*tmp)) # self.t = t/self.sum_i_obs # self.g = g/self.sum_i_obs # #print (self.t,t1) # #print (list(self.g)) # #print (list(g1)) # #print () # #assert approx_equal(self.t, t1, 5) # #assert approx_equal(self.g, g1, 1.e-6) # if self.use_curvatures: d = flex.double() for j in range(len(self.F)): tmp1 = flex.double(self.i_obs.data().size(), 0) tmp2 = flex.double(self.i_obs.data().size(), 0) for m, km in enumerate(self.x): zz = flex.real(self.F[j].data() * flex.conj(self.F[m].data())) tmp1 += km * zz tmp2 += zz #pj = self.F[j].phases().data()*s #pm = self.F[m].phases().data()*s #Fj = flex.abs(self.F[j].data()) #Fm = flex.abs(self.F[m].data()) #tmp += km * Fj*Fm*flex.cos(pj-pm) d.append(flex.sum(tmp1 * tmp1 + tmp2)) self.d = d
def __call__(self, xray_structure, u_iso_refinable_params, dp, n_parameters, verbose=0): omptbx.env.num_threads = libtbx.introspection.number_of_processors() result = xray.fast_gradients( unit_cell=xray_structure.unit_cell(), scatterers=xray_structure.scatterers(), scattering_type_registry=xray_structure.scattering_type_registry(), u_base=self.u_base(), wing_cutoff=self.wing_cutoff(), exp_table_one_over_step_size=self.exp_table_one_over_step_size(), tolerance_positive_definite=1.e-5) if (0 or verbose): print("u_base:", result.u_base()) print("u_extra:", result.u_extra()) gradient_map = self.ft_dp(dp, u_extra=result.u_extra()) if (not gradient_map.anomalous_flag()): gradient_map = gradient_map.real_map() else: gradient_map = gradient_map.complex_map() assert not gradient_map.is_padded() if (0 or verbose): print("grid:", gradient_map.focus()) print("ft_dt_map real: %.4g %.4g" % (flex.min(flex.real(gradient_map)), flex.max(flex.real(gradient_map)))) print("ft_dt_map imag: %.4g %.4g" % (flex.min(flex.imag(gradient_map)), flex.max(flex.imag(gradient_map)))) print() result.sampling( scatterers=xray_structure.scatterers(), u_iso_refinable_params=u_iso_refinable_params, scattering_type_registry=xray_structure.scattering_type_registry(), site_symmetry_table=xray_structure.site_symmetry_table(), ft_d_target_d_f_calc=gradient_map, n_parameters=n_parameters, sampled_density_must_be_positive=False) if (0 or verbose): print("max_sampling_box_edges:", result.max_sampling_box_edges()) print("exp_table_size:", result.exp_table_size()) print() return result
def __call__(self, xray_structure, u_iso_refinable_params, dp, n_parameters, verbose=0): omptbx.env.num_threads = libtbx.introspection.number_of_processors() result = xray.fast_gradients( unit_cell=xray_structure.unit_cell(), scatterers=xray_structure.scatterers(), scattering_type_registry=xray_structure.scattering_type_registry(), u_base=self.u_base(), wing_cutoff=self.wing_cutoff(), exp_table_one_over_step_size=self.exp_table_one_over_step_size(), tolerance_positive_definite=1.e-5) if (0 or verbose): print "u_base:", result.u_base() print "u_extra:", result.u_extra() gradient_map = self.ft_dp(dp, u_extra=result.u_extra()) if (not gradient_map.anomalous_flag()): gradient_map = gradient_map.real_map() else: gradient_map = gradient_map.complex_map() assert not gradient_map.is_padded() if (0 or verbose): print "grid:", gradient_map.focus() print "ft_dt_map real: %.4g %.4g" % ( flex.min(flex.real(gradient_map)), flex.max(flex.real(gradient_map))) print "ft_dt_map imag: %.4g %.4g" % ( flex.min(flex.imag(gradient_map)), flex.max(flex.imag(gradient_map))) print result.sampling( scatterers=xray_structure.scatterers(), u_iso_refinable_params=u_iso_refinable_params, scattering_type_registry=xray_structure.scattering_type_registry(), site_symmetry_table=xray_structure.site_symmetry_table(), ft_d_target_d_f_calc=gradient_map, n_parameters=n_parameters, sampled_density_must_be_positive=False) if (0 or verbose): print "max_sampling_box_edges:", result.max_sampling_box_edges() print "exp_table_size:", result.exp_table_size() print return result
def algorithm_4(f_obs, F, max_cycles=100, auto_converge_eps=1.e-7): """ Phased simultaneous search """ fc, f_masks = F[0], F[1:] fc = fc.deep_copy() F = [fc] + F[1:] x_res = None cntr = 0 x_prev = None while True: f_obs_cmpl = f_obs.phase_transfer(phase_source=fc) A = [] b = [] for j, Fj in enumerate(F): A_rows = [] for n, Fn in enumerate(F): Gjn = flex.real(Fj.data() * flex.conj(Fn.data())) A_rows.append(flex.sum(Gjn)) Hj = flex.real(Fj.data() * flex.conj(f_obs_cmpl.data())) b.append(flex.sum(Hj)) A.extend(A_rows) A = matrix.sqr(A) A_1 = A.inverse() b = matrix.col(b) x = A_1 * b if x_res is None: x_res = flex.double(x) else: x_res += flex.double(x) x_ = [x[0]] + list(x_res[1:]) #print "iteration:", cntr, " ".join(["%10.6f"%i for i in x_]) # fc_d = fc.data() for i, f in enumerate(F): if i == 0: continue fc_d += x[i] * f.data() fc = fc.customized_copy(data=fc_d) cntr += 1 if (cntr > max_cycles): break if (x_prev is None): x_prev = x_[:] else: max_diff = flex.max( flex.abs(flex.double(x_prev) - flex.double(x_))) if (max_diff <= auto_converge_eps): break x_prev = x_[:] return x_
def fft(self): if self.params.fft3d.reciprocal_space_grid.d_min is libtbx.Auto: # rough calculation of suitable d_min based on max cell # see also Campbell, J. (1998). J. Appl. Cryst., 31(3), 407-413. # fft_cell should be greater than twice max_cell, so say: # fft_cell = 2.5 * max_cell # then: # fft_cell = n_points * d_min/2 # 2.5 * max_cell = n_points * d_min/2 # a little bit of rearrangement: # d_min = 5 * max_cell/n_points max_cell = self.params.max_cell d_min = (5 * max_cell / self.params.fft3d.reciprocal_space_grid.n_points) d_spacings = 1 / self.reflections['rlp'].norms() self.params.fft3d.reciprocal_space_grid.d_min = max( d_min, min(d_spacings)) logger.info("Setting d_min: %.2f" % self.params.fft3d.reciprocal_space_grid.d_min) n_points = self.params.fft3d.reciprocal_space_grid.n_points self.gridding = fftpack.adjust_gridding_triple( (n_points, n_points, n_points), max_prime=5) n_points = self.gridding[0] self.map_centroids_to_reciprocal_space_grid() self.d_min = self.params.fft3d.reciprocal_space_grid.d_min logger.info("Number of centroids used: %i" % ((self.reciprocal_space_grid > 0).count(True))) #gb_to_bytes = 1073741824 #bytes_to_gb = 1/gb_to_bytes #(128**3)*8*2*bytes_to_gb #0.03125 #(256**3)*8*2*bytes_to_gb #0.25 #(512**3)*8*2*bytes_to_gb #2.0 fft = fftpack.complex_to_complex_3d(self.gridding) grid_complex = flex.complex_double( reals=self.reciprocal_space_grid, imags=flex.double(self.reciprocal_space_grid.size(), 0)) grid_transformed = fft.forward(grid_complex) #self.grid_real = flex.pow2(flex.abs(grid_transformed)) self.grid_real = flex.pow2(flex.real(grid_transformed)) #self.grid_real = flex.pow2(flex.imag(self.grid_transformed)) del grid_transformed if self.params.debug: self.debug_write_ccp4_map(map_data=self.grid_real, file_name="fft3d.map") if self.params.fft3d.peak_search == 'flood_fill': self.find_peaks() elif self.params.fft3d.peak_search == 'clean': self.find_peaks_clean()
def algorithm_3(i_obs, fc, f_masks): """ Unphased two-step search """ F = [fc] + f_masks Gnm = [] cs = {} cntr = 0 nm = [] # Compute and store Gnm for n, Fn in enumerate(F): for m, Fm in enumerate(F): if m < n: continue Gnm.append(flex.real(Fn.data() * flex.conj(Fm.data()))) cs[(n, m)] = cntr cntr += 1 nm.append((n, m)) # Keep track of indices for "upper triangular matrix vs full" for k, v in zip(list(cs.keys()), list(cs.values())): i, j = k if i == j: continue else: cs[(j, i)] = v # Generate and solve system Ax=b, x = A_1*b A = [] b = [] for u, Gnm_u in enumerate(Gnm): for v, Gnm_v in enumerate(Gnm): scale = 2 n, m = nm[v] if n == m: scale = 1 A.append(flex.sum(Gnm_u * Gnm_v) * scale) b.append(flex.sum(Gnm_u * i_obs.data())) A = matrix.sqr(A) A_1 = A.inverse() b = matrix.col(b) x = A_1 * b # Expand Xmn from solution x Xmn = [] for n, Fn in enumerate(F): rows = [] for m, Fm in enumerate(F): x_ = x[cs[(n, m)]] rows.append(x_) Xmn.append(rows) # Do formula (19) lnK = [] for j, Fj in enumerate(F): t1 = flex.sum(flex.log(flex.double(Xmn[j]))) t2 = 0 for n, Fn in enumerate(F): for m, Fm in enumerate(F): t2 += math.log(Xmn[n][m]) t2 = t2 / (2 * len(F)) lnK.append(1 / len(F) * (t1 - t2)) return [math.exp(x) for x in lnK]
def fft(self): #gb_to_bytes = 1073741824 #bytes_to_gb = 1/gb_to_bytes #(128**3)*8*2*bytes_to_gb #0.03125 #(256**3)*8*2*bytes_to_gb #0.25 #(512**3)*8*2*bytes_to_gb #2.0 fft = fftpack.complex_to_complex_3d(self.gridding) grid_complex = flex.complex_double( reals=self.reciprocal_space_grid, imags=flex.double(self.reciprocal_space_grid.size(), 0)) grid_transformed = fft.forward(grid_complex) #self.grid_real = flex.pow2(flex.abs(grid_transformed)) self.grid_real = flex.pow2(flex.real(grid_transformed)) #self.grid_real = flex.pow2(flex.imag(self.grid_transformed)) del grid_transformed
def __init__(O, f_obs, i_obs, i_sig, i_calc=None, f_calc=None, wa=0.1, wb=0): assert [i_calc, f_calc].count(None) == 1 if (i_calc is None): from cctbx.array_family import flex i_calc = flex.norm(f_calc) from cctbx import xray raw = xray.targets_shelxl_wght_ls_kwt_b_dv(f_obs=f_obs, i_obs=i_obs, i_sig=i_sig, ic=i_calc, wa=wa, wb=wb) assert len(raw) == 5 O.scale_factor, \ O.weights, \ O.target, \ O.i_gradients, \ O.i_curvatures = raw if (f_calc is None): O.f_gradients = None O.f_hessians = None else: g = O.i_gradients c = O.i_curvatures O.f_gradients = 2 * g * f_calc a = flex.real(f_calc) b = flex.imag(f_calc) aa = 2 * g + 4 * a * a * c bb = 2 * g + 4 * b * b * c ab = 4 * a * b * c O.f_hessians = flex.vec3_double(aa, bb, ab)
def exercise_under_sampled(space_group_info, anomalous_flag, conjugate_flag, under_sampling, d_min=2., resolution_factor=0.5, max_prime=5, verbose=0): structure_factors = random_structure.xray_structure( space_group_info, elements=("N", "C", "C", "O"), random_f_prime_d_min=1, random_f_double_prime=anomalous_flag, use_u_aniso=True, random_u_iso=True, random_occupancy=True).structure_factors(anomalous_flag=anomalous_flag, d_min=d_min, algorithm="direct") f_calc = structure_factors.f_calc() n_real = maptbx.crystal_gridding(unit_cell=f_calc.unit_cell(), d_min=d_min, resolution_factor=resolution_factor, max_prime=max_prime, mandatory_factors=(under_sampling, ) * 3).n_real() if (not anomalous_flag): rfft = fftpack.real_to_complex_3d(n_real) n_complex = rfft.n_complex() else: cfft = fftpack.complex_to_complex_3d(n_real) n_complex = cfft.n() map = maptbx.structure_factors.to_map(space_group=f_calc.space_group(), anomalous_flag=anomalous_flag, miller_indices=f_calc.indices(), structure_factors=f_calc.data(), n_real=n_real, map_grid=flex.grid(n_complex), conjugate_flag=conjugate_flag) f_calc_p1 = f_calc.expand_to_p1() map_p1 = maptbx.structure_factors.to_map( space_group=f_calc_p1.space_group(), anomalous_flag=anomalous_flag, miller_indices=f_calc_p1.indices(), structure_factors=f_calc_p1.data(), n_real=n_real, map_grid=flex.grid(n_complex), conjugate_flag=conjugate_flag) assert flex.max( flex.abs(map_p1.complex_map() - map.complex_map())) < 1.e-10 if (not anomalous_flag): real_map = rfft.backward(map.complex_map()) assert real_map.all() == rfft.m_real() else: real_map = cfft.backward(map.complex_map()) assert not real_map.is_padded() if (0 or verbose): if (not anomalous_flag): maptbx.statistics(real_map).show_summary() maptbx.statistics(real_map).show_summary() else: maptbx.statistics(flex.real(real_map)).show_summary() maptbx.statistics(flex.imag(real_map)).show_summary() n_real_under_sampled = [n // under_sampling for n in n_real] if (not anomalous_flag): rfft = fftpack.real_to_complex_3d(n_real_under_sampled) n_complex_under_sampled = rfft.n_complex() else: cfft = fftpack.complex_to_complex_3d(n_real_under_sampled) n_complex_under_sampled = cfft.n() under_sampled_map = maptbx.structure_factors.to_map( space_group=f_calc.space_group(), anomalous_flag=anomalous_flag, miller_indices=f_calc.indices(), structure_factors=f_calc.data(), n_real=n_real_under_sampled, map_grid=flex.grid(n_complex_under_sampled), conjugate_flag=conjugate_flag) under_sampled_map_p1 = maptbx.structure_factors.to_map( space_group=f_calc_p1.space_group(), anomalous_flag=anomalous_flag, miller_indices=f_calc_p1.indices(), structure_factors=f_calc_p1.data(), n_real=n_real_under_sampled, map_grid=flex.grid(n_complex_under_sampled), conjugate_flag=conjugate_flag) assert flex.max( flex.abs(under_sampled_map_p1.complex_map() - under_sampled_map.complex_map())) < 1.e-10 if (not anomalous_flag): under_sampled_map_before_fft = under_sampled_map.complex_map( ).deep_copy() under_sampled_real_map = rfft.backward(under_sampled_map.complex_map()) assert under_sampled_real_map.all() == rfft.m_real() else: under_sampled_real_map = cfft.backward(under_sampled_map.complex_map()) assert not under_sampled_real_map.is_padded() if (0 or verbose): if (not anomalous_flag): maptbx.statistics(under_sampled_real_map).show_summary() maptbx.statistics(under_sampled_real_map).show_summary() else: maptbx.statistics(flex.real(under_sampled_real_map)).show_summary() maptbx.statistics(flex.imag(under_sampled_real_map)).show_summary() if (0 or verbose): print(real_map.all(), n_complex) print(under_sampled_real_map.all(), n_complex_under_sampled) if (not anomalous_flag): x_source = real_map y_source = under_sampled_real_map else: x_source = flex.real(real_map) y_source = flex.real(under_sampled_real_map) x = flex.double() n = x_source.focus() for i in range(0, n[0], under_sampling): for j in range(0, n[1], under_sampling): for k in range(0, n[2], under_sampling): x.append(x_source[(i, j, k)]) y = maptbx.copy(y_source, flex.grid(y_source.focus())).as_1d() if (0 or verbose): print("x:", tuple(x)) print("y:", tuple(y)) assert flex.max(flex.abs(x-y)) \ < (flex.max(flex.abs(x))+flex.max(flex.abs(y)))/2*1.e-6 if (under_sampling == 1): x = maptbx.copy(x_source, flex.grid(x_source.focus())).as_1d() c = flex.linear_correlation(x, y) assert c.coefficient() >= 0.9999
def exercise_under_sampled(space_group_info, anomalous_flag, conjugate_flag, under_sampling, d_min=2., resolution_factor=0.5, max_prime=5, verbose=0): structure_factors = random_structure.xray_structure( space_group_info, elements=("N", "C", "C", "O"), random_f_prime_d_min=1, random_f_double_prime=anomalous_flag, use_u_aniso=True, random_u_iso=True, random_occupancy=True ).structure_factors( anomalous_flag=anomalous_flag, d_min=d_min, algorithm="direct") f_calc = structure_factors.f_calc() n_real = maptbx.crystal_gridding( unit_cell=f_calc.unit_cell(), d_min=d_min, resolution_factor=resolution_factor, max_prime=max_prime, mandatory_factors=(under_sampling,)*3).n_real() if (not anomalous_flag): rfft = fftpack.real_to_complex_3d(n_real) n_complex = rfft.n_complex() else: cfft = fftpack.complex_to_complex_3d(n_real) n_complex = cfft.n() map = maptbx.structure_factors.to_map( space_group=f_calc.space_group(), anomalous_flag=anomalous_flag, miller_indices=f_calc.indices(), structure_factors=f_calc.data(), n_real=n_real, map_grid=flex.grid(n_complex), conjugate_flag=conjugate_flag) f_calc_p1 = f_calc.expand_to_p1() map_p1 = maptbx.structure_factors.to_map( space_group=f_calc_p1.space_group(), anomalous_flag=anomalous_flag, miller_indices=f_calc_p1.indices(), structure_factors=f_calc_p1.data(), n_real=n_real, map_grid=flex.grid(n_complex), conjugate_flag=conjugate_flag) assert flex.max(flex.abs(map_p1.complex_map() - map.complex_map())) < 1.e-10 if (not anomalous_flag): real_map = rfft.backward(map.complex_map()) assert real_map.all() == rfft.m_real() else: real_map = cfft.backward(map.complex_map()) assert not real_map.is_padded() if (0 or verbose): if (not anomalous_flag): maptbx.statistics(real_map).show_summary() maptbx.statistics(real_map).show_summary() else: maptbx.statistics(flex.real(real_map)).show_summary() maptbx.statistics(flex.imag(real_map)).show_summary() n_real_under_sampled = [n//under_sampling for n in n_real] if (not anomalous_flag): rfft = fftpack.real_to_complex_3d(n_real_under_sampled) n_complex_under_sampled = rfft.n_complex() else: cfft = fftpack.complex_to_complex_3d(n_real_under_sampled) n_complex_under_sampled = cfft.n() under_sampled_map = maptbx.structure_factors.to_map( space_group=f_calc.space_group(), anomalous_flag=anomalous_flag, miller_indices=f_calc.indices(), structure_factors=f_calc.data(), n_real=n_real_under_sampled, map_grid=flex.grid(n_complex_under_sampled), conjugate_flag=conjugate_flag) under_sampled_map_p1 = maptbx.structure_factors.to_map( space_group=f_calc_p1.space_group(), anomalous_flag=anomalous_flag, miller_indices=f_calc_p1.indices(), structure_factors=f_calc_p1.data(), n_real=n_real_under_sampled, map_grid=flex.grid(n_complex_under_sampled), conjugate_flag=conjugate_flag) assert flex.max(flex.abs(under_sampled_map_p1.complex_map() - under_sampled_map.complex_map())) < 1.e-10 if (not anomalous_flag): under_sampled_map_before_fft = under_sampled_map.complex_map().deep_copy() under_sampled_real_map = rfft.backward(under_sampled_map.complex_map()) assert under_sampled_real_map.all() == rfft.m_real() else: under_sampled_real_map = cfft.backward(under_sampled_map.complex_map()) assert not under_sampled_real_map.is_padded() if (0 or verbose): if (not anomalous_flag): maptbx.statistics(under_sampled_real_map).show_summary() maptbx.statistics(under_sampled_real_map).show_summary() else: maptbx.statistics(flex.real(under_sampled_real_map)).show_summary() maptbx.statistics(flex.imag(under_sampled_real_map)).show_summary() if (0 or verbose): print real_map.all(), n_complex print under_sampled_real_map.all(), n_complex_under_sampled if (not anomalous_flag): x_source = real_map y_source = under_sampled_real_map else: x_source = flex.real(real_map) y_source = flex.real(under_sampled_real_map) x = flex.double() n = x_source.focus() for i in xrange(0, n[0], under_sampling): for j in xrange(0, n[1], under_sampling): for k in xrange(0, n[2], under_sampling): x.append(x_source[(i,j,k)]) y = maptbx.copy(y_source, flex.grid(y_source.focus())).as_1d() if (0 or verbose): print "x:", tuple(x) print "y:", tuple(y) assert flex.max(flex.abs(x-y)) \ < (flex.max(flex.abs(x))+flex.max(flex.abs(y)))/2*1.e-6 if (under_sampling == 1): x = maptbx.copy(x_source, flex.grid(x_source.focus())).as_1d() c = flex.linear_correlation(x, y) assert c.coefficient() >= 0.9999
def add_miller_array(self, array, array_type=None, column_name=None, column_names=None): """ Accepts a miller array, and one of array_type, column_name or column_names. """ assert [array_type, column_name, column_names].count(None) == 2 if array_type is not None: assert array_type in ('calc', 'meas') elif column_name is not None: column_names = [column_name] if array.is_complex_array(): if column_names is None: column_names = [ self.prefix + 'F_' + array_type, self.prefix + 'phase_' + array_type ] else: assert len(column_names) == 2 if (('_A_' in column_names[0] and '_B_' in column_names[1]) or ('.A_' in column_names[0] and '.B_' in column_names[1])): data = [ flex.real(array.data()).as_string(), flex.imag(array.data()).as_string() ] else: data = [ flex.abs(array.data()).as_string(), array.phases(deg=True).data().as_string() ] elif array.is_hendrickson_lattman_array(): if column_names is None: column_names = [ self.prefix + 'HL_%s_iso' % abcd for abcd in 'ABCD' ] else: assert len(column_names) == 4 data = [d.as_string() for d in array.data().as_abcd()] else: if array_type is not None: if array.is_xray_intensity_array(): obs_ext = 'squared_' else: obs_ext = '' column_names = [self.prefix + 'F_' + obs_ext + array_type] if array.sigmas() is not None: column_names.append(self.prefix + 'F_' + obs_ext + 'sigma') if isinstance(array.data(), flex.std_string): data = [array.data()] else: data = [array.data().as_string()] if array.anomalous_flag(): if ((array.sigmas() is not None and len(column_names) == 4) or (array.sigmas() is None and len(column_names) == 2)): data = [] asu, matches = array.match_bijvoet_mates() for anomalous_sign in ("+", "-"): sel = matches.pairs_hemisphere_selection( anomalous_sign) sel.extend( matches.singles_hemisphere_selection( anomalous_sign)) if (anomalous_sign == "+"): indices = asu.indices().select(sel) hemisphere_column_names = column_names[:len( column_names) // 2] else: indices = -asu.indices().select(sel) hemisphere_column_names = column_names[ len(column_names) // 2:] hemisphere_data = asu.data().select(sel) hemisphere_array = miller.array( miller.set(array.crystal_symmetry(), indices), hemisphere_data) if array.sigmas() is not None: hemisphere_array.set_sigmas( asu.sigmas().select(sel)) if self.refln_loop is None: # then this is the first array to be added to the loop, # hack so we don't have both hemispheres of indices self.indices = indices self.add_miller_array( hemisphere_array, column_names=hemisphere_column_names) return if array.sigmas() is not None and len(column_names) == 2: data.append(array.sigmas().as_string()) if not (self.indices.size() == array.indices().size() and self.indices.all_eq(array.indices())): from cctbx.miller import match_indices other_indices = array.indices().deep_copy() match = match_indices(self.indices, other_indices) if match.singles(0).size(): # array is missing some reflections indices that already appear in the loop # therefore pad the data with '?' values other_indices.extend( self.indices.select(match.single_selection(0))) for d in data: d.extend( flex.std_string(['?'] * (other_indices.size() - d.size()))) for d in data: assert d.size() == other_indices.size() match = match_indices(self.indices, other_indices) if match.singles(1).size(): # this array contains some reflections that are not already present in the # cif loop, therefore need to add rows of '?' values single_indices = other_indices.select( match.single_selection(1)) self.indices.extend(single_indices) n_data_columns = len(self.refln_loop.keys()) - 3 for hkl in single_indices: row = list(hkl) + ['?'] * n_data_columns self.refln_loop.add_row(row) match = match_indices(self.indices, other_indices) match = match_indices(self.indices, other_indices) perm = match.permutation() data = [d.select(perm) for d in data] if self.refln_loop is None: self.refln_loop = miller_indices_as_cif_loop(self.indices, prefix=self.prefix) columns = OrderedDict(zip(column_names, data)) for key in columns: assert key not in self.refln_loop self.refln_loop.add_columns(columns)
def exercise(space_group_info, const_gaussian, negative_gaussian, anomalous_flag, allow_mix, use_u_iso, use_u_aniso, d_min=1., resolution_factor=1. / 3, max_prime=5, quality_factor=100, wing_cutoff=1.e-6, exp_table_one_over_step_size=-100, force_complex=False, verbose=0): if (const_gaussian): elements = ["const"] * 8 elif (negative_gaussian): elements = ["H"] * 8 else: elements = ["N", "C", "C", "O", "N", "C", "C", "O"] if (random.random() < 0.5): random_f_prime_scale = 0.6 else: random_f_prime_scale = 0 structure = random_structure.xray_structure( space_group_info, elements=elements, random_f_prime_d_min=1, random_f_prime_scale=random_f_prime_scale, random_f_double_prime=anomalous_flag, use_u_aniso=True, use_u_iso=False, random_u_cart_scale=0.3, random_u_iso=True, random_occupancy=True) random_structure.random_modify_adp_and_adp_flags_2( scatterers=structure.scatterers(), use_u_iso=use_u_iso, use_u_aniso=use_u_aniso, allow_mix=allow_mix, random_u_iso_scale=0.3, random_u_iso_min=0.0) sampled_density_must_be_positive = True if (negative_gaussian): reg = structure.scattering_type_registry( custom_dict={"H": eltbx.xray_scattering.gaussian(-1)}) assert reg.gaussian("H").n_terms() == 0 assert reg.gaussian("H").c() == -1 sampled_density_must_be_positive = False elif (not const_gaussian and random.random() < 0.5): if (random.random() < 0.5): sampled_density_must_be_positive = False assign_custom_gaussians( structure, negative_a=not sampled_density_must_be_positive) f_direct = structure.structure_factors(anomalous_flag=anomalous_flag, d_min=d_min, algorithm="direct").f_calc() crystal_gridding = f_direct.crystal_gridding( resolution_factor=resolution_factor, d_min=d_min, max_prime=max_prime) assert crystal_gridding.symmetry_flags() is None rfft = fftpack.real_to_complex_3d(crystal_gridding.n_real()) u_base = xray.calc_u_base(d_min, resolution_factor, quality_factor) omptbx.env.num_threads = libtbx.introspection.number_of_processors() sampled_density = xray.sampled_model_density( unit_cell=structure.unit_cell(), scatterers=structure.scatterers(), scattering_type_registry=structure.scattering_type_registry(), fft_n_real=rfft.n_real(), fft_m_real=rfft.m_real(), u_base=u_base, wing_cutoff=wing_cutoff, exp_table_one_over_step_size=exp_table_one_over_step_size, force_complex=force_complex, sampled_density_must_be_positive=sampled_density_must_be_positive, tolerance_positive_definite=1.e-5, use_u_base_as_u_extra=False) focus = sampled_density.real_map_unpadded().focus() all = sampled_density.real_map_unpadded().all() last = sampled_density.real_map_unpadded().last() assert approx_equal(focus, last) assert approx_equal(all, last) assert sampled_density.anomalous_flag() == (anomalous_flag or force_complex) if (0 or verbose): print("const_gaussian:", const_gaussian) print("negative_gaussian:", negative_gaussian) print("number of scatterers passed:", \ sampled_density.n_scatterers_passed()) print("number of contributing scatterers:", \ sampled_density.n_contributing_scatterers()) print("number of anomalous scatterers:", \ sampled_density.n_anomalous_scatterers()) print("wing_cutoff:", sampled_density.wing_cutoff()) print("exp_table_one_over_step_size:", \ sampled_density.exp_table_one_over_step_size()) print("exp_table_size:", sampled_density.exp_table_size()) print("max_sampling_box_edges:", sampled_density.max_sampling_box_edges(), end=' ') print("(%.4f, %.4f, %.4f)" % sampled_density.max_sampling_box_edges_frac()) if (not sampled_density.anomalous_flag()): print("map min:", flex.min(sampled_density.real_map())) print("map max:", flex.max(sampled_density.real_map())) else: print("map min:", flex.min(flex.real(sampled_density.complex_map())), end=' ') print(flex.min(flex.imag(sampled_density.complex_map()))) print("map max:", flex.max(flex.real(sampled_density.complex_map())), end=' ') print(flex.max(flex.imag(sampled_density.complex_map()))) if (not sampled_density.anomalous_flag() and negative_gaussian): assert flex.min(sampled_density.real_map()) < 0 assert flex.max(sampled_density.real_map()) == 0 if (not sampled_density.anomalous_flag()): map = sampled_density.real_map() assert map.all() == rfft.m_real() assert map.focus() == rfft.n_real() sf_map = rfft.forward(map) assert sf_map.all() == rfft.n_complex() assert sf_map.focus() == rfft.n_complex() collect_conj = True else: cfft = fftpack.complex_to_complex_3d(rfft.n_real()) map = sampled_density.complex_map() assert map.all() == cfft.n() assert map.focus() == cfft.n() sf_map = cfft.backward(map) assert sf_map.all() == cfft.n() assert sf_map.focus() == cfft.n() collect_conj = False f_fft_data = maptbx.structure_factors.from_map( space_group=f_direct.space_group(), anomalous_flag=sampled_density.anomalous_flag(), miller_indices=f_direct.indices(), complex_map=sf_map, conjugate_flag=collect_conj).data() sampled_density.eliminate_u_extra_and_normalize(f_direct.indices(), f_fft_data) structure_factor_utils.check_correlation("direct/fft_regression", f_direct.indices(), 0, f_direct.data(), f_fft_data, min_corr_ampl=1 * 0.99, max_mean_w_phase_error=1 * 3., verbose=verbose) f_fft = xray.structure_factors.from_scatterers( miller_set=f_direct, grid_resolution_factor=resolution_factor, quality_factor=quality_factor, wing_cutoff=wing_cutoff, exp_table_one_over_step_size=exp_table_one_over_step_size, sampled_density_must_be_positive=sampled_density_must_be_positive, max_prime=max_prime)(xray_structure=structure, miller_set=f_direct, algorithm="fft").f_calc() structure_factor_utils.check_correlation("direct/fft_xray", f_direct.indices(), 0, f_direct.data(), f_fft.data(), min_corr_ampl=1 * 0.99, max_mean_w_phase_error=1 * 3., verbose=verbose)
def add_miller_array(self, array, array_type=None, column_name=None, column_names=None): """ Accepts a miller array, and one of array_type, column_name or column_names. """ assert [array_type, column_name, column_names].count(None) == 2 if array_type is not None: assert array_type in ('calc', 'meas') elif column_name is not None: column_names = [column_name] if array.is_complex_array(): if column_names is None: column_names = [self.prefix+'F_'+array_type, self.prefix+'phase_'+array_type] else: assert len(column_names) == 2 if (('_A_' in column_names[0] and '_B_' in column_names[1]) or ('.A_' in column_names[0] and '.B_' in column_names[1])): data = [flex.real(array.data()).as_string(), flex.imag(array.data()).as_string()] else: data = [flex.abs(array.data()).as_string(), array.phases(deg=True).data().as_string()] elif array.is_hendrickson_lattman_array(): if column_names is None: column_names = [self.prefix+'HL_%s_iso' %abcd for abcd in 'ABCD'] else: assert len(column_names) == 4 data = [d.as_string() for d in array.data().as_abcd()] else: if array_type is not None: if array.is_xray_intensity_array(): obs_ext = 'squared_' else: obs_ext = '' column_names = [self.prefix+'F_'+obs_ext+array_type] if array.sigmas() is not None: column_names.append(self.prefix+'F_'+obs_ext+'sigma') if isinstance(array.data(), flex.std_string): data = [array.data()] else: data = [array.data().as_string()] if array.anomalous_flag(): if ((array.sigmas() is not None and len(column_names) == 4) or (array.sigmas() is None and len(column_names) == 2)): data = [] asu, matches = array.match_bijvoet_mates() for anomalous_sign in ("+", "-"): sel = matches.pairs_hemisphere_selection(anomalous_sign) sel.extend(matches.singles_hemisphere_selection(anomalous_sign)) if (anomalous_sign == "+"): indices = asu.indices().select(sel) hemisphere_column_names = column_names[:len(column_names)//2] else: indices = -asu.indices().select(sel) hemisphere_column_names = column_names[len(column_names)//2:] hemisphere_data = asu.data().select(sel) hemisphere_array = miller.array(miller.set( array.crystal_symmetry(), indices), hemisphere_data) if array.sigmas() is not None: hemisphere_array.set_sigmas(asu.sigmas().select(sel)) if self.refln_loop is None: # then this is the first array to be added to the loop, # hack so we don't have both hemispheres of indices self.indices = indices self.add_miller_array( hemisphere_array, column_names=hemisphere_column_names) return if array.sigmas() is not None and len(column_names) == 2: data.append(array.sigmas().as_string()) if not (self.indices.size() == array.indices().size() and self.indices.all_eq(array.indices())): from cctbx.miller import match_indices other_indices = array.indices().deep_copy() match = match_indices(self.indices, other_indices) if match.singles(0).size(): # array is missing some reflections indices that already appear in the loop # therefore pad the data with '?' values other_indices.extend(self.indices.select(match.single_selection(0))) for d in data: d.extend(flex.std_string(['?']*(other_indices.size() - d.size()))) for d in data: assert d.size() == other_indices.size() match = match_indices(self.indices, other_indices) if match.singles(1).size(): # this array contains some reflections that are not already present in the # cif loop, therefore need to add rows of '?' values single_indices = other_indices.select(match.single_selection(1)) self.indices.extend(single_indices) n_data_columns = len(self.refln_loop.keys()) - 3 for hkl in single_indices: row = list(hkl) + ['?'] * n_data_columns self.refln_loop.add_row(row) match = match_indices(self.indices, other_indices) match = match_indices(self.indices, other_indices) perm = match.permutation() data = [d.select(perm) for d in data] if self.refln_loop is None: self.refln_loop = miller_indices_as_cif_loop(self.indices, prefix=self.prefix) columns = OrderedDict(zip(column_names, data)) for key in columns: assert key not in self.refln_loop self.refln_loop.add_columns(columns)
def exercise(space_group_info, const_gaussian, negative_gaussian, anomalous_flag, allow_mix, use_u_iso, use_u_aniso, d_min=1., resolution_factor=1./3, max_prime=5, quality_factor=100, wing_cutoff=1.e-6, exp_table_one_over_step_size=-100, force_complex=False, verbose=0): if (const_gaussian): elements=["const"]*8 elif (negative_gaussian): elements=["H"]*8 else: elements=["N", "C", "C", "O", "N", "C", "C", "O"] if (random.random() < 0.5): random_f_prime_scale=0.6 else: random_f_prime_scale=0 structure = random_structure.xray_structure( space_group_info, elements=elements, random_f_prime_d_min=1, random_f_prime_scale=random_f_prime_scale, random_f_double_prime=anomalous_flag, use_u_aniso= True, use_u_iso= False, random_u_cart_scale=0.3, random_u_iso=True, random_occupancy=True) random_structure.random_modify_adp_and_adp_flags_2( scatterers = structure.scatterers(), use_u_iso = use_u_iso, use_u_aniso = use_u_aniso, allow_mix = allow_mix, random_u_iso_scale = 0.3, random_u_iso_min = 0.0) sampled_density_must_be_positive = True if (negative_gaussian): reg = structure.scattering_type_registry( custom_dict={"H": eltbx.xray_scattering.gaussian(-1)}) assert reg.gaussian("H").n_terms() == 0 assert reg.gaussian("H").c() == -1 sampled_density_must_be_positive = False elif (not const_gaussian and random.random() < 0.5): if (random.random() < 0.5): sampled_density_must_be_positive = False assign_custom_gaussians( structure, negative_a=not sampled_density_must_be_positive) f_direct = structure.structure_factors( anomalous_flag=anomalous_flag, d_min=d_min, algorithm="direct").f_calc() crystal_gridding = f_direct.crystal_gridding( resolution_factor=resolution_factor, d_min=d_min, max_prime=max_prime) assert crystal_gridding.symmetry_flags() is None rfft = fftpack.real_to_complex_3d(crystal_gridding.n_real()) u_base = xray.calc_u_base(d_min, resolution_factor, quality_factor) omptbx.env.num_threads = libtbx.introspection.number_of_processors() sampled_density = xray.sampled_model_density( unit_cell=structure.unit_cell(), scatterers=structure.scatterers(), scattering_type_registry=structure.scattering_type_registry(), fft_n_real=rfft.n_real(), fft_m_real=rfft.m_real(), u_base=u_base, wing_cutoff=wing_cutoff, exp_table_one_over_step_size=exp_table_one_over_step_size, force_complex=force_complex, sampled_density_must_be_positive=sampled_density_must_be_positive, tolerance_positive_definite=1.e-5, use_u_base_as_u_extra=False) focus = sampled_density.real_map_unpadded().focus() all = sampled_density.real_map_unpadded().all() last = sampled_density.real_map_unpadded().last() assert approx_equal(focus, last) assert approx_equal(all, last) assert sampled_density.anomalous_flag() == (anomalous_flag or force_complex) if (0 or verbose): print "const_gaussian:", const_gaussian print "negative_gaussian:", negative_gaussian print "number of scatterers passed:", \ sampled_density.n_scatterers_passed() print "number of contributing scatterers:", \ sampled_density.n_contributing_scatterers() print "number of anomalous scatterers:", \ sampled_density.n_anomalous_scatterers() print "wing_cutoff:", sampled_density.wing_cutoff() print "exp_table_one_over_step_size:", \ sampled_density.exp_table_one_over_step_size() print "exp_table_size:", sampled_density.exp_table_size() print "max_sampling_box_edges:", sampled_density.max_sampling_box_edges(), print "(%.4f, %.4f, %.4f)" % sampled_density.max_sampling_box_edges_frac() if (not sampled_density.anomalous_flag()): print "map min:", flex.min(sampled_density.real_map()) print "map max:", flex.max(sampled_density.real_map()) else: print "map min:", flex.min(flex.real(sampled_density.complex_map())), print flex.min(flex.imag(sampled_density.complex_map())) print "map max:", flex.max(flex.real(sampled_density.complex_map())), print flex.max(flex.imag(sampled_density.complex_map())) if (not sampled_density.anomalous_flag() and negative_gaussian): assert flex.min(sampled_density.real_map()) < 0 assert flex.max(sampled_density.real_map()) == 0 if (not sampled_density.anomalous_flag()): map = sampled_density.real_map() assert map.all() == rfft.m_real() assert map.focus() == rfft.n_real() sf_map = rfft.forward(map) assert sf_map.all() == rfft.n_complex() assert sf_map.focus() == rfft.n_complex() collect_conj = True else: cfft = fftpack.complex_to_complex_3d(rfft.n_real()) map = sampled_density.complex_map() assert map.all() == cfft.n() assert map.focus() == cfft.n() sf_map = cfft.backward(map) assert sf_map.all() == cfft.n() assert sf_map.focus() == cfft.n() collect_conj = False f_fft_data = maptbx.structure_factors.from_map( space_group=f_direct.space_group(), anomalous_flag=sampled_density.anomalous_flag(), miller_indices=f_direct.indices(), complex_map=sf_map, conjugate_flag=collect_conj).data() sampled_density.eliminate_u_extra_and_normalize( f_direct.indices(), f_fft_data) structure_factor_utils.check_correlation( "direct/fft_regression", f_direct.indices(), 0, f_direct.data(), f_fft_data, min_corr_ampl=1*0.99, max_mean_w_phase_error=1*3., verbose=verbose) f_fft = xray.structure_factors.from_scatterers( miller_set=f_direct, grid_resolution_factor=resolution_factor, quality_factor=quality_factor, wing_cutoff=wing_cutoff, exp_table_one_over_step_size=exp_table_one_over_step_size, sampled_density_must_be_positive=sampled_density_must_be_positive, max_prime=max_prime)( xray_structure=structure, miller_set=f_direct, algorithm="fft").f_calc() structure_factor_utils.check_correlation( "direct/fft_xray", f_direct.indices(), 0, f_direct.data(), f_fft.data(), min_corr_ampl=1*0.99, max_mean_w_phase_error=1*3., verbose=verbose)
def find_peaks_clean(self): import omptbx # doesn't seem to be any benefit to using more than say 8 threads num_threads = min(8, omptbx.omp_get_num_procs(), self.params.nproc) omptbx.omp_set_num_threads(num_threads) d_min = self.params.fft3d.reciprocal_space_grid.d_min rlgrid = 2 / (d_min * self.gridding[0]) frame_number = self.reflections['xyzobs.px.value'].parts()[2] scan_range_min = max( int(math.floor(flex.min(frame_number))), self.imagesets[0].get_array_range()[0]) # XXX what about multiple imagesets? scan_range_max = min( int(math.ceil(flex.max(frame_number))), self.imagesets[0].get_array_range()[1]) # XXX what about multiple imagesets? scan_range = self.params.scan_range if not len(scan_range): scan_range = [[scan_range_min, scan_range_max]] scan = self.imagesets[0].get_scan() # XXX what about multiple imagesets? angle_ranges = [ [scan.get_angle_from_array_index(i, deg=False) for i in range_] for range_ in scan_range] grid = flex.double(flex.grid(self.gridding), 0) sampling_volume_map(grid, flex.vec2_double(angle_ranges), self.imagesets[0].get_beam().get_s0(), self.imagesets[0].get_goniometer().get_rotation_axis(), rlgrid, d_min, self.params.b_iso) fft = fftpack.complex_to_complex_3d(self.gridding) grid_complex = flex.complex_double( reals=grid, imags=flex.double(grid.size(), 0)) grid_transformed = fft.forward(grid_complex) grid_real = flex.pow2(flex.real(grid_transformed)) gamma = 1 peaks = flex.vec3_double() #n_peaks = 200 n_peaks = 100 # XXX how many do we need? dirty_beam = grid_real dirty_map = self.grid_real.deep_copy() import time t0 = time.time() peaks = clean_3d(dirty_beam, dirty_map, n_peaks, gamma=gamma) t1 = time.time() #print "clean_3d took %.2f s" %(t1-t0) reciprocal_lattice_points = self.reflections['rlp'].select( self.reflections_used_for_indexing) peaks = self.optimise_peaks(peaks, reciprocal_lattice_points) peaks_frac = flex.vec3_double() for p in peaks: peaks_frac.append((p[0]/self.gridding[0], p[1]/self.gridding[1], p[2]/self.gridding[2])) #print p, peaks_frac[-1] if self.params.debug: self.debug_write_ccp4_map(grid, "sampling_volume.map") self.debug_write_ccp4_map(grid_real, "sampling_volume_FFT.map") self.debug_write_ccp4_map(dirty_map, "clean.map") self.sites = peaks_frac # we don't really know the "volume"" of the peaks, but this method should # find the peaks in order of their intensity (strongest first) self.volumes = flex.double(range(len(self.sites), 0, -1)) return