def exercise_ls_cycles(self): xs = self.xray_structure.deep_copy_scatterers() connectivity_table = smtbx.utils.connectivity_table(xs) emma_ref = xs.as_emma_model() # shaking must happen before the reparametrisation is constructed, # otherwise the original values will prevail xs.shake_sites_in_place(rms_difference=0.1) reparametrisation = constraints.reparametrisation( structure=xs, constraints=[], connectivity_table=connectivity_table) ls = least_squares.crystallographic_ls( self.fo_sq.as_xray_observations(), reparametrisation, weighting_scheme=least_squares.mainstream_shelx_weighting(a=0), origin_fixing_restraints_type= origin_fixing_restraints.atomic_number_weighting) cycles = normal_eqns_solving.naive_iterations( ls, gradient_threshold=1e-12, step_threshold=1e-7, track_all=True) assert approx_equal(ls.scale_factor(), 1, eps=1e-5), ls.scale_factor() assert approx_equal(ls.objective(), 0), ls.objective() match = emma.model_matches(emma_ref, xs.as_emma_model()).refined_matches[0] assert match.rt.r == matrix.identity(3) for pair in match.pairs: assert approx_equal(match.calculate_shortest_dist(pair), 0, eps=1e-4)
def exercise_ls_cycles(self): xs = self.xray_structure.deep_copy_scatterers() connectivity_table = smtbx.utils.connectivity_table(xs) emma_ref = xs.as_emma_model() # shaking must happen before the reparametrisation is constructed, # otherwise the original values will prevail xs.shake_sites_in_place(rms_difference=0.1) reparametrisation = constraints.reparametrisation( structure=xs, constraints=[], connectivity_table=connectivity_table) ls = least_squares.crystallographic_ls( self.fo_sq.as_xray_observations(), reparametrisation, weighting_scheme=least_squares.unit_weighting(), origin_fixing_restraints_type= origin_fixing_restraints.atomic_number_weighting) cycles = normal_eqns_solving.naive_iterations( ls, n_max_iterations=5, track_all=True) assert approx_equal(ls.scale_factor(), 1, eps=1e-5) assert approx_equal(ls.objective(), 0) # skip next-to-last one to allow for no progress and rounding error assert ( cycles.objective_history[0] >= cycles.objective_history[1] >= cycles.objective_history[3]), numstr(cycles.objective_history) assert approx_equal(cycles.gradient_norm_history[-1], 0, eps=5e-8) match = emma.model_matches(emma_ref, xs.as_emma_model()).refined_matches[0] assert match.rt.r == matrix.identity(3) for pair in match.pairs: assert approx_equal(match.calculate_shortest_dist(pair), 0, eps=1e-4)
def get_substruct_matches(substruct_dict, spacegroups, nsites, ano_rlimits): '''Run EMMA on all pairs of substructure models found for different HA number/resolution combinations for the given space group''' ha_dict = {} for spgr in spacegroups: sbm = [ substruct_dict[(spgr, nsite, rlimit)] for (nsite, rlimit) in product(nsites, ano_rlimits) ] ha_dict[spgr] = [[0] * len(mod.scatterers()) if mod else [] for mod in sbm] for idx1, idx2 in combinations(range(len(sbm)), 2): em1, em2 = sbm[idx1], sbm[idx2] try: emma_matches = emma.model_matches( em1.as_emma_model(), em2.as_emma_model(), tolerance=0.5, break_if_match_with_no_singles=False) best_match = next(iter(emma_matches.refined_matches)) for ha_em1, ha_em2 in best_match.pairs: ha_dict[spgr][idx1][ha_em1] += 1 ha_dict[spgr][idx2][ha_em2] += 1 except AttributeError: continue except StopIteration: continue return ha_dict
def exercise(self, fixed_twin_fraction): # Create a shaken structure xs ready for refinement xs0 = self.structure emma_ref = xs0.as_emma_model() xs = xs0.deep_copy_scatterers() xs.shake_sites_in_place(rms_difference=0.15) xs.shake_adp() for sc in xs.scatterers(): sc.flags.set_use_u_iso(False).set_use_u_aniso(True) sc.flags.set_grad_site(True).set_grad_u_aniso(True) # Setup L.S. problem connectivity_table = smtbx.utils.connectivity_table(xs) shaken_twin_fraction = (self.twin_fraction if fixed_twin_fraction else self.twin_fraction + 0.1 * flex.random_double()) # 2nd domain in __init__ twin_components = (xray.twin_component(twin_law=self.twin_law.r(), value=shaken_twin_fraction, grad=not fixed_twin_fraction), ) reparametrisation = constraints.reparametrisation( structure=xs, constraints=[], connectivity_table=connectivity_table, twin_fractions=twin_components) obs = self.fo_sq.as_xray_observations(twin_components=twin_components) ls = least_squares.crystallographic_ls( obs, reparametrisation, weighting_scheme=least_squares.unit_weighting(), origin_fixing_restraints_type=origin_fixing_restraints. atomic_number_weighting) # Refine till we get back the original structure (so we hope) cycles = normal_eqns_solving.levenberg_marquardt_iterations( ls, gradient_threshold=1e-12, step_threshold=1e-6, track_all=True) # Now let's start to check it all worked assert ls.n_parameters == 63 if fixed_twin_fraction else 64 match = emma.model_matches(emma_ref, xs.as_emma_model()).refined_matches[0] assert match.rt.r == matrix.identity(3) for pair in match.pairs: assert approx_equal(match.calculate_shortest_dist(pair), 0, eps=1e-4), pair if fixed_twin_fraction: assert ls.twin_fractions[0].value == self.twin_fraction else: assert approx_equal(ls.twin_fractions[0].value, self.twin_fraction, eps=1e-2) assert approx_equal(ls.scale_factor(), 1, eps=1e-5) assert approx_equal(ls.objective(), 0)
def exercise(self, fixed_twin_fraction): # Create a shaken structure xs ready for refinement xs0 = self.structure emma_ref = xs0.as_emma_model() xs = xs0.deep_copy_scatterers() xs.shake_sites_in_place(rms_difference=0.15) xs.shake_adp() for sc in xs.scatterers(): sc.flags.set_use_u_iso(False).set_use_u_aniso(True) sc.flags.set_grad_site(True).set_grad_u_aniso(True) # Setup L.S. problem connectivity_table = smtbx.utils.connectivity_table(xs) shaken_twin_fraction = ( self.twin_fraction if fixed_twin_fraction else self.twin_fraction + 0.1*flex.random_double()) # 2nd domain in __init__ twin_components = (xray.twin_component( twin_law=self.twin_law.r(), value=shaken_twin_fraction, grad=not fixed_twin_fraction),) reparametrisation = constraints.reparametrisation( structure=xs, constraints=[], connectivity_table=connectivity_table, twin_fractions=twin_components) obs = self.fo_sq.as_xray_observations(twin_components=twin_components) ls = least_squares.crystallographic_ls( obs, reparametrisation, weighting_scheme=least_squares.unit_weighting(), origin_fixing_restraints_type= origin_fixing_restraints.atomic_number_weighting) # Refine till we get back the original structure (so we hope) cycles = normal_eqns_solving.levenberg_marquardt_iterations( ls, gradient_threshold=1e-12, step_threshold=1e-6, track_all=True) # Now let's start to check it all worked assert ls.n_parameters == 63 if fixed_twin_fraction else 64 match = emma.model_matches(emma_ref, xs.as_emma_model()).refined_matches[0] assert match.rt.r == matrix.identity(3) for pair in match.pairs: assert approx_equal(match.calculate_shortest_dist(pair), 0, eps=1e-4), pair if fixed_twin_fraction: assert ls.twin_fractions[0].value == self.twin_fraction else: assert approx_equal(ls.twin_fractions[0].value, self.twin_fraction, eps=1e-2) assert approx_equal(ls.scale_factor(), 1, eps=1e-5) assert approx_equal(ls.objective(), 0)
def best_superpositions_on_other( self, other_model, tolerance=1.5, models_are_diffraction_index_equivalent=True, break_if_match_with_no_singles=True, f=sys.stdout, specifically_test_inverse=True): # 2013-01-25 tt.Find best match to other_model and return it # 2013-01-19 return list of best ones (can be alternatives) # if you want the superposed model use: # superposed_model2=match.get_transformed_model2( # template=other_model) if not hasattr(self, 'match_dict'): self.match_dict = {} match_list = None else: match_list = self.match_dict.get(other_model, None) if match_list is None: # need to get it from cctbx import euclidean_model_matching as emma test_list = [other_model] match_list = [] if specifically_test_inverse: from copy import deepcopy inv_other_model = other_model.change_hand() inv_other_model._cb_op = deepcopy(other_model._cb_op) test_list.append(inv_other_model) for test_model in test_list: matches = emma.model_matches( model1 = self, model2 = test_model, tolerance = tolerance, models_are_diffraction_index_equivalent = \ models_are_diffraction_index_equivalent, break_if_match_with_no_singles=break_if_match_with_no_singles, ) if (matches.n_matches() > 0): best_number_of_matches = len( matches.refined_matches[0].pairs) for match in matches.refined_matches: n = len(match.pairs) if n > 0 and n >= best_number_of_matches: match_list.append(match) self.match_dict[other_model] = match_list # save it if not match_list: match_list = [None] return match_list
def best_superpositions_on_other(self, other_model, tolerance = 1.5, models_are_diffraction_index_equivalent = True, break_if_match_with_no_singles=True, f=sys.stdout, specifically_test_inverse=True): # 2013-01-25 tt.Find best match to other_model and return it # 2013-01-19 return list of best ones (can be alternatives) # if you want the superposed model use: # superposed_model2=match.get_transformed_model2( # template=other_model) if not hasattr(self,'match_dict'): self.match_dict={} match_list=None else: match_list=self.match_dict.get(other_model,None) if match_list is None: # need to get it from cctbx import euclidean_model_matching as emma test_list=[other_model] match_list=[] if specifically_test_inverse: from copy import deepcopy inv_other_model=other_model.change_hand() inv_other_model._cb_op=deepcopy(other_model._cb_op) test_list.append(inv_other_model) for test_model in test_list: matches = emma.model_matches( model1 = self, model2 = test_model, tolerance = tolerance, models_are_diffraction_index_equivalent = \ models_are_diffraction_index_equivalent, break_if_match_with_no_singles=break_if_match_with_no_singles, ) if (matches.n_matches() > 0): best_number_of_matches=len(matches.refined_matches[0].pairs) for match in matches.refined_matches: n=len(match.pairs) if n > 0 and n >= best_number_of_matches: match_list.append(match) self.match_dict[other_model]=match_list # save it if not match_list: match_list=[None] return match_list
def exercise_one_structure( target_structure, flipping_type, anomalous_flag, d_min, grid_resolution_factor=1. / 2, verbose=False, amplitude_type="F", ): assert amplitude_type in ('F', 'E', 'quasi-E') # Generate its structure factors f_target = miller.build_set( crystal_symmetry=target_structure, anomalous_flag=target_structure.scatterers().count_anomalous() != 0, d_min=d_min).structure_factors_from_scatterers( xray_structure=target_structure, algorithm="direct").f_calc() f_target_in_p1 = f_target.expand_to_p1()\ .as_non_anomalous_array()\ .merge_equivalents().array() f_obs = f_target.as_amplitude_array() # Unleash charge flipping on the amplitudes flipping = flipping_type(delta=None) extra = group_args() if amplitude_type == 'E': extra.normalisations_for = lambda f: f.amplitude_normalisations( target_structure.unit_cell_content(omit=('H', 'D'))) elif amplitude_type == 'quasi-E': extra.normalisations_for = charge_flipping.amplitude_quasi_normalisations solving = charge_flipping.solving_iterator( flipping, f_obs, yield_during_delta_guessing=True, yield_solving_interval=1, **extra.__dict__) s = StringIO() charge_flipping.loop(solving, verbose="highly", out=s) if verbose: print s.getvalue() # check whether a phase transition has occured assert solving.had_phase_transition flipping = solving.flipping_iterator f_result_in_p1 = solving.flipping_iterator.f_calc # Euclidean matching of the peaks from the obtained map # against those of the correct structure (in P1) target_structure = target_structure.select( target_structure.scattering_types() == "H", negate=True) target_structure_in_p1 = target_structure.expand_to_p1() search_parameters = maptbx.peak_search_parameters( interpolate=True, min_distance_sym_equiv=1., max_clusters=int(target_structure_in_p1.scatterers().size() * 1.2)) peak_search_outcome = flipping.rho_map.peak_search(search_parameters) peak_structure = emma.model( target_structure_in_p1.crystal_symmetry().special_position_settings(), positions=[ emma.position('Q%i' % i, x) for i, x in enumerate(peak_search_outcome.all().sites()) ]) refined_matches = emma.model_matches( target_structure_in_p1.as_emma_model(), peak_structure, tolerance=0.5, break_if_match_with_no_singles=False).refined_matches m = refined_matches[0] assert m.rms < 0.2, m.rms # no farther than that assert m.rt.r in (mat.identity(3), mat.inversion(3)) reference_shift = -refined_matches[0].rt.t # Find the translation to bring back the structure to the same space-group # setting as the starting f_obs from correlation map analysis is_allowed = lambda x: f_target.space_group_info().is_allowed_origin_shift( x, tolerance=0.1) first_correct_correlation_peak = None for i, (f_calc, shift, cc_peak_height) in enumerate(solving.f_calc_solutions): if (is_allowed(shift - reference_shift) or is_allowed(shift + reference_shift)): first_correct_correlation_peak = i break else: if verbose == "more": print "++ Incorrect peak: shift=(%.3f, %.3f, %.3f), height=%.2f"\ % (tuple(shift)+(cc_peak_height,)) print " Reference shift=(%.3f, %.3f, %.3f)" % tuple( reference_shift) assert first_correct_correlation_peak is not None if verbose and first_correct_correlation_peak != 0: print "** First correct correlation peak: #%i (%.3f) **"\ % (first_correct_correlation_peak, cc_peak_height) # check Euclidean matching in the original space-group search_parameters = maptbx.peak_search_parameters( interpolate=True, min_distance_sym_equiv=1., max_clusters=int(1.5 * target_structure.scatterers().size())) solution_fft_map = f_calc.fft_map( symmetry_flags=maptbx.use_space_group_symmetry) solution_peaks = solution_fft_map.peak_search(search_parameters, verify_symmetry=False) solution_peak_structure = emma.model( target_structure.crystal_symmetry().special_position_settings(), positions=[ emma.position('Q%i' % i, x) for i, x in enumerate(solution_peaks.all().sites()) ]) refined_matches = emma.model_matches( target_structure.as_emma_model(), solution_peak_structure, break_if_match_with_no_singles=False).refined_matches assert refined_matches m = refined_matches[0] assert not m.singles1, m.show() # all sites match a peak assert m.rms < 0.15, m.rms # no farther than that assert m.rt.r in (mat.identity(3), mat.inversion(3)) # success! if verbose: print "@@ Success @@"
def run(): command_line = (option_parser( usage="usage: cctbx.euclidean_model_matching [OPTIONS] " "reference_structure.pickle structure.pickle", description="").option("--tolerance", type="float", default=3).option( "--match_hydrogens", type='bool', default=True)).process(args=sys.argv[1:]) if len(command_line.args) != 2: command_line.parser.print_help() sys.exit(1) reference_structure = easy_pickle.load(command_line.args[0]) if (type(reference_structure) in (type([]), type(()))): reference_structure = reference_structure[0] structures = easy_pickle.load(command_line.args[1]) if (not type(structures) in (type([]), type(()))): structures = [structures] if not command_line.options.match_hydrogens: reference_structure.select_inplace( ~reference_structure.element_selection('H')) for structure in structures: structure.select_inplace(~structure.element_selection('H')) print "Reference model:" reference_structure.show_summary() print reference_model = reference_structure.as_emma_model() match_list = [] match_histogram = dicts.with_default_value(0) for structure in structures: structure.show_summary() if (hasattr(structure, "info")): print structure.info print sys.stdout.flush() refined_matches = emma.model_matches( reference_model, structure.as_emma_model(), tolerance=command_line.options.tolerance, models_are_diffraction_index_equivalent=False, break_if_match_with_no_singles=True).refined_matches if (len(refined_matches)): refined_matches[0].show() m = len(refined_matches[0].pairs) else: print "No matches" m = 0 match_list.append(match_record(m, structure.scatterers().size())) match_histogram[m] += 1 print sys.stdout.flush() print "match_list:", match_list keys = match_histogram.keys() keys.sort() keys.reverse() print "matches: frequency" sum = 0 for key in keys: v = match_histogram[key] sum += v s = 0 for key in keys: v = match_histogram[key] s += v print " %3d: %3d = %5.1f%%, %5.1f%%" % (key, v, 100. * v / sum, 100. * s / sum) print sys.stdout.flush()
def run_test(space_group_info, n_elements=5, d_min=1.5, grid_resolution_factor=1./3, max_prime=5, verbose=0): structure = random_structure.xray_structure( space_group_info, elements=["Si"]*n_elements, volume_per_atom=200, min_distance=3., general_positions_only=False) miller_set_f_obs = miller.build_set( crystal_symmetry=structure, anomalous_flag=(random.random()>0.5), d_min=d_min) f_obs = miller_set_f_obs.structure_factors_from_scatterers( xray_structure=structure, algorithm="direct").f_calc() structure_factor_utils.check_phase_restrictions(f_obs, verbose=verbose) if (0 or verbose): f_obs.show_summary() if (0 or verbose): f_obs.show_array() fft_map = f_obs.fft_map( resolution_factor=grid_resolution_factor, symmetry_flags=maptbx.use_space_group_symmetry) p = pickle.dumps(fft_map) l = pickle.loads(p) s1 = StringIO() fft_map.statistics().show_summary(f=s1) s2 = StringIO() l.statistics().show_summary(f=s2) assert not show_diff(s2.getvalue(), s1.getvalue()) # if (not f_obs.anomalous_flag()): maptbx_fft_map = maptbx.fft_to_real_map_unpadded( space_group=fft_map.space_group(), n_real=fft_map.n_real(), miller_indices=f_obs.indices(), data=f_obs.data()) fft_map_unpadded = fft_map.real_map_unpadded(in_place=False) assert approx_equal( flex.linear_correlation( fft_map_unpadded.as_1d(), maptbx_fft_map.as_1d()).coefficient(), 1) assert approx_equal( flex.max(flex.abs(maptbx_fft_map - fft_map_unpadded)), 0) # fft_map.apply_sigma_scaling() real_map = maptbx.copy( fft_map.real_map(), flex.grid(fft_map.real_map().focus())) grid_tags = maptbx.grid_tags(real_map.focus()) grid_tags.build( fft_map.space_group_info().type(), fft_map.symmetry_flags()) assert grid_tags.n_grid_misses() == 0 assert grid_tags.verify(real_map) rms = [] for interpolate in (False,True): peak_list = maptbx.peak_list( data=real_map, tags=grid_tags.tag_array(), peak_search_level=1, max_peaks=2*n_elements, interpolate=interpolate) assert peak_list.gridding() == real_map.focus() check_peaks(structure, peak_list.sites(), d_min * grid_resolution_factor) crystal_gridding_tags = fft_map.tags() cluster_analysis = maptbx.peak_cluster_analysis( peak_list=peak_list, special_position_settings=structure, general_positions_only=False, effective_resolution=d_min, min_cross_distance=2, max_clusters=n_elements).all() check_peaks( structure, cluster_analysis.sites(), cluster_analysis.min_cross_distance() + d_min * grid_resolution_factor) structure_from_peaks = xray.structure(structure) for site in cluster_analysis.sites(): structure_from_peaks.add_scatterer( xray.scatterer(label="site", scattering_type="", site=site)) emma_matches = emma.model_matches( structure.as_emma_model(), structure_from_peaks.as_emma_model(), tolerance=d_min*2) rms.append(emma_matches.refined_matches[0].rms) assert len(emma_matches.refined_matches[0].pairs) == n_elements # exercise interpolation vs. summation map_coeffs = f_obs.expand_to_p1() fft_map = f_obs.fft_map( resolution_factor=grid_resolution_factor, symmetry_flags=maptbx.use_space_group_symmetry) fft_map.apply_volume_scaling() real_map = fft_map.real_map_unpadded() sum1 = sum2 = 0 for scatterer in structure.scatterers() : v1 = real_map.eight_point_interpolation(scatterer.site) v2 = real_map.tricubic_interpolation(scatterer.site) v3 = map_coeffs.direct_summation_at_point(scatterer.site) sum1 += abs(v1 - v3.real) sum2 += abs(v2 - v3.real) mean_delta_linear = sum1 / n_elements mean_delta_cubic = sum2 / n_elements assert (mean_delta_cubic < mean_delta_linear) if (0 or verbose): print "emma rms grid, interpolated: %.2f %.2f" % tuple(rms) assert rms[0] >= rms[1] map_1 = fft_map.real_map_unpadded(in_place=False) map_2 = fft_map.real_map_unpadded(in_place=True) assert (map_1.all_eq(map_2))
def exercise_masks(): mt = flex.mersenne_twister(seed=0) xs_ref = structure.from_shelx(file=StringIO(YAKRUY_ins)) mi = xs_ref.crystal_symmetry().build_miller_set(d_min=0.5, anomalous_flag=False) fo = mi.structure_factors_from_scatterers( xs_ref, algorithm="direct").f_calc().as_amplitude_array() k = 0.05 + 10 * mt.random_double() fo = fo.customized_copy(data=fo.data() * k) fo2 = fo.f_as_f_sq() acetonitrile_sel = xs_ref.label_selection('N4', 'C20', 'C21', 'H211', 'H212', 'H213') xs_no_sol = xs_ref.deep_copy_scatterers().select(acetonitrile_sel, negate=True) # check what happens when no voids are found mask = masks.mask(xs_ref, fo2) mask.compute(solvent_radius=1.2, shrink_truncation_radius=1.2, resolution_factor=1 / 2, atom_radii_table={ 'C': 1.70, 'B': 1.63, 'N': 1.55, 'O': 1.52 }) assert mask.structure_factors() is None assert mask.n_voids() == 0 assert mask.n_solvent_grid_points() == 0 assert mask.f_mask() is None assert mask.f_model() is None assert mask.modified_intensities() is None assert mask.f_000 is None s = StringIO() mask.show_summary(log=s) assert not show_diff( s.getvalue(), """\ use_set_completion: False solvent_radius: 1.20 shrink_truncation_radius: 1.20 van der Waals radii: B C H N O 1.63 1.70 1.20 1.55 1.52 Total solvent accessible volume / cell = 0.0 Ang^3 [0.0%] gridding: (30,45,54) """) # and now with some voids fo2_complete = fo2.sort() fo2_missing_1 = fo2.select_indices(flex.miller_index([ (0, 0, 1), ]), negate=True) mt = flex.mersenne_twister(seed=0) fo2_incomplete = fo2.select(mt.random_bool(fo2.size(), 0.95)) for fo2, use_space_group_symmetry in zip( (fo2_complete, fo2_complete, fo2_missing_1, fo2_incomplete), (True, False, True, True)): if fo2 is fo2_complete: use_set_completion = False else: use_set_completion = True mask = masks.mask(xs_no_sol, fo2, use_set_completion=use_set_completion) mask.compute( solvent_radius=1.2, shrink_truncation_radius=1.2, resolution_factor=1 / 3, #atom_radii_table={'C':1.70, 'B':1.63, 'N':1.55, 'O':1.52}, use_space_group_symmetry=use_space_group_symmetry) n_voids = flex.max(mask.mask.data) - 1 f_mask = mask.structure_factors() f_model = mask.f_model() modified_fo = mask.modified_intensities().as_amplitude_array() f_obs_minus_f_model = fo.common_set(f_model).f_obs_minus_f_calc( f_obs_factor=1 / k, f_calc=f_model) diff_map = miller.fft_map(mask.crystal_gridding, f_obs_minus_f_model) diff_map.apply_volume_scaling() stats = diff_map.statistics() assert n_voids == 2 assert approx_equal(n_voids, mask.n_voids()) assert mask.n_solvent_grid_points() == 42148 if fo2 is fo2_complete: # check the difference map has no large peaks/holes assert max(stats.max(), abs(stats.min())) < 0.11 # expected electron count: 44 assert approx_equal(mask.f_000_s, 44, eps=1) assert modified_fo.r1_factor(mask.f_calc.common_set(modified_fo), k) < 0.006 assert fo.common_set(fo2).r1_factor(f_model.common_set(fo2), k) < 0.006 s = StringIO() mask.show_summary(log=s) assert not show_diff( s.getvalue(), """\ use_set_completion: True solvent_radius: 1.20 shrink_truncation_radius: 1.20 van der Waals radii: C H N O 1.77 1.20 1.50 1.45 Total solvent accessible volume / cell = 146.5 Ang^3 [16.3%] Total electron count / cell = 43.2 gridding: (45,72,80) Void #Grid points Vol/A^3 Vol/% Centre of mass (frac) Eigenvectors (frac) 1 21074 73.3 8.1 ( 0.267, 0.461, 0.672) 1 ( 0.982, 0.126, 0.142) 2 (-0.166, 0.206, 0.964) 3 (-0.092, 0.970,-0.223) 2 21074 73.3 8.1 (-0.267, 0.539, 0.328) 1 ( 0.982, 0.126, 0.142) 2 (-0.166, 0.206, 0.964) 3 (-0.092, 0.970,-0.223) Void Vol/Ang^3 #Electrons 1 73.3 21.6 2 73.3 21.6 """) cif_block = mask.as_cif_block() fo2 = fo.f_as_f_sq() # this bit is necessary until we have constraints, as # otherwise the hydrogens just disappear into the ether. xs = xs_no_sol.deep_copy_scatterers() h_selection = xs.element_selection('H') orig_flags = xs.scatterer_flags() flags = orig_flags.deep_copy() for flag, is_h in zip(flags, h_selection): if is_h: flag.set_grads(False) xs.set_scatterer_flags(flags) # first refine with no mask xs = exercise_least_squares(xs, fo2, mask=None) xs.set_scatterer_flags(orig_flags) for i in range(1): # compute improved mask/f_mask mask = masks.mask(xs, fo2) mask.compute(solvent_radius=1.2, shrink_truncation_radius=1.2, atom_radii_table={ 'C': 1.70, 'B': 1.63, 'N': 1.55, 'O': 1.52 }, resolution_factor=1 / 3) mask.structure_factors() xs = exercise_least_squares(xs, fo2, mask) # again exclude hydrogens from tests because of lack of constraints emma_ref = xs_no_sol.select(h_selection, negate=True).as_emma_model() match = emma.model_matches( emma_ref, xs.select(h_selection, negate=True).as_emma_model()).refined_matches[0] assert approx_equal(match.rms, 0, eps=1e-3)
def exercise_one_structure( target_structure, flipping_type, anomalous_flag, d_min, grid_resolution_factor=1.0 / 2, verbose=False, amplitude_type="F", ): assert amplitude_type in ("F", "E", "quasi-E") # Generate its structure factors f_target = ( miller.build_set( crystal_symmetry=target_structure, anomalous_flag=target_structure.scatterers().count_anomalous() != 0, d_min=d_min, ) .structure_factors_from_scatterers(xray_structure=target_structure, algorithm="direct") .f_calc() ) f_target_in_p1 = f_target.expand_to_p1().as_non_anomalous_array().merge_equivalents().array() f_obs = f_target.as_amplitude_array() # Unleash charge flipping on the amplitudes flipping = flipping_type(delta=None) extra = group_args() if amplitude_type == "E": extra.normalisations_for = lambda f: f.amplitude_normalisations( target_structure.unit_cell_content(omit=("H", "D")) ) elif amplitude_type == "quasi-E": extra.normalisations_for = charge_flipping.amplitude_quasi_normalisations solving = charge_flipping.solving_iterator( flipping, f_obs, yield_during_delta_guessing=True, yield_solving_interval=1, **extra.__dict__ ) s = StringIO() charge_flipping.loop(solving, verbose="highly", out=s) if verbose: print s.getvalue() # check whether a phase transition has occured assert solving.had_phase_transition flipping = solving.flipping_iterator f_result_in_p1 = solving.flipping_iterator.f_calc # Euclidean matching of the peaks from the obtained map # against those of the correct structure (in P1) target_structure = target_structure.select(target_structure.scattering_types() == "H", negate=True) target_structure_in_p1 = target_structure.expand_to_p1() search_parameters = maptbx.peak_search_parameters( interpolate=True, min_distance_sym_equiv=1.0, max_clusters=int(target_structure_in_p1.scatterers().size() * 1.2) ) peak_search_outcome = flipping.rho_map.peak_search(search_parameters) peak_structure = emma.model( target_structure_in_p1.crystal_symmetry().special_position_settings(), positions=[emma.position("Q%i" % i, x) for i, x in enumerate(peak_search_outcome.all().sites())], ) refined_matches = emma.model_matches( target_structure_in_p1.as_emma_model(), peak_structure, tolerance=0.5, break_if_match_with_no_singles=False ).refined_matches m = refined_matches[0] assert m.rms < 0.2, m.rms # no farther than that assert m.rt.r in (mat.identity(3), mat.inversion(3)) reference_shift = -refined_matches[0].rt.t # Find the translation to bring back the structure to the same space-group # setting as the starting f_obs from correlation map analysis is_allowed = lambda x: f_target.space_group_info().is_allowed_origin_shift(x, tolerance=0.1) first_correct_correlation_peak = None for i, (f_calc, shift, cc_peak_height) in enumerate(solving.f_calc_solutions): if is_allowed(shift - reference_shift) or is_allowed(shift + reference_shift): first_correct_correlation_peak = i break else: if verbose == "more": print "++ Incorrect peak: shift=(%.3f, %.3f, %.3f), height=%.2f" % (tuple(shift) + (cc_peak_height,)) print " Reference shift=(%.3f, %.3f, %.3f)" % tuple(reference_shift) assert first_correct_correlation_peak is not None if verbose and first_correct_correlation_peak != 0: print "** First correct correlation peak: #%i (%.3f) **" % (first_correct_correlation_peak, cc_peak_height) # check Euclidean matching in the original space-group search_parameters = maptbx.peak_search_parameters( interpolate=True, min_distance_sym_equiv=1.0, max_clusters=int(1.5 * target_structure.scatterers().size()) ) solution_fft_map = f_calc.fft_map(symmetry_flags=maptbx.use_space_group_symmetry) solution_peaks = solution_fft_map.peak_search(search_parameters, verify_symmetry=False) solution_peak_structure = emma.model( target_structure.crystal_symmetry().special_position_settings(), positions=[emma.position("Q%i" % i, x) for i, x in enumerate(solution_peaks.all().sites())], ) refined_matches = emma.model_matches( target_structure.as_emma_model(), solution_peak_structure, break_if_match_with_no_singles=False ).refined_matches assert refined_matches m = refined_matches[0] assert not m.singles1, m.show() # all sites match a peak assert m.rms < 0.15, m.rms # no farther than that assert m.rt.r in (mat.identity(3), mat.inversion(3)) # success! if verbose: print "@@ Success @@"
def run(args, command_name="phenix.emma"): command_line = (option_parser( usage=command_name + " [options]" +" reference_coordinates other_coordinates", description="Example: %s model1.pdb model2.sdb" % command_name) .enable_symmetry_comprehensive() .option(None, "--output_pdb", action="store", type="str", default="", help="Output pdb: second model transformed to best match first model", metavar="STR") .option(None, "--tolerance", action="store", type="float", default=3., help="match tolerance", metavar="FLOAT") .option(None, "--diffraction_index_equivalent", action="store_true", help="Use only if models are diffraction-index equivalent.") ).process(args=args, nargs=2) crystal_symmetry = command_line.symmetry if ( crystal_symmetry.unit_cell() is None or crystal_symmetry.space_group_info() is None): for file_name in command_line.args: crystal_symmetry = crystal_symmetry.join_symmetry( other_symmetry=crystal_symmetry_from_any.extract_from( file_name=file_name), force=False) output_pdb = command_line.options.output_pdb if output_pdb: print "Output pdb:",output_pdb tolerance = command_line.options.tolerance print "Tolerance:", tolerance if (tolerance <= 0.): raise ValueError, "Tolerance must be greater than zero." print diffraction_index_equivalent = \ command_line.options.diffraction_index_equivalent if (diffraction_index_equivalent): print "Models are diffraction index equivalent." print emma_models = [] for file_name in command_line.args: emma_models.append(get_emma_model( file_name=file_name, crystal_symmetry=crystal_symmetry)) emma_models[0].show("Reference model") emma_models[1].show("Other model") for model,label in zip(emma_models, ["reference", "other"]): if (model.unit_cell() is None): raise RuntimeError("Unit cell parameters unknown (%s model)." % label) if (model.space_group_info() is None): raise RuntimeError("Space group unknown (%s model)." % label) model_matches = emma.model_matches( model1=emma_models[0], model2=emma_models[1], tolerance=tolerance, models_are_diffraction_index_equivalent=diffraction_index_equivalent) if (model_matches.n_matches() == 0): print "No matches." print else: max_n_pairs = None first=True for match in model_matches.refined_matches: if (max_n_pairs is None or len(match.pairs) > max_n_pairs*0.2): print "." * 79 print match.show() if first and output_pdb: # 2013-01-25 tt match.get_transformed_model2(output_pdb=output_pdb, scattering_type="SE",f=sys.stdout) first=False if (max_n_pairs is None): max_n_pairs = len(match.pairs)
def run(): command_line = (option_parser( usage="usage: cctbx.euclidean_model_matching [OPTIONS] " "reference_structure.pickle structure.pickle", description="") .option("--tolerance", type="float", default=3) .option("--match_hydrogens", type='bool', default=True) ).process(args=sys.argv[1:]) if len(command_line.args) != 2: command_line.parser.print_help() sys.exit(1) reference_structure = easy_pickle.load(command_line.args[0]) if (type(reference_structure) in (type([]), type(()))): reference_structure = reference_structure[0] structures = easy_pickle.load(command_line.args[1]) if (not type(structures) in (type([]), type(()))): structures = [structures] if not command_line.options.match_hydrogens: reference_structure.select_inplace( ~reference_structure.element_selection('H')) for structure in structures: structure.select_inplace(~structure.element_selection('H')) print "Reference model:" reference_structure.show_summary() print reference_model = reference_structure.as_emma_model() match_list = [] match_histogram = dicts.with_default_value(0) for structure in structures: structure.show_summary() if (hasattr(structure, "info")): print structure.info print sys.stdout.flush() refined_matches = emma.model_matches( reference_model, structure.as_emma_model(), tolerance=command_line.options.tolerance, models_are_diffraction_index_equivalent=False, break_if_match_with_no_singles=True).refined_matches if (len(refined_matches)): refined_matches[0].show() m = len(refined_matches[0].pairs) else: print "No matches" m = 0 match_list.append(match_record(m, structure.scatterers().size())) match_histogram[m] += 1 print sys.stdout.flush() print "match_list:", match_list keys = match_histogram.keys() keys.sort() keys.reverse() print "matches: frequency" sum = 0 for key in keys: v = match_histogram[key] sum += v s = 0 for key in keys: v = match_histogram[key] s += v print " %3d: %3d = %5.1f%%, %5.1f%%" % (key, v, 100.*v/sum, 100.*s/sum) print sys.stdout.flush()
def run_implementation(server_info, inp, status): if (inp.ucparams_2 == ""): inp.ucparams_2 = inp.ucparams_1 if (inp.sgsymbol_2 == ""): inp.sgsymbol_2 = inp.sgsymbol_1 inp.convention_2 = inp.convention_1 tolerance = float(inp.tolerance) print "Tolerance:", tolerance if (tolerance <= 0.): raise ValueError, "Tolerance must be greater than zero." print diffraction_index_equivalent = int(inp.diffraction_index_equivalent) if (diffraction_index_equivalent): print "Models are diffraction index equivalent." print models1 = web_to_models( inp.ucparams_1, inp.sgsymbol_1, inp.convention_1, inp.format_1, inp.coor_type_1, inp.skip_columns_1, inp.coordinates[0]) model1 = models1.get_next() assert model1, "Problems reading reference model." model1.show("Reference model") if (model_is_too_large(model=model1)): return assert not models1.get_next() if (model1.unit_cell() is None): raise RuntimeError("Unit cell parameters unknown (reference model).") if (model1.space_group_info() is None): raise RuntimeError("Space group unknown (reference model).") models2 = web_to_models( inp.ucparams_2, inp.sgsymbol_2, inp.convention_2, inp.format_2, inp.coor_type_2, inp.skip_columns_2, inp.coordinates[1], other_symmetry=model1) while 1: print "#" * 79 print model2 = models2.get_next() if (not model2): break model2.show(model2.label) assert model2.unit_cell() is not None assert model2.space_group_info() is not None if (model_is_too_large(model=model2)): continue sys.stdout.flush() model_matches = emma.model_matches( model1=model1, model2=model2, tolerance=tolerance, models_are_diffraction_index_equivalent=diffraction_index_equivalent) if (model_matches.n_matches() == 0): print "No matches." print else: for match in model_matches.refined_matches: print "." * 79 print match.show()
if len(emma_models) == 2 and os.path.isfile(file_name): try: second_model_as_pdb_inp = iotbx.pdb.input(file_name=file_name) except Exception, e: pass emma_models[0].show("Reference model") emma_models[1].show("Other model") for model, label in zip(emma_models, ["reference", "other"]): if (model.unit_cell() is None): raise RuntimeError("Unit cell parameters unknown (%s model)." % label) if (model.space_group_info() is None): raise RuntimeError("Space group unknown (%s model)." % label) model_matches = emma.model_matches( model1=emma_models[0], model2=emma_models[1], tolerance=tolerance, models_are_diffraction_index_equivalent=diffraction_index_equivalent) if (model_matches.n_matches() == 0): print "No matches." print else: max_n_pairs = None first = True for match in model_matches.refined_matches: if (max_n_pairs is None or len(match.pairs) > max_n_pairs * 0.2): print "." * 79 print match.show() if first and output_pdb: # 2013-01-25 tt if second_model_as_pdb_inp:
def run(args, command_name="phenix.emma"): command_line = (option_parser( usage=command_name + " [options]" + " reference_coordinates other_coordinates", description="Example: %s model1.pdb model2.sdb" % command_name ).enable_symmetry_comprehensive().option( None, "--output_pdb", action="store", type="str", default="", help="Output pdb: second model transformed to best match first model", metavar="STR").option( None, "--tolerance", action="store", type="float", default=3., help="match tolerance", metavar="FLOAT").option( None, "--diffraction_index_equivalent", action="store_true", help="Use only if models are diffraction-index equivalent.") ).process(args=args, nargs=2) crystal_symmetry = command_line.symmetry if (crystal_symmetry.unit_cell() is None or crystal_symmetry.space_group_info() is None): for file_name in command_line.args: crystal_symmetry = crystal_symmetry.join_symmetry( other_symmetry=crystal_symmetry_from_any.extract_from( file_name=file_name), force=False) output_pdb = command_line.options.output_pdb if output_pdb: print("Output pdb:", output_pdb) tolerance = command_line.options.tolerance print("Tolerance:", tolerance) if (tolerance <= 0.): raise ValueError("Tolerance must be greater than zero.") print() diffraction_index_equivalent = \ command_line.options.diffraction_index_equivalent if (diffraction_index_equivalent): print("Models are diffraction index equivalent.") print() second_model_as_pdb_inp = None emma_models = [] for file_name in command_line.args: emma_models.append( get_emma_model(file_name=file_name, crystal_symmetry=crystal_symmetry)) if len(emma_models) == 2 and os.path.isfile(file_name): try: second_model_as_pdb_inp = iotbx.pdb.input(file_name=file_name) except Exception as e: pass emma_models[0].show("Reference model") emma_models[1].show("Other model") for model, label in zip(emma_models, ["reference", "other"]): if (model.unit_cell() is None): raise RuntimeError("Unit cell parameters unknown (%s model)." % label) if (model.space_group_info() is None): raise RuntimeError("Space group unknown (%s model)." % label) model_matches = emma.model_matches( model1=emma_models[0], model2=emma_models[1], tolerance=tolerance, models_are_diffraction_index_equivalent=diffraction_index_equivalent) if (model_matches.n_matches() == 0): print("No matches.") print() else: max_n_pairs = None first = True for match in model_matches.refined_matches: if (max_n_pairs is None or len(match.pairs) > max_n_pairs * 0.2): print("." * 79) print() match.show() if first and output_pdb: # 2013-01-25 tt if second_model_as_pdb_inp: match.get_transformed_model2( output_pdb=output_pdb, template_pdb_inp=second_model_as_pdb_inp, f=sys.stdout) else: print("No output model as input model was not PDB") first = False if (max_n_pairs is None): max_n_pairs = len(match.pairs)
def run_call_back(flags, space_group_info): verbose = flags.Verbose if (flags.StaticModels): model1 = (test_model() .add_random_positions(2, "A") .shuffle_positions() .random_symmetry_mates() .apply_random_eucl_op() ) model2 = (test_model() .add_random_positions(3, "B") .shuffle_positions() .random_symmetry_mates() .apply_random_eucl_op() .shake_positions() .random_hand() ) for i in (0,1): m1 = model1 if (i): m1 = model1.transform_to_reference_setting().reset_cb_op() for j in (0,1): m2 = model2 if (j): m2 = model2.transform_to_reference_setting().reset_cb_op() if (0 or verbose): m1.show("Model1(%d)" % (i,)) m2.show("Model2(%d)" % (j,)) model_matches = emma.model_matches(m1, m2, rms_penalty_per_site=0) analyze_refined_matches(m1, m2, model_matches.refined_matches, verbose) return False model_core = test_model(space_group_info) model1 = (model_core .add_random_positions(2, "A") ) model2 = (model_core .add_random_positions(3, "B") .shuffle_positions() .random_symmetry_mates() .apply_random_eucl_op() .shake_positions() .random_hand() ) if (0 or verbose): model_core.show("Core") model1.show("Model1") model2.show("Model2") model_matches = emma.model_matches(model1, model2, rms_penalty_per_site=0) analyze_refined_matches( model1, model2, model_matches.refined_matches, verbose) assert model_matches.consensus_model().size() >= model1.size()-2 assert model_matches.consensus_model(i_model=2).size() >= model2.size()-3 model1.expand_to_p1() model2.as_xray_structure() for i1,i2,m1,m2 in [(1,2,model1,model2),(2,1,model2,model1)]: m2_t = model_matches.transform_model(i_model=i2) assert m1.unit_cell().is_similar_to(m2_t.unit_cell()) assert m1.space_group() == m2_t.space_group() for pair in model_matches.refined_matches[0].pairs: site1 = m1.positions()[pair[i1-1]].site site2 = m2_t.positions()[pair[i2-1]].site equiv_sites1 = sgtbx.sym_equiv_sites(m1.site_symmetry(site1)) dist_info = sgtbx.min_sym_equiv_distance_info(equiv_sites1, site2) assert dist_info.dist() < model_matches.tolerance + 1.e-6 site2_closest = dist_info.sym_op() * site2 assert approx_equal( m1.unit_cell().distance(site1, site2_closest), dist_info.dist()) if (i1 == 1): singles = model_matches.refined_matches[0].singles2 else: singles = model_matches.refined_matches[0].singles1 for i_site2 in singles: site2 = m2_t.positions()[i_site2].site for i_site1 in xrange(len(model1.positions())): site1 = m1.positions()[i_site1].site equiv_sites1 = sgtbx.sym_equiv_sites(m1.site_symmetry(site1)) dist_info = sgtbx.min_sym_equiv_distance_info(equiv_sites1, site2) if (dist_info.dist() < model_matches.tolerance - 1.e-6): ok = False for pair in model_matches.refined_matches[0].pairs: if (pair[i1-1] == i_site1): ok = True assert ok
def exercise(self): xs0 = self.structure xs = xs0.deep_copy_scatterers() k1, s1, li1, o1, o2 = xs.scatterers() self.shake_point_group_3(k1) self.shake_point_group_3(s1) self.shake_point_group_3(li1) self.shake_point_group_3(o1) o2.site = tuple( [ x*(1 + random.uniform(-self.delta_site, self.delta_site)) for x in o2.site]) o2.u_star = tuple( [ u*(1 + random.uniform(-self.delta_u_star, self.delta_u_star)) for u in o2.u_star]) for sc in xs.scatterers(): sc.flags.set_use_u_iso(False).set_use_u_aniso(True) sc.flags.set_grad_site(True).set_grad_u_aniso(True) connectivity_table = smtbx.utils.connectivity_table(xs) reparametrisation = constraints.reparametrisation( structure=xs, constraints=[], connectivity_table=connectivity_table) ls = least_squares.crystallographic_ls( self.fo_sq.as_xray_observations(), reparametrisation, weighting_scheme=least_squares.unit_weighting(), origin_fixing_restraints_type= origin_fixing_restraints.atomic_number_weighting) cycles = normal_eqns_solving.naive_iterations( ls, gradient_threshold=1e-6, step_threshold=1e-6, track_all=True) ## Test whether refinement brought back the shaked structure to its ## original state match = emma.model_matches(xs0.as_emma_model(), xs.as_emma_model()).refined_matches[0] assert match.rt.r == matrix.identity(3) assert not match.singles1 and not match.singles2 assert match.rms < 1e-6 delta_u_carts= ( xs.scatterers().extract_u_cart(xs.unit_cell()) - xs0.scatterers().extract_u_cart(xs.unit_cell())).norms() assert flex.abs(delta_u_carts) < 1e-6 assert approx_equal(ls.scale_factor(), 1, eps=1e-4) ## Test covariance matrix jac_tr = reparametrisation.jacobian_transpose_matching_grad_fc() cov = ls.covariance_matrix( jacobian_transpose=jac_tr, normalised_by_goof=False)\ .matrix_packed_u_as_symmetric() m, n = cov.accessor().focus() # x,y for point group 3 sites are fixed: no variance or correlation for i in (0, 9, 18, 27,): assert cov.matrix_copy_block(i, 0, 2, n) == 0 # u_star coefficients u13 and u23 for point group 3 sites are fixed # to 0: again no variance or correlation with any other param for i in (7, 16, 25, 34,): assert cov.matrix_copy_block(i, 0, 2, n).as_1d()\ .all_approx_equal(0., 1e-20) # u_star coefficients u11, u22 and u12 for point group 3 sites # are totally correlated, with variances in ratios 1:1:1/2 for i in (3, 12, 21, 30,): assert cov[i, i] != 0 assert approx_equal(cov[i, i], cov[i+1, i+1], eps=1e-15) assert approx_equal(cov[i, i+1]/cov[i, i], 1, eps=1e-12) assert approx_equal(cov[i, i+3]/cov[i, i], 0.5, eps=1e-12)
def run_implementation(server_info, inp, status): if (inp.ucparams_2 == ""): inp.ucparams_2 = inp.ucparams_1 if (inp.sgsymbol_2 == ""): inp.sgsymbol_2 = inp.sgsymbol_1 inp.convention_2 = inp.convention_1 tolerance = float(inp.tolerance) print "Tolerance:", tolerance if (tolerance <= 0.): raise ValueError, "Tolerance must be greater than zero." print diffraction_index_equivalent = int(inp.diffraction_index_equivalent) if (diffraction_index_equivalent): print "Models are diffraction index equivalent." print models1 = web_to_models(inp.ucparams_1, inp.sgsymbol_1, inp.convention_1, inp.format_1, inp.coor_type_1, inp.skip_columns_1, inp.coordinates[0]) model1 = models1.get_next() assert model1, "Problems reading reference model." model1.show("Reference model") if (model_is_too_large(model=model1)): return assert not models1.get_next() if (model1.unit_cell() is None): raise RuntimeError("Unit cell parameters unknown (reference model).") if (model1.space_group_info() is None): raise RuntimeError("Space group unknown (reference model).") models2 = web_to_models(inp.ucparams_2, inp.sgsymbol_2, inp.convention_2, inp.format_2, inp.coor_type_2, inp.skip_columns_2, inp.coordinates[1], other_symmetry=model1) while 1: print "#" * 79 print model2 = models2.get_next() if (not model2): break model2.show(model2.label) assert model2.unit_cell() is not None assert model2.space_group_info() is not None if (model_is_too_large(model=model2)): continue sys.stdout.flush() model_matches = emma.model_matches( model1=model1, model2=model2, tolerance=tolerance, models_are_diffraction_index_equivalent=diffraction_index_equivalent ) if (model_matches.n_matches() == 0): print "No matches." print else: for match in model_matches.refined_matches: print "." * 79 print match.show()
def exercise(self): xs0 = self.structure xs = xs0.deep_copy_scatterers() k1, s1, li1, o1, o2 = xs.scatterers() self.shake_point_group_3(k1) self.shake_point_group_3(s1) self.shake_point_group_3(li1) self.shake_point_group_3(o1) o2.site = tuple( [ x*(1 + random.uniform(-self.delta_site, self.delta_site)) for x in o2.site]) o2.u_star = tuple( [ u*(1 + random.uniform(-self.delta_u_star, self.delta_u_star)) for u in o2.u_star]) for sc in xs.scatterers(): sc.flags.set_use_u_iso(False).set_use_u_aniso(True) sc.flags.set_grad_site(True).set_grad_u_aniso(True) connectivity_table = smtbx.utils.connectivity_table(xs) reparametrisation = constraints.reparametrisation( structure=xs, constraints=[], connectivity_table=connectivity_table) ls = least_squares.crystallographic_ls( self.fo_sq.as_xray_observations(), reparametrisation, weighting_scheme=least_squares.unit_weighting(), origin_fixing_restraints_type= origin_fixing_restraints.atomic_number_weighting) cycles = normal_eqns_solving.levenberg_marquardt_iterations( ls, gradient_threshold=1e-12, step_threshold=1e-7, track_all=True) ## Test whether refinement brought back the shaked structure to its ## original state match = emma.model_matches(xs0.as_emma_model(), xs.as_emma_model()).refined_matches[0] assert match.rt.r == matrix.identity(3) assert not match.singles1 and not match.singles2 assert match.rms < 1e-6 delta_u_carts= ( xs.scatterers().extract_u_cart(xs.unit_cell()) - xs0.scatterers().extract_u_cart(xs.unit_cell())).norms() assert flex.abs(delta_u_carts) < 1e-6 assert approx_equal(ls.scale_factor(), 1, eps=1e-4) ## Test covariance matrix jac_tr = reparametrisation.jacobian_transpose_matching_grad_fc() cov = ls.covariance_matrix( jacobian_transpose=jac_tr, normalised_by_goof=False)\ .matrix_packed_u_as_symmetric() m, n = cov.accessor().focus() # x,y for point group 3 sites are fixed: no variance or correlation for i in (0, 9, 18, 27,): assert cov.matrix_copy_block(i, 0, 2, n) == 0 # u_star coefficients u13 and u23 for point group 3 sites are fixed # to 0: again no variance or correlation with any other param for i in (7, 16, 25, 34,): assert cov.matrix_copy_block(i, 0, 2, n).as_1d()\ .all_approx_equal(0., 1e-20) # u_star coefficients u11, u22 and u12 for point group 3 sites # are totally correlated, with variances in ratios 1:1:1/2 for i in (3, 12, 21, 30,): assert cov[i, i] != 0 assert approx_equal(cov[i, i], cov[i+1, i+1], eps=1e-15) assert approx_equal(cov[i, i+1]/cov[i, i], 1, eps=1e-12) assert approx_equal(cov[i, i+3]/cov[i, i], 0.5, eps=1e-12)
def exercise_masks(): mt = flex.mersenne_twister(seed=0) xs_ref = structure.from_shelx( file=cStringIO.StringIO(YAKRUY_ins)) mi = xs_ref.crystal_symmetry().build_miller_set( d_min=0.5, anomalous_flag=False) fo = mi.structure_factors_from_scatterers( xs_ref, algorithm="direct").f_calc().as_amplitude_array() k = 0.05 + 10 * mt.random_double() fo = fo.customized_copy(data=fo.data()*k) fo2 = fo.f_as_f_sq() acetonitrile_sel = xs_ref.label_selection( 'N4', 'C20', 'C21', 'H211', 'H212', 'H213') xs_no_sol = xs_ref.deep_copy_scatterers().select( acetonitrile_sel, negate=True) # check what happens when no voids are found mask = masks.mask(xs_ref, fo2) mask.compute(solvent_radius=1.2, shrink_truncation_radius=1.2, resolution_factor=1/2, atom_radii_table={'C':1.70, 'B':1.63, 'N':1.55, 'O':1.52}) assert mask.structure_factors() is None assert mask.n_voids() == 0 assert mask.n_solvent_grid_points() == 0 assert mask.f_mask() is None assert mask.f_model() is None assert mask.modified_intensities() is None assert mask.f_000 is None s = cStringIO.StringIO() mask.show_summary(log=s) assert not show_diff(s.getvalue(), """\ use_set_completion: False solvent_radius: 1.20 shrink_truncation_radius: 1.20 van der Waals radii: B C H N O 1.63 1.70 1.20 1.55 1.52 Total solvent accessible volume / cell = 0.0 Ang^3 [0.0%] gridding: (30,45,54) """) # and now with some voids fo2_complete = fo2.sort() fo2_missing_1 = fo2.select_indices(flex.miller_index([(0,0,1), ]), negate=True) mt = flex.mersenne_twister(seed=0) fo2_incomplete = fo2.select(mt.random_bool(fo2.size(), 0.95)) for fo2, use_space_group_symmetry in zip( (fo2_complete, fo2_complete, fo2_missing_1, fo2_incomplete), (True, False, True, True)): if fo2 is fo2_complete: use_set_completion=False else: use_set_completion=True mask = masks.mask(xs_no_sol, fo2, use_set_completion=use_set_completion) mask.compute(solvent_radius=1.2, shrink_truncation_radius=1.2, resolution_factor=1/3, #atom_radii_table={'C':1.70, 'B':1.63, 'N':1.55, 'O':1.52}, use_space_group_symmetry=use_space_group_symmetry) n_voids = flex.max(mask.mask.data) - 1 f_mask = mask.structure_factors() f_model = mask.f_model() modified_fo = mask.modified_intensities().as_amplitude_array() f_obs_minus_f_model = fo.common_set(f_model).f_obs_minus_f_calc(f_obs_factor=1/k, f_calc=f_model) diff_map = miller.fft_map(mask.crystal_gridding, f_obs_minus_f_model) diff_map.apply_volume_scaling() stats = diff_map.statistics() assert n_voids == 2 assert approx_equal(n_voids, mask.n_voids()) assert mask.n_solvent_grid_points() == 42148 if fo2 is fo2_complete: # check the difference map has no large peaks/holes assert max(stats.max(), abs(stats.min())) < 0.11 # expected electron count: 44 assert approx_equal(mask.f_000_s, 44, eps=1) assert modified_fo.r1_factor(mask.f_calc.common_set(modified_fo), k) < 0.006 assert fo.common_set(fo2).r1_factor(f_model.common_set(fo2), k) < 0.006 s = cStringIO.StringIO() mask.show_summary(log=s) assert not show_diff(s.getvalue(), """\ use_set_completion: True solvent_radius: 1.20 shrink_truncation_radius: 1.20 van der Waals radii: C H N O 1.77 1.20 1.50 1.45 Total solvent accessible volume / cell = 146.5 Ang^3 [16.3%] Total electron count / cell = 43.2 gridding: (45,72,80) Void #Grid points Vol/A^3 Vol/% Centre of mass (frac) Eigenvectors (frac) 1 21074 73.3 8.1 ( 0.267, 0.461, 0.672) 1 ( 0.982, 0.126, 0.142) 2 (-0.166, 0.206, 0.964) 3 (-0.092, 0.970,-0.223) 2 21074 73.3 8.1 (-0.267, 0.539, 0.328) 1 ( 0.982, 0.126, 0.142) 2 (-0.166, 0.206, 0.964) 3 (-0.092, 0.970,-0.223) Void Vol/Ang^3 #Electrons 1 73.3 21.6 2 73.3 21.6 """) cif_block = mask.as_cif_block() fo2 = fo.f_as_f_sq() # this bit is necessary until we have constraints, as # otherwise the hydrogens just disappear into the ether. xs = xs_no_sol.deep_copy_scatterers() h_selection = xs.element_selection('H') orig_flags = xs.scatterer_flags() flags = orig_flags.deep_copy() for flag, is_h in zip(flags, h_selection): if is_h: flag.set_grads(False) xs.set_scatterer_flags(flags) # first refine with no mask xs = exercise_least_squares(xs, fo2, mask=None) xs.set_scatterer_flags(orig_flags) for i in range(1): # compute improved mask/f_mask mask = masks.mask(xs, fo2) mask.compute(solvent_radius=1.2, shrink_truncation_radius=1.2, atom_radii_table={'C':1.70, 'B':1.63, 'N':1.55, 'O':1.52}, resolution_factor=1/3) mask.structure_factors() xs = exercise_least_squares(xs, fo2, mask) # again exclude hydrogens from tests because of lack of constraints emma_ref = xs_no_sol.select(h_selection, negate=True).as_emma_model() match = emma.model_matches(emma_ref, xs.select( h_selection, negate=True).as_emma_model()).refined_matches[0] assert approx_equal(match.rms, 0, eps=1e-3)
def run(): import sys reflection_file_name = sys.argv[1] import iotbx.cif miller_arrays = iotbx.cif.reader( file_path=reflection_file_name).as_miller_arrays() for miller_array in miller_arrays: s = str(miller_array.info()) if '_meas' in s: if miller_array.is_xray_intensity_array(): break elif miller_array.is_xray_amplitude_array(): break if not ('_meas' in str(miller_array.info()) and (miller_array.is_xray_amplitude_array() or miller_array.is_xray_intensity_array())): print "Sorry: CIF does not contain an appropriate miller array" return miller_array.show_comprehensive_summary() print if (miller_array.is_xray_intensity_array()): print "Converting intensities to amplitudes." miller_array = miller_array.as_amplitude_array() print miller_array.setup_binner(auto_binning=True) miller_array.binner().show_summary() print all_e_values = miller_array.quasi_normalize_structure_factors().sort( by_value="data") large_e_values = all_e_values.select(all_e_values.data() > 1.2) print "number of large_e_values:", large_e_values.size() print from cctbx import dmtbx triplets = dmtbx.triplet_generator(large_e_values) from cctbx.array_family import flex print "triplets per reflection: min,max,mean: %d, %d, %.2f" % ( flex.min(triplets.n_relations()), flex.max(triplets.n_relations()), flex.mean(triplets.n_relations().as_double())) print "total number of triplets:", flex.sum(triplets.n_relations()) print input_phases = large_e_values \ .random_phases_compatible_with_phase_restrictions() tangent_formula_phases = input_phases.data() for i in xrange(10): tangent_formula_phases = triplets.apply_tangent_formula( amplitudes=large_e_values.data(), phases_rad=tangent_formula_phases, selection_fixed=None, use_fixed_only=False, reuse_results=True) e_map_coeff = large_e_values.phase_transfer( phase_source=tangent_formula_phases) from cctbx import maptbx e_map = e_map_coeff.fft_map( symmetry_flags=maptbx.use_space_group_symmetry) e_map.apply_sigma_scaling() e_map.statistics().show_summary(prefix="e_map ") print peak_search = e_map.peak_search(parameters=maptbx.peak_search_parameters( min_distance_sym_equiv=1.2)) peaks = peak_search.all(max_clusters=10) print "e_map peak list" print " fractional coordinates peak height" for site,height in zip(peaks.sites(), peaks.heights()): print " (%9.6f, %9.6f, %9.6f)" % site, "%10.3f" % height print if (len(sys.argv) > 2): coordinate_file_name = sys.argv[2] xray_structure = iotbx.cif.reader( file_path=coordinate_file_name).build_crystal_structures( data_block_name="I") xray_structure.show_summary().show_scatterers() print f_calc = abs(miller_array.structure_factors_from_scatterers( xray_structure=xray_structure, algorithm="direct").f_calc()) correlation = flex.linear_correlation(f_calc.data(), miller_array.data()) assert correlation.is_well_defined() print "correlation of f_obs and f_calc: %.4f" % correlation.coefficient() print reference_model = xray_structure.as_emma_model() assert reference_model.unit_cell().is_similar_to(e_map.unit_cell()) assert reference_model.space_group() == e_map.space_group() from cctbx import euclidean_model_matching as emma peak_model = emma.model(special_position_settings=reference_model) for i,site in enumerate(peaks.sites()): peak_model.add_position(emma.position(label="peak%02d" % i, site=site)) matches = emma.model_matches( model1=reference_model, model2=peak_model, tolerance=1., models_are_diffraction_index_equivalent=True) for match in matches.refined_matches: match.show()
def run(): import sys reflection_file_name = sys.argv[1] import iotbx.cif miller_arrays = iotbx.cif.reader( file_path=reflection_file_name).as_miller_arrays() for miller_array in miller_arrays: s = str(miller_array.info()) if '_meas' in s: if miller_array.is_xray_intensity_array(): break elif miller_array.is_xray_amplitude_array(): break if not ('_meas' in str(miller_array.info()) and (miller_array.is_xray_amplitude_array() or miller_array.is_xray_intensity_array())): print "Sorry: CIF does not contain an appropriate miller array" return miller_array.show_comprehensive_summary() print if (miller_array.is_xray_intensity_array()): print "Converting intensities to amplitudes." miller_array = miller_array.as_amplitude_array() print miller_array.setup_binner(auto_binning=True) miller_array.binner().show_summary() print all_e_values = miller_array.quasi_normalize_structure_factors().sort( by_value="data") large_e_values = all_e_values.select(all_e_values.data() > 1.2) print "number of large_e_values:", large_e_values.size() print from cctbx import dmtbx triplets = dmtbx.triplet_generator(large_e_values) from cctbx.array_family import flex print "triplets per reflection: min,max,mean: %d, %d, %.2f" % ( flex.min(triplets.n_relations()), flex.max(triplets.n_relations()), flex.mean(triplets.n_relations().as_double())) print "total number of triplets:", flex.sum(triplets.n_relations()) print input_phases = large_e_values \ .random_phases_compatible_with_phase_restrictions() tangent_formula_phases = input_phases.data() for i in xrange(10): tangent_formula_phases = triplets.apply_tangent_formula( amplitudes=large_e_values.data(), phases_rad=tangent_formula_phases, selection_fixed=None, use_fixed_only=False, reuse_results=True) e_map_coeff = large_e_values.phase_transfer( phase_source=tangent_formula_phases) from cctbx import maptbx e_map = e_map_coeff.fft_map(symmetry_flags=maptbx.use_space_group_symmetry) e_map.apply_sigma_scaling() e_map.statistics().show_summary(prefix="e_map ") print peak_search = e_map.peak_search(parameters=maptbx.peak_search_parameters( min_distance_sym_equiv=1.2)) peaks = peak_search.all(max_clusters=10) print "e_map peak list" print " fractional coordinates peak height" for site, height in zip(peaks.sites(), peaks.heights()): print " (%9.6f, %9.6f, %9.6f)" % site, "%10.3f" % height print if (len(sys.argv) > 2): coordinate_file_name = sys.argv[2] xray_structure = iotbx.cif.reader( file_path=coordinate_file_name).build_crystal_structures( data_block_name="I") xray_structure.show_summary().show_scatterers() print f_calc = abs( miller_array.structure_factors_from_scatterers( xray_structure=xray_structure, algorithm="direct").f_calc()) correlation = flex.linear_correlation(f_calc.data(), miller_array.data()) assert correlation.is_well_defined() print "correlation of f_obs and f_calc: %.4f" % correlation.coefficient( ) print reference_model = xray_structure.as_emma_model() assert reference_model.unit_cell().is_similar_to(e_map.unit_cell()) assert reference_model.space_group() == e_map.space_group() from cctbx import euclidean_model_matching as emma peak_model = emma.model(special_position_settings=reference_model) for i, site in enumerate(peaks.sites()): peak_model.add_position( emma.position(label="peak%02d" % i, site=site)) matches = emma.model_matches( model1=reference_model, model2=peak_model, tolerance=1., models_are_diffraction_index_equivalent=True) for match in matches.refined_matches: match.show()
if len(emma_models)==2 and os.path.isfile(file_name): try: second_model_as_pdb_inp=iotbx.pdb.input( file_name=file_name) except Exception,e: pass emma_models[0].show("Reference model") emma_models[1].show("Other model") for model,label in zip(emma_models, ["reference", "other"]): if (model.unit_cell() is None): raise RuntimeError("Unit cell parameters unknown (%s model)." % label) if (model.space_group_info() is None): raise RuntimeError("Space group unknown (%s model)." % label) model_matches = emma.model_matches( model1=emma_models[0], model2=emma_models[1], tolerance=tolerance, models_are_diffraction_index_equivalent=diffraction_index_equivalent) if (model_matches.n_matches() == 0): print "No matches." print else: max_n_pairs = None first=True for match in model_matches.refined_matches: if (max_n_pairs is None or len(match.pairs) > max_n_pairs*0.2): print "." * 79 print match.show() if first and output_pdb: # 2013-01-25 tt if second_model_as_pdb_inp:
def run_test(space_group_info, n_elements=5, d_min=1.5, grid_resolution_factor=1. / 3, max_prime=5, verbose=0): structure = random_structure.xray_structure(space_group_info, elements=["Si"] * n_elements, volume_per_atom=200, min_distance=3., general_positions_only=False) miller_set_f_obs = miller.build_set(crystal_symmetry=structure, anomalous_flag=(random.random() > 0.5), d_min=d_min) f_obs = miller_set_f_obs.structure_factors_from_scatterers( xray_structure=structure, algorithm="direct").f_calc() structure_factor_utils.check_phase_restrictions(f_obs, verbose=verbose) if (0 or verbose): f_obs.show_summary() if (0 or verbose): f_obs.show_array() fft_map = f_obs.fft_map(resolution_factor=grid_resolution_factor, symmetry_flags=maptbx.use_space_group_symmetry) p = pickle.dumps(fft_map) l = pickle.loads(p) s1 = StringIO() fft_map.statistics().show_summary(f=s1) s2 = StringIO() l.statistics().show_summary(f=s2) assert not show_diff(s2.getvalue(), s1.getvalue()) # if (not f_obs.anomalous_flag()): maptbx_fft_map = maptbx.fft_to_real_map_unpadded( space_group=fft_map.space_group(), n_real=fft_map.n_real(), miller_indices=f_obs.indices(), data=f_obs.data()) fft_map_unpadded = fft_map.real_map_unpadded(in_place=False) assert approx_equal( flex.linear_correlation(fft_map_unpadded.as_1d(), maptbx_fft_map.as_1d()).coefficient(), 1) assert approx_equal( flex.max(flex.abs(maptbx_fft_map - fft_map_unpadded)), 0) # fft_map.apply_sigma_scaling() real_map = maptbx.copy(fft_map.real_map(), flex.grid(fft_map.real_map().focus())) grid_tags = maptbx.grid_tags(real_map.focus()) grid_tags.build(fft_map.space_group_info().type(), fft_map.symmetry_flags()) assert grid_tags.n_grid_misses() == 0 assert grid_tags.verify(real_map) rms = [] for interpolate in (False, True): peak_list = maptbx.peak_list(data=real_map, tags=grid_tags.tag_array(), peak_search_level=1, max_peaks=2 * n_elements, interpolate=interpolate) assert peak_list.gridding() == real_map.focus() check_peaks(structure, peak_list.sites(), d_min * grid_resolution_factor) crystal_gridding_tags = fft_map.tags() cluster_analysis = maptbx.peak_cluster_analysis( peak_list=peak_list, special_position_settings=structure, general_positions_only=False, effective_resolution=d_min, min_cross_distance=2, max_clusters=n_elements).all() check_peaks( structure, cluster_analysis.sites(), cluster_analysis.min_cross_distance() + d_min * grid_resolution_factor) structure_from_peaks = xray.structure(structure) for site in cluster_analysis.sites(): structure_from_peaks.add_scatterer( xray.scatterer(label="site", scattering_type="", site=site)) emma_matches = emma.model_matches(structure.as_emma_model(), structure_from_peaks.as_emma_model(), tolerance=d_min * 2) rms.append(emma_matches.refined_matches[0].rms) assert len(emma_matches.refined_matches[0].pairs) == n_elements # exercise interpolation vs. summation map_coeffs = f_obs.expand_to_p1() fft_map = f_obs.fft_map(resolution_factor=grid_resolution_factor, symmetry_flags=maptbx.use_space_group_symmetry) fft_map.apply_volume_scaling() real_map = fft_map.real_map_unpadded() sum1 = sum2 = 0 for scatterer in structure.scatterers(): v1 = real_map.eight_point_interpolation(scatterer.site) v2 = real_map.tricubic_interpolation(scatterer.site) v3 = map_coeffs.direct_summation_at_point(scatterer.site) sum1 += abs(v1 - v3.real) sum2 += abs(v2 - v3.real) mean_delta_linear = sum1 / n_elements mean_delta_cubic = sum2 / n_elements assert (mean_delta_cubic < mean_delta_linear) if (0 or verbose): print("emma rms grid, interpolated: %.2f %.2f" % tuple(rms)) assert rms[0] >= rms[1] map_1 = fft_map.real_map_unpadded(in_place=False) map_2 = fft_map.real_map_unpadded(in_place=True) assert (map_1.all_eq(map_2))
def run(args, command_name="emma_shelxd_lst.py"): command_line = (option_parser( usage=command_name + " [options]" +" reference_coordinates shelxd-lst-file", description="Example: %s model1.pdb sad_fa.lst" % command_name) .enable_symmetry_comprehensive() .option(None, "--tolerance", action="store", type="float", default=.5, help="match tolerance", metavar="FLOAT") .option(None, "--diffraction_index_equivalent", action="store_true", help="Use only if models are diffraction-index equivalent.") ).process(args=args, nargs=2) crystal_symmetry = command_line.symmetry if ( crystal_symmetry.unit_cell() is None or crystal_symmetry.space_group_info() is None): for file_name in command_line.args: crystal_symmetry = crystal_symmetry.join_symmetry( other_symmetry=crystal_symmetry_from_any.extract_from( file_name=file_name), force=False) tolerance = command_line.options.tolerance print "Tolerance:", tolerance if (tolerance <= 0.): raise ValueError, "Tolerance must be greater than zero." print diffraction_index_equivalent = \ command_line.options.diffraction_index_equivalent if (diffraction_index_equivalent): print "Models are diffraction index equivalent." print emma_ref = get_emma_model(file_name=command_line.args[0], crystal_symmetry=crystal_symmetry) emma_ref.show("Reference model") emma_others = get_emma_models_from_lst(command_line.args[1], crystal_symmetry) print "try CCall CCweak nmatch rms order.min order.max" for emma_other, itry, ccall, ccweak in emma_others: model_matches = emma.model_matches(model1=emma_ref, model2=emma_other, tolerance=tolerance, models_are_diffraction_index_equivalent=diffraction_index_equivalent) print itry, ccall, ccweak, if (model_matches.n_matches() == 0): print "0 nan nan nan" else: max_n_pairs = None first=True for match in model_matches.refined_matches: if (max_n_pairs is None or len(match.pairs) > max_n_pairs*0.2): orders = map(lambda x: int(x[1]), match.pairs) print "%3d %.5f %3d %3d" % (len(match.pairs), match.rms, min(orders), max(orders)) #match.show() #first=False break if (max_n_pairs is None): max_n_pairs = len(match.pairs)
def run_call_back(flags, space_group_info): verbose = flags.Verbose if (flags.StaticModels): model1 = (test_model().add_random_positions(2, "A").shuffle_positions( ).random_symmetry_mates().apply_random_eucl_op()) model2 = (test_model().add_random_positions( 3, "B").shuffle_positions().random_symmetry_mates(). apply_random_eucl_op().shake_positions().random_hand()) for i in (0, 1): m1 = model1 if (i): m1 = model1.transform_to_reference_setting().reset_cb_op() for j in (0, 1): m2 = model2 if (j): m2 = model2.transform_to_reference_setting().reset_cb_op() if (0 or verbose): m1.show("Model1(%d)" % (i, )) m2.show("Model2(%d)" % (j, )) model_matches = emma.model_matches(m1, m2, rms_penalty_per_site=0) analyze_refined_matches(m1, m2, model_matches.refined_matches, verbose) return False model_core = test_model(space_group_info) model1 = (model_core.add_random_positions(2, "A")) model2 = (model_core.add_random_positions( 3, "B").shuffle_positions().random_symmetry_mates(). apply_random_eucl_op().shake_positions().random_hand()) if (0 or verbose): model_core.show("Core") model1.show("Model1") model2.show("Model2") model_matches = emma.model_matches(model1, model2, rms_penalty_per_site=0) analyze_refined_matches(model1, model2, model_matches.refined_matches, verbose) assert model_matches.consensus_model().size() >= model1.size() - 2 assert model_matches.consensus_model(i_model=2).size() >= model2.size() - 3 model1.expand_to_p1() model2.as_xray_structure() for i1, i2, m1, m2 in [(1, 2, model1, model2), (2, 1, model2, model1)]: m2_t = model_matches.transform_model(i_model=i2) assert m1.unit_cell().is_similar_to(m2_t.unit_cell()) assert m1.space_group() == m2_t.space_group() for pair in model_matches.refined_matches[0].pairs: site1 = m1.positions()[pair[i1 - 1]].site site2 = m2_t.positions()[pair[i2 - 1]].site equiv_sites1 = sgtbx.sym_equiv_sites(m1.site_symmetry(site1)) dist_info = sgtbx.min_sym_equiv_distance_info(equiv_sites1, site2) assert dist_info.dist() < model_matches.tolerance + 1.e-6 site2_closest = dist_info.sym_op() * site2 assert approx_equal(m1.unit_cell().distance(site1, site2_closest), dist_info.dist()) if (i1 == 1): singles = model_matches.refined_matches[0].singles2 else: singles = model_matches.refined_matches[0].singles1 for i_site2 in singles: site2 = m2_t.positions()[i_site2].site for i_site1 in range(len(model1.positions())): site1 = m1.positions()[i_site1].site equiv_sites1 = sgtbx.sym_equiv_sites(m1.site_symmetry(site1)) dist_info = sgtbx.min_sym_equiv_distance_info( equiv_sites1, site2) if (dist_info.dist() < model_matches.tolerance - 1.e-6): ok = False for pair in model_matches.refined_matches[0].pairs: if (pair[i1 - 1] == i_site1): ok = True assert ok