def benchmark(observations, model, may_parallelise, blas): time = timeit.default_timer ls = least_squares.crystallographic_ls( observations, model, non_linear_ls_engine[blas], may_parallelise, weighting_scheme=least_squares.mainstream_shelx_weighting(a=0)) m = ls.observations.fo_sq.size() n = ls.reparametrisation.n_independents # let's do worth of 5 Gflops at least n_trials = max(int(5e9 / (0.5 * m * n**2)), 1) building = 0 solving = 0 for i in xrange(n_trials): t0 = time() ls.build_up() t1 = time() rls = ls.reduced_problem() neqns = rls.step_equations() neqns.solve() t2 = time() building += t1 - t0 solving += t2 - t1 return (ls.observations.fo_sq.d_min(), len(ls.xray_structure.scatterers()), building / n_trials, solving / n_trials)
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 make_shelx_weighting_scheme(self, a, b, c=0, d=0, e=0, f=1/3): assert f == 1/3, "Non-Wilsonian ShelX weighting not supported" if c == 0 and d == 0 and e == 0: self.weighting_scheme = \ least_squares.mainstream_shelx_weighting(a, b) else: raise NotImplementedError( "ShelX weighting scheme with non-zero parameter c, d or e")
def make_shelx_weighting_scheme(self, a, b, c=0, d=0, e=0, f=1 / 3): assert f == 1 / 3, "Non-Wilsonian ShelX weighting not supported" if c == 0 and d == 0 and e == 0: self.weighting_scheme = \ least_squares.mainstream_shelx_weighting(a, b) else: raise NotImplementedError( "ShelX weighting scheme with non-zero parameter c, d or e")
def exercise_weighting_schemes(): unit_weighting = least_squares.unit_weighting() assert unit_weighting.type() == "unit" assert str(unit_weighting) == "w=1" shelx_weighting = least_squares.mainstream_shelx_weighting(0.1234, 0.5678) assert shelx_weighting.type() == "calc" assert not show_diff( str(shelx_weighting), "w=1/[\s^2^(Fo^2^)+(0.1234P)^2^+0.5678P] where P=(Fo^2^+2Fc^2^)/3")
def exercise_optimise_shelxl_weights(): def calc_goof(fo2, fc, w, k, n_params): fc2 = fc.as_intensity_array() w = w(fo2.data(), fo2.sigmas(), fc2.data(), k) return math.sqrt( flex.sum(w * flex.pow2(fo2.data() - k * fc2.data())) / (fo2.size() - n_params)) xs = smtbx.development.sucrose() k = 0.05 + 10 * flex.random_double() fc = xs.structure_factors(anomalous_flag=False, d_min=0.7).f_calc() fo = fc.as_amplitude_array() fo = fo.customized_copy(data=fo.data() * math.sqrt(k)) fo = fo.customized_copy(sigmas=0.03 * fo.data()) sigmas = fo.sigmas() for i in range(fo.size()): fo.data()[i] += 2 * scitbx.random.variate( scitbx.random.normal_distribution(sigma=sigmas[i]))() \ + 0.5*random.random() fo2 = fo.as_intensity_array() fc2 = fc.as_intensity_array() w = least_squares.mainstream_shelx_weighting(a=0.1) s = calc_goof(fo2, fc, w, k, xs.n_parameters()) w2 = w.optimise_parameters(fo2, fc2, k, xs.n_parameters()) s2 = calc_goof(fo2, fc, w2, k, xs.n_parameters()) # sort data and setup binning by fc/fc_max fc_sq = fc.as_intensity_array() fc_sq_over_fc_sq_max = fc_sq.data() / flex.max(fc_sq.data()) permutation = flex.sort_permutation(fc_sq_over_fc_sq_max) fc_sq_over_fc_sq_max = fc_sq.customized_copy( data=fc_sq_over_fc_sq_max).select(permutation) fc_sq = fc_sq.select(permutation) fo_sq = fo2.select(permutation) n_bins = 10 bin_max = 0 bin_limits = flex.size_t(1, 0) bin_count = flex.size_t() for i in range(n_bins): bin_limits.append(int(math.ceil((i + 1) * fc_sq.size() / n_bins))) bin_count.append(bin_limits[i + 1] - bin_limits[i]) goofs_w = flex.double() goofs_w2 = flex.double() for i_bin in range(n_bins): sel = flex.size_t_range(bin_limits[i_bin], bin_limits[i_bin + 1]) goofs_w2.append( calc_goof(fo_sq.select(sel), fc_sq.select(sel), w2, k, xs.n_parameters())) goofs_w.append( calc_goof(fo_sq.select(sel), fc_sq.select(sel), w, k, xs.n_parameters())) a = flex.mean_and_variance(goofs_w).unweighted_sample_variance() b = flex.mean_and_variance(goofs_w2).unweighted_sample_variance() assert a > b or abs(1 - s) > abs(1 - s2) assert a > b # flat analysis of variance assert abs(1 - s) > abs(1 - s2) # GooF close to 1
def exercise_optimise_shelxl_weights(): def calc_goof(fo2, fc, w, k, n_params): fc2 = fc.as_intensity_array() w = w(fo2.data(), fo2.sigmas(), fc2.data(), k) return math.sqrt(flex.sum( w * flex.pow2(fo2.data() - k*fc2.data()))/(fo2.size() - n_params)) xs = smtbx.development.sucrose() k = 0.05 + 10 * flex.random_double() fc = xs.structure_factors(anomalous_flag=False, d_min=0.7).f_calc() fo = fc.as_amplitude_array() fo = fo.customized_copy(data=fo.data()*math.sqrt(k)) fo = fo.customized_copy(sigmas=0.03*fo.data()) sigmas = fo.sigmas() for i in range(fo.size()): fo.data()[i] += 2 * scitbx.random.variate( scitbx.random.normal_distribution(sigma=sigmas[i]))() \ + 0.5*random.random() fo2 = fo.as_intensity_array() fc2 = fc.as_intensity_array() w = least_squares.mainstream_shelx_weighting(a=0.1) s = calc_goof(fo2, fc, w, k, xs.n_parameters()) w2 = w.optimise_parameters(fo2, fc2, k, xs.n_parameters()) s2 = calc_goof(fo2, fc, w2, k, xs.n_parameters()) # sort data and setup binning by fc/fc_max fc_sq = fc.as_intensity_array() fc_sq_over_fc_sq_max = fc_sq.data()/flex.max(fc_sq.data()) permutation = flex.sort_permutation(fc_sq_over_fc_sq_max) fc_sq_over_fc_sq_max = fc_sq.customized_copy( data=fc_sq_over_fc_sq_max).select(permutation) fc_sq = fc_sq.select(permutation) fo_sq = fo2.select(permutation) n_bins = 10 bin_max = 0 bin_limits = flex.size_t(1, 0) bin_count = flex.size_t() for i in range(n_bins): bin_limits.append(int(math.ceil((i+1) * fc_sq.size()/n_bins))) bin_count.append(bin_limits[i+1] - bin_limits[i]) goofs_w = flex.double() goofs_w2 = flex.double() for i_bin in range(n_bins): sel = flex.size_t_range(bin_limits[i_bin], bin_limits[i_bin+1]) goofs_w2.append(calc_goof(fo_sq.select(sel), fc_sq.select(sel), w2, k, xs.n_parameters())) goofs_w.append(calc_goof(fo_sq.select(sel), fc_sq.select(sel), w, k, xs.n_parameters())) a = flex.mean_and_variance(goofs_w).unweighted_sample_variance() b = flex.mean_and_variance(goofs_w2).unweighted_sample_variance() assert a > b or abs(1-s) > abs(1-s2) assert a > b # flat analysis of variance assert abs(1-s) > abs(1-s2) # GooF close to 1
def check_refinement_stability(self): if not self.shall_refine_thermal_displacements: for sc in self.xray_structure.scatterers(): sc.flags.set_grad_site(True) if sc.flags.use_u_aniso(): sc.flags.set_grad_u_aniso(False) if sc.flags.use_u_iso(): sc.flags.set_grad_u_iso(False) xs = self.xray_structure xs0 = self.reference_xray_structure = xs.deep_copy_scatterers() mi = xs0.build_miller_set(anomalous_flag=False, d_min=0.5) fo_sq = mi.structure_factors_from_scatterers( xs0, algorithm="direct").f_calc().norm() fo_sq = fo_sq.customized_copy(sigmas=flex.double(fo_sq.size(), 1)) xs.shake_sites_in_place(rms_difference=0.1) if self.shall_refine_thermal_displacements: # a spread of 10 for u_iso's would be enormous for our low temperature # test structures if those u_iso's were not constrained xs.shake_adp( spread=10, # absolute aniso_spread=0.2) # relative self.reparametrisation = constraints.reparametrisation( xs, self.constraints, self.connectivity_table, temperature=self.t_celsius) obs = fo_sq.as_xray_observations() ls = least_squares.crystallographic_ls( obs, self.reparametrisation, weighting_scheme=least_squares.mainstream_shelx_weighting()) self.cycles = self.normal_eqns_solving_method(ls) print("%i %s iterations to recover from shaking" % (self.cycles.n_iterations, self.cycles)) if 0: from crys3d.qttbx.xray_structure_viewer import display display(xray_structure=xs) diff = xray.meaningful_site_cart_differences(xs0, xs) assert diff.max_absolute() < self.site_refinement_tolerance,\ self.__class__.__name__ if self.shall_refine_thermal_displacements: delta_u = [] for sc, sc0 in itertools.izip(xs.scatterers(), xs0.scatterers()): if not sc.flags.use_u_aniso() or not sc0.flags.use_u_aniso(): continue delta_u.extend(matrix.col(sc.u_star) - matrix.col(sc0.u_star)) delta_u = flex.double(delta_u) assert flex.max_absolute(delta_u) < self.u_star_refinement_tolerance,\ self.__class__.__name__
def exercise_weighting_schemes(): unit_weighting = least_squares.unit_weighting() assert unit_weighting.type() == "unit" assert str(unit_weighting) == "w=1" shelx_weighting = least_squares.mainstream_shelx_weighting(0.1234, 0.5678) assert shelx_weighting.type() == "calc" assert not show_diff( str(shelx_weighting), "w=1/[\s^2^(Fo^2^)+(0.1234P)^2^+0.5678P] where P=(Fo^2^+2Fc^2^)/3") try: shelx_weighting(fo_sq=1, sigma=1, fc_sq=1, scale_factor=None) except RuntimeError, e: assert 'SMTBX_ASSERT' in str(e)
def check_refinement_stability(self): xs = self.xray_structure xs0 = self.reference_xray_structure = xs.deep_copy_scatterers() # First we construct the Fo array mi = xs0.build_miller_set(anomalous_flag=True, d_min=0.5) fo_sq = mi.structure_factors_from_scatterers( xs0, algorithm="direct").f_calc().norm() fo_sq = fo_sq.customized_copy(sigmas=flex.double(fo_sq.size(), 1)) # Then shake adps and store the shaken adp components self.shake_selection = flex.bool( [sc.element_symbol() in ['C', 'O'] for sc in xs.scatterers()]) xs.shake_adp(selection=self.shake_selection) adp_ref = [] for sc in xs.scatterers(): if sc.flags.use_u_aniso(): adp_ref.extend(sc.u_star) else: adp_ref.append(sc.u_iso) # Then do the refinement self.reparametrisation = constraints.reparametrisation( xs, self.constraints, self.connectivity_table, temperature=self.t_celsius) self.obs = fo_sq.as_xray_observations() ls = least_squares.crystallographic_ls( self.obs, self.reparametrisation, weighting_scheme=least_squares.mainstream_shelx_weighting()) self.cycles = self.normal_eqns_solving_method(ls) print("%i %s iterations to recover from shaking" % (self.cycles.n_iterations, self.cycles)) # Then verify the final ADPs have all changed by the same amount adp_final = [] for sc in xs.scatterers(): if sc.flags.use_u_aniso(): adp_final.extend(sc.u_star) else: adp_final.append(sc.u_iso) adp_ratios = [ x / y for x, y in zip(adp_ref, adp_final) if x > 1e-6 and y > 1e-6 ] assert all( [approx_equal(x, adp_ratios[0], eps=1e-9) for x in adp_ratios[1:]]) #Make sure the ADPs have changed by some non-zero amount assert adp_ratios[0] > 1.01 or adp_ratios[0] < 0.99
def check_refinement_stability(self): if not self.shall_refine_thermal_displacements: for sc in self.xray_structure.scatterers(): sc.flags.set_grad_site(True) if sc.flags.use_u_aniso(): sc.flags.set_grad_u_aniso(False) if sc.flags.use_u_iso(): sc.flags.set_grad_u_iso(False) xs = self.xray_structure xs0 = self.reference_xray_structure = xs.deep_copy_scatterers() mi = xs0.build_miller_set(anomalous_flag=False, d_min=0.5) fo_sq = mi.structure_factors_from_scatterers( xs0, algorithm="direct").f_calc().norm() fo_sq = fo_sq.customized_copy(sigmas=flex.double(fo_sq.size(), 1)) xs.shake_sites_in_place(rms_difference=0.1) if self.shall_refine_thermal_displacements: # a spread of 10 for u_iso's would be enormous for our low temperature # test structures if those u_iso's were not constrained xs.shake_adp(spread=10, # absolute aniso_spread=0.2) # relative self.reparametrisation = constraints.reparametrisation( xs, self.constraints, self.connectivity_table, temperature=self.t_celsius) obs = fo_sq.as_xray_observations() ls = least_squares.crystallographic_ls( obs, self.reparametrisation, weighting_scheme=least_squares.mainstream_shelx_weighting()) self.cycles = self.normal_eqns_solving_method(ls) print ("%i %s iterations to recover from shaking" % (self.cycles.n_iterations, self.cycles)) if 0: from crys3d.qttbx.xray_structure_viewer import display display(xray_structure=xs) diff = xray.meaningful_site_cart_differences(xs0, xs) assert diff.max_absolute() < self.site_refinement_tolerance,\ self.__class__.__name__ if self.shall_refine_thermal_displacements: delta_u = [] for sc, sc0 in itertools.izip(xs.scatterers(), xs0.scatterers()): if not sc.flags.use_u_aniso() or not sc0.flags.use_u_aniso(): continue delta_u.extend(matrix.col(sc.u_star) - matrix.col(sc0.u_star)) delta_u = flex.double(delta_u) assert flex.max_absolute(delta_u) < self.u_star_refinement_tolerance,\ self.__class__.__name__
def check_refinement_stability(self): xs = self.xray_structure xs0 = self.reference_xray_structure = xs.deep_copy_scatterers() mi = xs0.build_miller_set(anomalous_flag=True, d_min=0.5) fo_sq = mi.structure_factors_from_scatterers( xs0, algorithm="direct").f_calc().norm() fo_sq = fo_sq.customized_copy(sigmas=flex.double(fo_sq.size(), 1)) self.shake_selection = flex.bool([ True if sc.element_symbol() == 'O' else False for sc in self.xray_structure.scatterers() ]) xs.shake_fps(selection=self.shake_selection) xs.shake_fdps(selection=self.shake_selection) self.reparametrisation = constraints.reparametrisation( xs, self.constraints, self.connectivity_table, temperature=self.t_celsius) self.obs = fo_sq.as_xray_observations() ls = least_squares.crystallographic_ls( self.obs, self.reparametrisation, weighting_scheme=least_squares.mainstream_shelx_weighting()) self.cycles = self.normal_eqns_solving_method(ls) print("%i %s iterations to recover from shaking" % (self.cycles.n_iterations, self.cycles)) delta_fp = flex.double([ sc.fp - sc0.fp for sc, sc0 in zip(xs.scatterers(), xs0.scatterers()) ]) delta_fdp = flex.double([ sc.fdp - sc0.fdp for sc, sc0 in zip(xs.scatterers(), xs0.scatterers()) ]) assert flex.max_absolute(delta_fp) < self.fp_refinement_tolerance,\ self.__class__.__name__ assert flex.max_absolute(delta_fdp) < self.fdp_refinement_tolerance,\ self.__class__.__name__
def exercise_ls_cycles(self): xs = self.xray_structure.deep_copy_scatterers() xs.shake_adp( ) # it must happen before the reparamtrisation is constructed # because the ADP values are read then and only then. 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.mainstream_shelx_weighting(a=0), origin_fixing_restraints_type=oop.null()) try: cycles = normal_eqns_solving.naive_iterations( ls, gradient_threshold=1e-12, track_all=True) assert approx_equal(ls.scale_factor(), 1, eps=1e-4) assert approx_equal(ls.objective(), 0) assert cycles.gradient_norm_history[-1] < cycles.gradient_threshold for sc0, sc1 in zip(self.xray_structure.scatterers(), xs.scatterers()): assert approx_equal(sc0.u_star, sc1.u_star) except RuntimeError, err: import re m = re.search( r'^cctbx::adptbx::debye_waller_factor_exp: \s* arg_limit \s+ exceeded' '.* arg \s* = \s* ([\d.eE+-]+)', str(err), re.X) assert m is not None, eval print "Warning: refinement of ADP's diverged" print ' argument to debye_waller_factor_exp reached %s' % m.group( 1) print 'Here is the failing structure' xs.show_summary() xs.show_scatterers() raise self.refinement_diverged()
def exercise_ls_cycles(self): xs = self.xray_structure.deep_copy_scatterers() xs.shake_adp() # it must happen before the reparamtrisation is constructed # because the ADP values are read then and only then. 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.mainstream_shelx_weighting(a=0), origin_fixing_restraints_type=oop.null()) try: cycles = normal_eqns_solving.naive_iterations( ls, gradient_threshold=1e-12, track_all=True) assert approx_equal(ls.scale_factor(), 1, eps=1e-4) assert approx_equal(ls.objective(), 0) assert cycles.gradient_norm_history[-1] < cycles.gradient_threshold for sc0, sc1 in zip(self.xray_structure.scatterers(), xs.scatterers()): assert approx_equal(sc0.u_star, sc1.u_star) except RuntimeError, err: import re m = re.search( r'^cctbx::adptbx::debye_waller_factor_exp: \s* arg_limit \s+ exceeded' '.* arg \s* = \s* ([\d.eE+-]+)', str(err), re.X) assert m is not None, eval print "Warning: refinement of ADP's diverged" print ' argument to debye_waller_factor_exp reached %s' % m.group(1) print 'Here is the failing structure' xs.show_summary() xs.show_scatterers() raise self.refinement_diverged()
def exercise_floating_origin_dynamic_weighting(verbose=False): from cctbx import covariance import scitbx.math worst_condition_number_acceptable = 10 # light elements only xs0 = random_structure.xray_structure(elements=['C', 'C', 'C', 'O', 'N'], use_u_aniso=True) msg = "light elements in %s ..." % ( xs0.space_group_info().type().hall_symbol()) if verbose: print(msg, end=' ') fo_sq = xs0.structure_factors(d_min=0.8).f_calc().norm() fo_sq = fo_sq.customized_copy(sigmas=flex.double(fo_sq.size(), 1.)) xs = xs0.deep_copy_scatterers() xs.shake_adp() xs.shake_sites_in_place(rms_difference=0.1) for sc in xs.scatterers(): sc.flags.set_grad_site(True).set_grad_u_aniso(True) ls = least_squares.crystallographic_ls( fo_sq.as_xray_observations(), constraints.reparametrisation( structure=xs, constraints=[], connectivity_table=smtbx.utils.connectivity_table(xs)), weighting_scheme=least_squares.unit_weighting(), origin_fixing_restraints_type= origin_fixing_restraints.atomic_number_weighting) ls.build_up() lambdas = eigensystem.real_symmetric( ls.normal_matrix_packed_u().matrix_packed_u_as_symmetric()).values() # assert the restrained L.S. problem is not too ill-conditionned cond = math.log10(lambdas[0]/lambdas[-1]) if verbose: print("normal matrix condition: %.1f" % cond) assert cond < worst_condition_number_acceptable, msg # one heavy element xs0 = random_structure.xray_structure( space_group_info=sgtbx.space_group_info('hall: P 2yb'), elements=['Zn', 'C', 'C', 'C', 'O', 'N'], use_u_aniso=True) msg = "one heavy element + light elements (synthetic data) in %s ..." % ( xs0.space_group_info().type().hall_symbol()) if verbose: print(msg, end=' ') fo_sq = xs0.structure_factors(d_min=0.8).f_calc().norm() fo_sq = fo_sq.customized_copy(sigmas=flex.double(fo_sq.size(), 1.)) xs = xs0.deep_copy_scatterers() xs.shake_adp() xs.shake_sites_in_place(rms_difference=0.1) for sc in xs.scatterers(): sc.flags.set_grad_site(True).set_grad_u_aniso(True) ls = least_squares.crystallographic_ls( fo_sq.as_xray_observations(), constraints.reparametrisation( structure=xs, constraints=[], connectivity_table=smtbx.utils.connectivity_table(xs)), weighting_scheme=least_squares.mainstream_shelx_weighting(), origin_fixing_restraints_type= origin_fixing_restraints.atomic_number_weighting) ls.build_up() lambdas = eigensystem.real_symmetric( ls.normal_matrix_packed_u().matrix_packed_u_as_symmetric()).values() # assert the restrained L.S. problem is not too ill-conditionned cond = math.log10(lambdas[0]/lambdas[-1]) if verbose: print("normal matrix condition: %.1f" % cond) assert cond < worst_condition_number_acceptable, msg # are esd's for x,y,z coordinates of the same order of magnitude? var_cart = covariance.orthogonalize_covariance_matrix( ls.covariance_matrix(), xs.unit_cell(), xs.parameter_map()) var_site_cart = covariance.extract_covariance_matrix_for_sites( flex.size_t_range(len(xs.scatterers())), var_cart, xs.parameter_map()) site_esds = var_site_cart.matrix_packed_u_diagonal() indicators = flex.double() for i in xrange(0, len(site_esds), 3): stats = scitbx.math.basic_statistics(site_esds[i:i+3]) indicators.append(stats.bias_corrected_standard_deviation/stats.mean) assert indicators.all_lt(2) # especially troublesome structure with one heavy element # (contributed by Jonathan Coome) xs0 = xray.structure( crystal_symmetry=crystal.symmetry( unit_cell=(8.4519, 8.4632, 18.7887, 90, 96.921, 90), space_group_symbol="hall: P 2yb"), scatterers=flex.xray_scatterer([ xray.scatterer( #0 label="ZN1", site=(-0.736683, -0.313978, -0.246902), u=(0.000302, 0.000323, 0.000054, 0.000011, 0.000015, -0.000004)), xray.scatterer( #1 label="N3B", site=(-0.721014, -0.313583, -0.134277), u=(0.000268, 0.000237, 0.000055, -0.000027, 0.000005, 0.000006)), xray.scatterer( #2 label="N3A", site=(-0.733619, -0.290423, -0.357921), u=(0.000229, 0.000313, 0.000053, 0.000022, 0.000018, -0.000018)), xray.scatterer( #3 label="C9B", site=(-1.101537, -0.120157, -0.138063), u=(0.000315, 0.000345, 0.000103, 0.000050, 0.000055, -0.000017)), xray.scatterer( #4 label="N5B", site=(-0.962032, -0.220345, -0.222045), u=(0.000274, 0.000392, 0.000060, -0.000011, -0.000001, -0.000002)), xray.scatterer( #5 label="N1B", site=(-0.498153, -0.402742, -0.208698), u=(0.000252, 0.000306, 0.000063, 0.000000, 0.000007, 0.000018)), xray.scatterer( #6 label="C3B", site=(-0.322492, -0.472610, -0.114594), u=(0.000302, 0.000331, 0.000085, 0.000016, -0.000013, 0.000037)), xray.scatterer( #7 label="C4B", site=(-0.591851, -0.368163, -0.094677), u=(0.000262, 0.000255, 0.000073, -0.000034, 0.000027, -0.000004)), xray.scatterer( #8 label="N4B", site=(-0.969383, -0.204624, -0.150014), u=(0.000279, 0.000259, 0.000070, -0.000009, 0.000039, 0.000000)), xray.scatterer( #9 label="N2B", site=(-0.470538, -0.414572, -0.135526), u=(0.000277, 0.000282, 0.000065, 0.000003, 0.000021, -0.000006)), xray.scatterer( #10 label="C8A", site=(-0.679889, -0.158646, -0.385629), u=(0.000209, 0.000290, 0.000078, 0.000060, 0.000006, 0.000016)), xray.scatterer( #11 label="N5A", site=(-0.649210, -0.075518, -0.263412), u=(0.000307, 0.000335, 0.000057, -0.000002, 0.000016, -0.000012)), xray.scatterer( #12 label="C6B", site=(-0.708620, -0.325965, 0.011657), u=(0.000503, 0.000318, 0.000053, -0.000058, 0.000032, -0.000019)), xray.scatterer( #13 label="C10B", site=(-1.179332, -0.083184, -0.202815), u=(0.000280, 0.000424, 0.000136, 0.000094, 0.000006, 0.000013)), xray.scatterer( #14 label="N1A", site=(-0.838363, -0.532191, -0.293213), u=(0.000312, 0.000323, 0.000060, 0.000018, 0.000011, -0.000008)), xray.scatterer( #15 label="C3A", site=(-0.915414, -0.671031, -0.393826), u=(0.000319, 0.000384, 0.000078, -0.000052, -0.000001, -0.000020)), xray.scatterer( #16 label="C1A", site=(-0.907466, -0.665419, -0.276011), u=(0.000371, 0.000315, 0.000079, 0.000006, 0.000036, 0.000033)), xray.scatterer( #17 label="C1B", site=(-0.365085, -0.452753, -0.231927), u=(0.000321, 0.000253, 0.000087, -0.000024, 0.000047, -0.000034)), xray.scatterer( #18 label="C11A", site=(-0.598622, 0.053343, -0.227354), u=(0.000265, 0.000409, 0.000084, 0.000088, -0.000018, -0.000030)), xray.scatterer( #19 label="C2A", site=(-0.958694, -0.755645, -0.337016), u=(0.000394, 0.000350, 0.000106, -0.000057, 0.000027, -0.000005)), xray.scatterer( #20 label="C4A", site=(-0.784860, -0.407601, -0.402050), u=(0.000238, 0.000296, 0.000064, 0.000002, 0.000011, -0.000016)), xray.scatterer( #21 label="C5A", site=(-0.784185, -0.399716, -0.475491), u=(0.000310, 0.000364, 0.000062, 0.000044, -0.000011, -0.000017)), xray.scatterer( #22 label="N4A", site=(-0.630284, -0.043981, -0.333143), u=(0.000290, 0.000275, 0.000074, 0.000021, 0.000027, 0.000013)), xray.scatterer( #23 label="C10A", site=(-0.545465, 0.166922, -0.272829), u=(0.000369, 0.000253, 0.000117, 0.000015, -0.000002, -0.000008)), xray.scatterer( #24 label="C9A", site=(-0.567548, 0.102272, -0.339923), u=(0.000346, 0.000335, 0.000103, -0.000016, 0.000037, 0.000023)), xray.scatterer( #25 label="C11B", site=(-1.089943, -0.146930, -0.253779), u=(0.000262, 0.000422, 0.000102, -0.000018, -0.000002, 0.000029)), xray.scatterer( #26 label="N2A", site=(-0.843385, -0.537780, -0.366515), u=(0.000273, 0.000309, 0.000055, -0.000012, -0.000005, -0.000018)), xray.scatterer( #27 label="C7A", site=(-0.674021, -0.136086, -0.457790), u=(0.000362, 0.000378, 0.000074, 0.000043, 0.000034, 0.000016)), xray.scatterer( #28 label="C8B", site=(-0.843625, -0.264182, -0.102023), u=(0.000264, 0.000275, 0.000072, -0.000025, 0.000019, -0.000005)), xray.scatterer( #29 label="C6A", site=(-0.726731, -0.261702, -0.502366), u=(0.000339, 0.000472, 0.000064, 0.000062, -0.000003, 0.000028)), xray.scatterer( #30 label="C5B", site=(-0.577197, -0.376753, -0.020800), u=(0.000349, 0.000353, 0.000066, -0.000082, -0.000022, 0.000014)), xray.scatterer( #31 label="C2B", site=(-0.252088, -0.497338, -0.175057), u=(0.000251, 0.000342, 0.000119, 0.000020, 0.000034, -0.000018)), xray.scatterer( #32 label="C7B", site=(-0.843956, -0.268811, -0.028080), u=(0.000344, 0.000377, 0.000078, -0.000029, 0.000059, -0.000007)), xray.scatterer( #33 label="F4B", site=(-0.680814, -0.696808, -0.115056), u=(0.000670, 0.000408, 0.000109, -0.000099, 0.000139, -0.000031)), xray.scatterer( #34 label="F1B", site=(-0.780326, -0.921249, -0.073962), u=(0.000687, 0.000357, 0.000128, -0.000152, -0.000011, 0.000021)), xray.scatterer( #35 label="B1B", site=(-0.795220, -0.758128, -0.075955), u=(0.000413, 0.000418, 0.000075, 0.000054, 0.000045, 0.000023)), xray.scatterer( #36 label="F2B", site=(-0.945140, -0.714626, -0.105820), u=(0.000584, 0.001371, 0.000108, 0.000420, 0.000067, 0.000134)), xray.scatterer( #37 label="F3B", site=(-0.768914, -0.701660, -0.005161), u=(0.000678, 0.000544, 0.000079, -0.000000, 0.000090, -0.000021)), xray.scatterer( #38 label="F1A", site=(-0.109283, -0.252334, -0.429288), u=(0.000427, 0.001704, 0.000125, 0.000407, 0.000041, 0.000035)), xray.scatterer( #39 label="F4A", site=(-0.341552, -0.262864, -0.502023), u=(0.000640, 0.000557, 0.000081, -0.000074, 0.000042, -0.000052)), xray.scatterer( #40 label="F3A", site=(-0.324533, -0.142292, -0.393215), u=(0.000471, 0.001203, 0.000134, 0.000333, -0.000057, -0.000220)), xray.scatterer( #41 label="F2A", site=(-0.312838, -0.405405, -0.400231), u=(0.002822, 0.000831, 0.000092, -0.000648, 0.000115, 0.000027)), xray.scatterer( #42 label="B1A", site=(-0.271589, -0.268874, -0.430724), u=(0.000643, 0.000443, 0.000079, 0.000040, 0.000052, -0.000034)), xray.scatterer( #43 label="H5B", site=(-0.475808, -0.413802, 0.004402), u=0.005270), xray.scatterer( #44 label="H6B", site=(-0.699519, -0.326233, 0.062781), u=0.019940), xray.scatterer( #45 label="H3B", site=(-0.283410, -0.484757, -0.063922), u=0.029990), xray.scatterer( #46 label="H1B", site=(-0.357103, -0.451819, -0.284911), u=0.031070), xray.scatterer( #47 label="H10A", site=(-0.495517, 0.268296, -0.256187), u=0.027610), xray.scatterer( #48 label="H2B", site=(-0.147129, -0.535141, -0.174699), u=0.017930), xray.scatterer( #49 label="H7A", site=(-0.643658, -0.031387, -0.475357), u=0.020200), xray.scatterer( #50 label="H1A", site=(-0.912757, -0.691043, -0.227554), u=0.033320), xray.scatterer( #51 label="H7B", site=(-0.933670, -0.241189, -0.010263), u=0.021310), xray.scatterer( #52 label="H11B", site=(-1.107736, -0.155470, -0.311996), u=0.041500), xray.scatterer( #53 label="H9A", site=(-0.539908, 0.139753, -0.382281), u=0.007130), xray.scatterer( #54 label="H10B", site=(-1.265944, -0.029610, -0.212398), u=0.030910), xray.scatterer( #55 label="H3A", site=(-0.934728, -0.691149, -0.450551), u=0.038950), xray.scatterer( #56 label="H5A", site=(-0.833654, -0.487479, -0.508239), u=0.031150), xray.scatterer( #57 label="H6A", site=(-0.742871, -0.242269, -0.558157), u=0.050490), xray.scatterer( #58 label="H9B", site=(-1.120150, -0.093752, -0.090706), u=0.039310), xray.scatterer( #59 label="H11A", site=(-0.593074, 0.054973, -0.180370), u=0.055810), xray.scatterer( #60 label="H2A", site=(-0.999576, -0.842158, -0.340837), u=0.057030) ])) fo_sq = xs0.structure_factors(d_min=0.8).f_calc().norm() fo_sq = fo_sq.customized_copy(sigmas=flex.double(fo_sq.size(), 1.)) for hydrogen_flag in (True, False): xs = xs0.deep_copy_scatterers() if not hydrogen_flag: xs.select_inplace(~xs.element_selection('H')) xs.shake_adp() xs.shake_sites_in_place(rms_difference=0.1) for sc in xs.scatterers(): sc.flags.set_grad_site(True).set_grad_u_aniso(False) ls = least_squares.crystallographic_ls( fo_sq.as_xray_observations(), constraints.reparametrisation( structure=xs, constraints=[], connectivity_table=smtbx.utils.connectivity_table(xs)), weighting_scheme=least_squares.unit_weighting(), origin_fixing_restraints_type= origin_fixing_restraints.atomic_number_weighting) ls.build_up() lambdas = eigensystem.real_symmetric( ls.normal_matrix_packed_u().matrix_packed_u_as_symmetric()).values() # assert the restrained L.S. problem is not too ill-conditionned cond = math.log10(lambdas[0]/lambdas[-1]) msg = ("one heavy element + light elements (real data) %s Hydrogens: %.1f" % (['without', 'with'][hydrogen_flag], cond)) if verbose: print(msg) assert cond < worst_condition_number_acceptable, msg # are esd's for x,y,z coordinates of the same order of magnitude? var_cart = covariance.orthogonalize_covariance_matrix( ls.covariance_matrix(), xs.unit_cell(), xs.parameter_map()) var_site_cart = covariance.extract_covariance_matrix_for_sites( flex.size_t_range(len(xs.scatterers())), var_cart, xs.parameter_map()) site_esds = var_site_cart.matrix_packed_u_diagonal() indicators = flex.double() for i in xrange(0, len(site_esds), 3): stats = scitbx.math.basic_statistics(site_esds[i:i+3]) indicators.append(stats.bias_corrected_standard_deviation/stats.mean) assert indicators.all_lt(1)
def exercise_floating_origin_dynamic_weighting(verbose=False): from cctbx import covariance import scitbx.math worst_condition_number_acceptable = 10 # light elements only xs0 = random_structure.xray_structure(elements=['C', 'C', 'C', 'O', 'N'], use_u_aniso=True) fo_sq = xs0.structure_factors(d_min=0.8).f_calc().norm() fo_sq = fo_sq.customized_copy(sigmas=flex.double(fo_sq.size(), 1.)) xs = xs0.deep_copy_scatterers() xs.shake_adp() xs.shake_sites_in_place(rms_difference=0.1) for sc in xs.scatterers(): sc.flags.set_grad_site(True).set_grad_u_aniso(True) ls = least_squares.crystallographic_ls( fo_sq.as_xray_observations(), constraints.reparametrisation( structure=xs, constraints=[], connectivity_table=smtbx.utils.connectivity_table(xs)), weighting_scheme=least_squares.unit_weighting(), origin_fixing_restraints_type= origin_fixing_restraints.atomic_number_weighting) ls.build_up() lambdas = eigensystem.real_symmetric( ls.normal_matrix_packed_u().matrix_packed_u_as_symmetric()).values() # assert the restrained L.S. problem is not too ill-conditionned cond = math.log10(lambdas[0]/lambdas[-1]) msg = "light elements: %.1f" % cond if verbose: print msg assert cond < worst_condition_number_acceptable, msg # one heavy element xs0 = random_structure.xray_structure( space_group_info=sgtbx.space_group_info('hall: P 2yb'), elements=['Zn', 'C', 'C', 'C', 'O', 'N'], use_u_aniso=True) fo_sq = xs0.structure_factors(d_min=0.8).f_calc().norm() fo_sq = fo_sq.customized_copy(sigmas=flex.double(fo_sq.size(), 1.)) xs = xs0.deep_copy_scatterers() xs.shake_adp() xs.shake_sites_in_place(rms_difference=0.1) for sc in xs.scatterers(): sc.flags.set_grad_site(True).set_grad_u_aniso(True) ls = least_squares.crystallographic_ls( fo_sq.as_xray_observations(), constraints.reparametrisation( structure=xs, constraints=[], connectivity_table=smtbx.utils.connectivity_table(xs)), weighting_scheme=least_squares.mainstream_shelx_weighting(), origin_fixing_restraints_type= origin_fixing_restraints.atomic_number_weighting) ls.build_up() lambdas = eigensystem.real_symmetric( ls.normal_matrix_packed_u().matrix_packed_u_as_symmetric()).values() # assert the restrained L.S. problem is not too ill-conditionned cond = math.log10(lambdas[0]/lambdas[-1]) msg = "one heavy element + light elements (synthetic data): %.1f" % cond if verbose: print msg assert cond < worst_condition_number_acceptable, msg # are esd's for x,y,z coordinates of the same order of magnitude? var_cart = covariance.orthogonalize_covariance_matrix( ls.covariance_matrix(), xs.unit_cell(), xs.parameter_map()) var_site_cart = covariance.extract_covariance_matrix_for_sites( flex.size_t_range(len(xs.scatterers())), var_cart, xs.parameter_map()) site_esds = var_site_cart.matrix_packed_u_diagonal() indicators = flex.double() for i in xrange(0, len(site_esds), 3): stats = scitbx.math.basic_statistics(site_esds[i:i+3]) indicators.append(stats.bias_corrected_standard_deviation/stats.mean) assert indicators.all_lt(1) # especially troublesome structure with one heavy element # (contributed by Jonathan Coome) xs0 = xray.structure( crystal_symmetry=crystal.symmetry( unit_cell=(8.4519, 8.4632, 18.7887, 90, 96.921, 90), space_group_symbol="hall: P 2yb"), scatterers=flex.xray_scatterer([ xray.scatterer( #0 label="ZN1", site=(-0.736683, -0.313978, -0.246902), u=(0.000302, 0.000323, 0.000054, 0.000011, 0.000015, -0.000004)), xray.scatterer( #1 label="N3B", site=(-0.721014, -0.313583, -0.134277), u=(0.000268, 0.000237, 0.000055, -0.000027, 0.000005, 0.000006)), xray.scatterer( #2 label="N3A", site=(-0.733619, -0.290423, -0.357921), u=(0.000229, 0.000313, 0.000053, 0.000022, 0.000018, -0.000018)), xray.scatterer( #3 label="C9B", site=(-1.101537, -0.120157, -0.138063), u=(0.000315, 0.000345, 0.000103, 0.000050, 0.000055, -0.000017)), xray.scatterer( #4 label="N5B", site=(-0.962032, -0.220345, -0.222045), u=(0.000274, 0.000392, 0.000060, -0.000011, -0.000001, -0.000002)), xray.scatterer( #5 label="N1B", site=(-0.498153, -0.402742, -0.208698), u=(0.000252, 0.000306, 0.000063, 0.000000, 0.000007, 0.000018)), xray.scatterer( #6 label="C3B", site=(-0.322492, -0.472610, -0.114594), u=(0.000302, 0.000331, 0.000085, 0.000016, -0.000013, 0.000037)), xray.scatterer( #7 label="C4B", site=(-0.591851, -0.368163, -0.094677), u=(0.000262, 0.000255, 0.000073, -0.000034, 0.000027, -0.000004)), xray.scatterer( #8 label="N4B", site=(-0.969383, -0.204624, -0.150014), u=(0.000279, 0.000259, 0.000070, -0.000009, 0.000039, 0.000000)), xray.scatterer( #9 label="N2B", site=(-0.470538, -0.414572, -0.135526), u=(0.000277, 0.000282, 0.000065, 0.000003, 0.000021, -0.000006)), xray.scatterer( #10 label="C8A", site=(-0.679889, -0.158646, -0.385629), u=(0.000209, 0.000290, 0.000078, 0.000060, 0.000006, 0.000016)), xray.scatterer( #11 label="N5A", site=(-0.649210, -0.075518, -0.263412), u=(0.000307, 0.000335, 0.000057, -0.000002, 0.000016, -0.000012)), xray.scatterer( #12 label="C6B", site=(-0.708620, -0.325965, 0.011657), u=(0.000503, 0.000318, 0.000053, -0.000058, 0.000032, -0.000019)), xray.scatterer( #13 label="C10B", site=(-1.179332, -0.083184, -0.202815), u=(0.000280, 0.000424, 0.000136, 0.000094, 0.000006, 0.000013)), xray.scatterer( #14 label="N1A", site=(-0.838363, -0.532191, -0.293213), u=(0.000312, 0.000323, 0.000060, 0.000018, 0.000011, -0.000008)), xray.scatterer( #15 label="C3A", site=(-0.915414, -0.671031, -0.393826), u=(0.000319, 0.000384, 0.000078, -0.000052, -0.000001, -0.000020)), xray.scatterer( #16 label="C1A", site=(-0.907466, -0.665419, -0.276011), u=(0.000371, 0.000315, 0.000079, 0.000006, 0.000036, 0.000033)), xray.scatterer( #17 label="C1B", site=(-0.365085, -0.452753, -0.231927), u=(0.000321, 0.000253, 0.000087, -0.000024, 0.000047, -0.000034)), xray.scatterer( #18 label="C11A", site=(-0.598622, 0.053343, -0.227354), u=(0.000265, 0.000409, 0.000084, 0.000088, -0.000018, -0.000030)), xray.scatterer( #19 label="C2A", site=(-0.958694, -0.755645, -0.337016), u=(0.000394, 0.000350, 0.000106, -0.000057, 0.000027, -0.000005)), xray.scatterer( #20 label="C4A", site=(-0.784860, -0.407601, -0.402050), u=(0.000238, 0.000296, 0.000064, 0.000002, 0.000011, -0.000016)), xray.scatterer( #21 label="C5A", site=(-0.784185, -0.399716, -0.475491), u=(0.000310, 0.000364, 0.000062, 0.000044, -0.000011, -0.000017)), xray.scatterer( #22 label="N4A", site=(-0.630284, -0.043981, -0.333143), u=(0.000290, 0.000275, 0.000074, 0.000021, 0.000027, 0.000013)), xray.scatterer( #23 label="C10A", site=(-0.545465, 0.166922, -0.272829), u=(0.000369, 0.000253, 0.000117, 0.000015, -0.000002, -0.000008)), xray.scatterer( #24 label="C9A", site=(-0.567548, 0.102272, -0.339923), u=(0.000346, 0.000335, 0.000103, -0.000016, 0.000037, 0.000023)), xray.scatterer( #25 label="C11B", site=(-1.089943, -0.146930, -0.253779), u=(0.000262, 0.000422, 0.000102, -0.000018, -0.000002, 0.000029)), xray.scatterer( #26 label="N2A", site=(-0.843385, -0.537780, -0.366515), u=(0.000273, 0.000309, 0.000055, -0.000012, -0.000005, -0.000018)), xray.scatterer( #27 label="C7A", site=(-0.674021, -0.136086, -0.457790), u=(0.000362, 0.000378, 0.000074, 0.000043, 0.000034, 0.000016)), xray.scatterer( #28 label="C8B", site=(-0.843625, -0.264182, -0.102023), u=(0.000264, 0.000275, 0.000072, -0.000025, 0.000019, -0.000005)), xray.scatterer( #29 label="C6A", site=(-0.726731, -0.261702, -0.502366), u=(0.000339, 0.000472, 0.000064, 0.000062, -0.000003, 0.000028)), xray.scatterer( #30 label="C5B", site=(-0.577197, -0.376753, -0.020800), u=(0.000349, 0.000353, 0.000066, -0.000082, -0.000022, 0.000014)), xray.scatterer( #31 label="C2B", site=(-0.252088, -0.497338, -0.175057), u=(0.000251, 0.000342, 0.000119, 0.000020, 0.000034, -0.000018)), xray.scatterer( #32 label="C7B", site=(-0.843956, -0.268811, -0.028080), u=(0.000344, 0.000377, 0.000078, -0.000029, 0.000059, -0.000007)), xray.scatterer( #33 label="F4B", site=(-0.680814, -0.696808, -0.115056), u=(0.000670, 0.000408, 0.000109, -0.000099, 0.000139, -0.000031)), xray.scatterer( #34 label="F1B", site=(-0.780326, -0.921249, -0.073962), u=(0.000687, 0.000357, 0.000128, -0.000152, -0.000011, 0.000021)), xray.scatterer( #35 label="B1B", site=(-0.795220, -0.758128, -0.075955), u=(0.000413, 0.000418, 0.000075, 0.000054, 0.000045, 0.000023)), xray.scatterer( #36 label="F2B", site=(-0.945140, -0.714626, -0.105820), u=(0.000584, 0.001371, 0.000108, 0.000420, 0.000067, 0.000134)), xray.scatterer( #37 label="F3B", site=(-0.768914, -0.701660, -0.005161), u=(0.000678, 0.000544, 0.000079, -0.000000, 0.000090, -0.000021)), xray.scatterer( #38 label="F1A", site=(-0.109283, -0.252334, -0.429288), u=(0.000427, 0.001704, 0.000125, 0.000407, 0.000041, 0.000035)), xray.scatterer( #39 label="F4A", site=(-0.341552, -0.262864, -0.502023), u=(0.000640, 0.000557, 0.000081, -0.000074, 0.000042, -0.000052)), xray.scatterer( #40 label="F3A", site=(-0.324533, -0.142292, -0.393215), u=(0.000471, 0.001203, 0.000134, 0.000333, -0.000057, -0.000220)), xray.scatterer( #41 label="F2A", site=(-0.312838, -0.405405, -0.400231), u=(0.002822, 0.000831, 0.000092, -0.000648, 0.000115, 0.000027)), xray.scatterer( #42 label="B1A", site=(-0.271589, -0.268874, -0.430724), u=(0.000643, 0.000443, 0.000079, 0.000040, 0.000052, -0.000034)), xray.scatterer( #43 label="H5B", site=(-0.475808, -0.413802, 0.004402), u=0.005270), xray.scatterer( #44 label="H6B", site=(-0.699519, -0.326233, 0.062781), u=0.019940), xray.scatterer( #45 label="H3B", site=(-0.283410, -0.484757, -0.063922), u=0.029990), xray.scatterer( #46 label="H1B", site=(-0.357103, -0.451819, -0.284911), u=0.031070), xray.scatterer( #47 label="H10A", site=(-0.495517, 0.268296, -0.256187), u=0.027610), xray.scatterer( #48 label="H2B", site=(-0.147129, -0.535141, -0.174699), u=0.017930), xray.scatterer( #49 label="H7A", site=(-0.643658, -0.031387, -0.475357), u=0.020200), xray.scatterer( #50 label="H1A", site=(-0.912757, -0.691043, -0.227554), u=0.033320), xray.scatterer( #51 label="H7B", site=(-0.933670, -0.241189, -0.010263), u=0.021310), xray.scatterer( #52 label="H11B", site=(-1.107736, -0.155470, -0.311996), u=0.041500), xray.scatterer( #53 label="H9A", site=(-0.539908, 0.139753, -0.382281), u=0.007130), xray.scatterer( #54 label="H10B", site=(-1.265944, -0.029610, -0.212398), u=0.030910), xray.scatterer( #55 label="H3A", site=(-0.934728, -0.691149, -0.450551), u=0.038950), xray.scatterer( #56 label="H5A", site=(-0.833654, -0.487479, -0.508239), u=0.031150), xray.scatterer( #57 label="H6A", site=(-0.742871, -0.242269, -0.558157), u=0.050490), xray.scatterer( #58 label="H9B", site=(-1.120150, -0.093752, -0.090706), u=0.039310), xray.scatterer( #59 label="H11A", site=(-0.593074, 0.054973, -0.180370), u=0.055810), xray.scatterer( #60 label="H2A", site=(-0.999576, -0.842158, -0.340837), u=0.057030) ])) fo_sq = xs0.structure_factors(d_min=0.8).f_calc().norm() fo_sq = fo_sq.customized_copy(sigmas=flex.double(fo_sq.size(), 1.)) for hydrogen_flag in (True, False): xs = xs0.deep_copy_scatterers() if not hydrogen_flag: xs.select_inplace(~xs.element_selection('H')) xs.shake_adp() xs.shake_sites_in_place(rms_difference=0.1) for sc in xs.scatterers(): sc.flags.set_grad_site(True).set_grad_u_aniso(False) ls = least_squares.crystallographic_ls( fo_sq.as_xray_observations(), constraints.reparametrisation( structure=xs, constraints=[], connectivity_table=smtbx.utils.connectivity_table(xs)), weighting_scheme=least_squares.unit_weighting(), origin_fixing_restraints_type= origin_fixing_restraints.atomic_number_weighting) ls.build_up() lambdas = eigensystem.real_symmetric( ls.normal_matrix_packed_u().matrix_packed_u_as_symmetric()).values() # assert the restrained L.S. problem is not too ill-conditionned cond = math.log10(lambdas[0]/lambdas[-1]) msg = ("one heavy element + light elements (real data) %s Hydrogens: %.1f" % (['without', 'with'][hydrogen_flag], cond)) if verbose: print msg assert cond < worst_condition_number_acceptable, msg # are esd's for x,y,z coordinates of the same order of magnitude? var_cart = covariance.orthogonalize_covariance_matrix( ls.covariance_matrix(), xs.unit_cell(), xs.parameter_map()) var_site_cart = covariance.extract_covariance_matrix_for_sites( flex.size_t_range(len(xs.scatterers())), var_cart, xs.parameter_map()) site_esds = var_site_cart.matrix_packed_u_diagonal() indicators = flex.double() for i in xrange(0, len(site_esds), 3): stats = scitbx.math.basic_statistics(site_esds[i:i+3]) indicators.append(stats.bias_corrected_standard_deviation/stats.mean) assert indicators.all_lt(1)