Exemple #1
0
def exercise_geometry():
    xs = quartz()
    uc = xs.unit_cell()
    flags = xs.scatterer_flags()
    for f in flags:
        f.set_grad_site(True)
    xs.set_scatterer_flags(flags)
    cov = flex.double(
        (1e-8, 1e-9, 2e-9, 3e-9, 4e-9, 5e-9, 2e-8, 1e-9, 2e-9, 3e-9, 4e-9,
         3e-8, 1e-9, 2e-9, 3e-9, 2e-8, 1e-9, 2e-9, 3e-8, 1e-9, 4e-8))
    cell_vcv = flex.double((3e-2, 3e-2, 0, 0, 0, 0, 3e-2, 0, 0, 0, 0, 4e-2, 0,
                            0, 0, 0, 0, 0, 0, 0, 0))
    param_map = xs.parameter_map()
    cov_cart = covariance.orthogonalize_covariance_matrix(cov, uc, param_map)
    O = matrix.sqr(uc.orthogonalization_matrix())
    F = matrix.sqr(uc.fractionalization_matrix())
    sites_cart = xs.sites_cart()
    sites_frac = xs.sites_frac()
    # distances
    rt_mx_ji = sgtbx.rt_mx('-y,x-y,z-1/3')
    sites = (sites_cart[0], uc.orthogonalize(rt_mx_ji * sites_frac[1]))
    d = geometry.distance(sites)
    assert approx_equal(d.distance_model, 1.6159860469110217)
    v = matrix.col(sites[1]) - matrix.col(sites[0])
    r_inv_cart = (O * matrix.sqr(rt_mx_ji.r().inverse().as_double()) * F)
    g = d.d_distance_d_sites()
    g = matrix.row(g[0] + tuple(r_inv_cart * matrix.col(g[1])))
    f = g * matrix.sqr(cov_cart.matrix_packed_u_as_symmetric()) * g.transpose()
    assert approx_equal(d.variance(cov_cart, uc, rt_mx_ji), f[0], eps=1e-15)
    assert approx_equal(0.0018054494791580823,
                        d.variance(cov_cart, cell_vcv, uc, rt_mx_ji))
    rt_mx_ji = sgtbx.rt_mx('x+1,y,z')
    sites = (sites_cart[0], uc.orthogonalize(rt_mx_ji * sites_frac[0]))
    d = geometry.distance(sites)
    assert approx_equal(d.distance_model, uc.parameters()[0])
    assert approx_equal(cell_vcv.matrix_packed_u_diagonal()[0],
                        d.variance(cov_cart, cell_vcv, uc, rt_mx_ji))
    # angles
    rt_mx_ji = sgtbx.rt_mx('x-y,x,z-2/3')
    rt_mx_ki = sgtbx.rt_mx('-y,x-y,z-1/3')
    r_inv_cart_ji = (O * matrix.sqr(rt_mx_ji.r().inverse().as_double()) * F)
    r_inv_cart_ki = (O * matrix.sqr(rt_mx_ki.r().inverse().as_double()) * F)
    cov_a = covariance.extract_covariance_matrix_for_sites(
        flex.size_t([1, 0, 1]), cov_cart, param_map)
    sites = (uc.orthogonalize(rt_mx_ji * sites_frac[1]), sites_cart[0],
             uc.orthogonalize(rt_mx_ki * sites_frac[1]))
    a = geometry.angle(sites)
    assert approx_equal(a.angle_model, 101.30738566828551)
    g = a.d_angle_d_sites()
    g = matrix.row(
        tuple(r_inv_cart_ji * matrix.col(g[0])) + g[1] +
        tuple(r_inv_cart_ki * matrix.col(g[2])))
    f = g * matrix.sqr(cov_a.matrix_packed_u_as_symmetric()) * g.transpose()
    assert approx_equal(a.variance(cov_a, uc,
                                   (rt_mx_ji, sgtbx.rt_mx(), rt_mx_ki)),
                        f[0],
                        eps=1e-15)
    assert approx_equal(
        0.0042632511984529199,
        a.variance(cov_a, cell_vcv, uc, (rt_mx_ji, sgtbx.rt_mx(), rt_mx_ki)))
def exercise_covariance():
  xs = xray.structure(
    crystal_symmetry=crystal.symmetry(
      (5.01,5.01,5.47,90,90,120), "P6222"),
    scatterers=flex.xray_scatterer([
      xray.scatterer("Si", (1/2.,1/2.,1/3.)),
      xray.scatterer("O", (0.197,-0.197,0.83333))]))
  uc = xs.unit_cell()
  flags = xs.scatterer_flags()
  for f in flags:
    f.set_grad_site(True)
  xs.set_scatterer_flags(flags)
  cov = flex.double((1e-8,1e-9,2e-9,3e-9,4e-9,5e-9,
                          2e-8,1e-9,2e-9,3e-9,4e-9,
                               3e-8,1e-9,2e-9,3e-9,
                                    2e-8,1e-9,2e-9,
                                         3e-8,1e-9,
                                              4e-8))
  param_map = xs.parameter_map()
  assert approx_equal(cov,
    covariance.extract_covariance_matrix_for_sites(flex.size_t([0,1]), cov, param_map))
  cov_cart = covariance.orthogonalize_covariance_matrix(cov, uc, param_map)
  O = matrix.sqr(uc.orthogonalization_matrix())
  for i in range(param_map.n_scatterers):
    cov_i = covariance.extract_covariance_matrix_for_sites(flex.size_t([i]), cov, param_map)
    cov_i_cart = covariance.extract_covariance_matrix_for_sites(flex.size_t([i]), cov_cart, param_map)
    assert approx_equal(
      O * matrix.sym(sym_mat3=cov_i) * O.transpose(),
      matrix.sym(sym_mat3=cov_i_cart).as_mat3())
  for f in flags: f.set_grads(False)
  flags[0].set_grad_u_aniso(True)
  flags[0].set_use_u_aniso(True)
  flags[1].set_grad_u_iso(True)
  flags[1].set_use_u_iso(True)
  xs.set_scatterer_flags(flags)
  param_map = xs.parameter_map()
  cov = flex.double(7*7, 0)
  cov.reshape(flex.grid(7,7))
  cov.matrix_diagonal_set_in_place(flex.double([i for i in range(7)]))
  cov = cov.matrix_symmetric_as_packed_u()
  assert approx_equal([i for i in range(6)],
                      covariance.extract_covariance_matrix_for_u_aniso(
                        0, cov, param_map).matrix_packed_u_diagonal())
  assert covariance.variance_for_u_iso(1, cov, param_map) == 6
  try: covariance.variance_for_u_iso(0, cov, param_map)
  except RuntimeError: pass
  else: raise Exception_expected
  try: covariance.extract_covariance_matrix_for_u_aniso(1, cov, param_map)
  except RuntimeError: pass
  else: raise Exception_expected
  approx_equal(covariance.extract_covariance_matrix_for_sites(
    flex.size_t([1]), cov, param_map), (0,0,0,0,0,0))
Exemple #3
0
 def __init__(self,
              hbonds,
              pair_asu_table,
              site_labels,
              sites_frac=None,
              sites_cart=None,
              min_dha_angle=150, # degrees
              max_da_distance=2.9, # angstrom
              covariance_matrix=None,
              cell_covariance_matrix=None,
              parameter_map=None,
              eps=2e-16):
   assert [sites_frac, sites_cart].count(None) == 1
   fmt_a = "%.1f"
   pair_asu_table = pair_asu_table
   asu_mappings = pair_asu_table.asu_mappings()
   space_group_info = sgtbx.space_group_info(group=asu_mappings.space_group())
   self.unit_cell = asu_mappings.unit_cell()
   if sites_cart is not None:
     sites_frac = self.unit_cell.fractionalize(sites_cart)
   if sites_frac is not None:
     sites_cart = self.unit_cell.orthogonalize(sites_frac)
   if covariance_matrix is not None:
     assert parameter_map is not None
     self.covariance_matrix_cart = covariance.orthogonalize_covariance_matrix(
       covariance_matrix, self.unit_cell, parameter_map)
   else: self.covariance_matrix_cart = None
   self.cell_covariance_matrix = cell_covariance_matrix
   self.eps = eps
   self.parameter_map = parameter_map
   self.loop = model.loop(header=(
     "_geom_hbond_atom_site_label_D",
     "_geom_hbond_atom_site_label_H",
     "_geom_hbond_atom_site_label_A",
     "_geom_hbond_distance_DH",
     "_geom_hbond_distance_HA",
     "_geom_hbond_distance_DA",
     "_geom_hbond_angle_DHA",
     "_geom_hbond_site_symmetry_A",
   ))
   for hbond in hbonds:
     d_seq, a_seq = hbond.d_seq, hbond.a_seq
     site_cart_d = sites_cart[d_seq]
     if hbond.rt_mx is not None:
       site_frac_a = sites_frac[a_seq]
       site_frac_a = hbond.rt_mx * site_frac_a
       site_cart_a = self.unit_cell.orthogonalize(site_frac_a)
     else:
       site_cart_a = sites_cart[a_seq]
     distance_da = geometry.distance((site_cart_d, site_cart_a))
     for h_seq, h_sym_groups in pair_asu_table.table()[hbond.d_seq].items():
       if site_labels[h_seq][0] not in ('H','D'):
         # XXX better to pass scattering types instead?
         continue
       site_cart_h = sites_cart[h_seq]
       distance_dh = geometry.distance((site_cart_d, site_cart_h))
       distance_ha = geometry.distance((site_cart_h, site_cart_a))
       angle_dha = geometry.angle((site_cart_d, site_cart_h, site_cart_a))
       if (angle_dha.angle_model < min_dha_angle or
           distance_da.distance_model > max_da_distance):
         continue
       if hbond.rt_mx is not None:
         sym_code = space_group_info.cif_symmetry_code(hbond.rt_mx)
       else: sym_code = '.'
       self.loop.add_row((
         site_labels[d_seq],
         site_labels[h_seq],
         site_labels[a_seq],
         self.formatted_distance(d_seq, h_seq, distance_dh, unit_mx),
         self.formatted_distance(h_seq, a_seq, distance_ha, unit_mx),
         self.formatted_distance(d_seq, a_seq, distance_da, hbond.rt_mx),
         self.formatted_angle(d_seq, h_seq, a_seq, angle_dha, hbond.rt_mx),
         sym_code
       ))
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)
Exemple #5
0
def exercise_covariance():
    xs = xray.structure(crystal_symmetry=crystal.symmetry(
        (5.01, 5.01, 5.47, 90, 90, 120), "P6222"),
                        scatterers=flex.xray_scatterer([
                            xray.scatterer("Si", (1 / 2., 1 / 2., 1 / 3.)),
                            xray.scatterer("O", (0.197, -0.197, 0.83333))
                        ]))
    uc = xs.unit_cell()
    flags = xs.scatterer_flags()
    for f in flags:
        f.set_grad_site(True)
    xs.set_scatterer_flags(flags)
    cov = flex.double(
        (1e-8, 1e-9, 2e-9, 3e-9, 4e-9, 5e-9, 2e-8, 1e-9, 2e-9, 3e-9, 4e-9,
         3e-8, 1e-9, 2e-9, 3e-9, 2e-8, 1e-9, 2e-9, 3e-8, 1e-9, 4e-8))
    param_map = xs.parameter_map()
    assert approx_equal(
        cov,
        covariance.extract_covariance_matrix_for_sites(flex.size_t([0, 1]),
                                                       cov, param_map))
    cov_cart = covariance.orthogonalize_covariance_matrix(cov, uc, param_map)
    O = matrix.sqr(uc.orthogonalization_matrix())
    for i in range(param_map.n_scatterers):
        cov_i = covariance.extract_covariance_matrix_for_sites(
            flex.size_t([i]), cov, param_map)
        cov_i_cart = covariance.extract_covariance_matrix_for_sites(
            flex.size_t([i]), cov_cart, param_map)
        assert approx_equal(O * matrix.sym(sym_mat3=cov_i) * O.transpose(),
                            matrix.sym(sym_mat3=cov_i_cart).as_mat3())
    for f in flags:
        f.set_grads(False)
    flags[0].set_grad_u_aniso(True)
    flags[0].set_use_u_aniso(True)
    flags[1].set_grad_u_iso(True)
    flags[1].set_use_u_iso(True)
    xs.set_scatterer_flags(flags)
    param_map = xs.parameter_map()
    cov = flex.double(7 * 7, 0)
    cov.reshape(flex.grid(7, 7))
    cov.matrix_diagonal_set_in_place(flex.double([i for i in range(7)]))
    cov = cov.matrix_symmetric_as_packed_u()
    assert approx_equal([i for i in range(6)],
                        covariance.extract_covariance_matrix_for_u_aniso(
                            0, cov, param_map).matrix_packed_u_diagonal())
    assert covariance.variance_for_u_iso(1, cov, param_map) == 6
    try:
        covariance.variance_for_u_iso(0, cov, param_map)
    except RuntimeError:
        pass
    else:
        raise Exception_expected
    try:
        covariance.extract_covariance_matrix_for_u_aniso(1, cov, param_map)
    except RuntimeError:
        pass
    else:
        raise Exception_expected
    approx_equal(
        covariance.extract_covariance_matrix_for_sites(flex.size_t([1]), cov,
                                                       param_map),
        (0, 0, 0, 0, 0, 0))
def exercise_geometry():
  xs = quartz()
  uc = xs.unit_cell()
  flags = xs.scatterer_flags()
  for f in flags:
    f.set_grad_site(True)
  xs.set_scatterer_flags(flags)
  cov = flex.double((1e-8,1e-9,2e-9,3e-9,4e-9,5e-9,
                          2e-8,1e-9,2e-9,3e-9,4e-9,
                               3e-8,1e-9,2e-9,3e-9,
                                    2e-8,1e-9,2e-9,
                                         3e-8,1e-9,
                                              4e-8))
  cell_vcv = flex.double((3e-2,3e-2,0,0,0,0,
                               3e-2,0,0,0,0,
                                 4e-2,0,0,0,
                                      0,0,0,
                                        0,0,
                                          0))
  param_map = xs.parameter_map()
  cov_cart = covariance.orthogonalize_covariance_matrix(cov, uc, param_map)
  O = matrix.sqr(uc.orthogonalization_matrix())
  F = matrix.sqr(uc.fractionalization_matrix())
  sites_cart = xs.sites_cart()
  sites_frac = xs.sites_frac()
  # distances
  rt_mx_ji = sgtbx.rt_mx('-y,x-y,z-1/3')
  sites = (sites_cart[0], uc.orthogonalize(rt_mx_ji*sites_frac[1]))
  d = geometry.distance(sites)
  assert approx_equal(d.distance_model, 1.6159860469110217)
  v = matrix.col(sites[1]) - matrix.col(sites[0])
  r_inv_cart = (O * matrix.sqr(rt_mx_ji.r().inverse().as_double()) * F)
  g = d.d_distance_d_sites()
  g = matrix.row(g[0] + tuple(r_inv_cart*matrix.col(g[1])))
  f = g * matrix.sqr(cov_cart.matrix_packed_u_as_symmetric()) * g.transpose()
  assert approx_equal(d.variance(cov_cart, uc, rt_mx_ji), f[0], eps=1e-15)
  assert approx_equal(
    0.0018054494791580823, d.variance(cov_cart, cell_vcv, uc, rt_mx_ji))
  rt_mx_ji = sgtbx.rt_mx('x+1,y,z')
  sites = (sites_cart[0], uc.orthogonalize(rt_mx_ji*sites_frac[0]))
  d = geometry.distance(sites)
  assert approx_equal(d.distance_model, uc.parameters()[0])
  assert approx_equal(cell_vcv.matrix_packed_u_diagonal()[0],
                      d.variance(cov_cart, cell_vcv, uc, rt_mx_ji))
  # angles
  rt_mx_ji = sgtbx.rt_mx('x-y,x,z-2/3')
  rt_mx_ki = sgtbx.rt_mx('-y,x-y,z-1/3')
  r_inv_cart_ji = (O * matrix.sqr(rt_mx_ji.r().inverse().as_double()) * F)
  r_inv_cart_ki = (O * matrix.sqr(rt_mx_ki.r().inverse().as_double()) * F)
  cov_a = covariance.extract_covariance_matrix_for_sites(flex.size_t([1,0,1]), cov_cart, param_map)
  sites = (uc.orthogonalize(rt_mx_ji*sites_frac[1]),
           sites_cart[0],
           uc.orthogonalize(rt_mx_ki*sites_frac[1]))
  a = geometry.angle(sites)
  assert approx_equal(a.angle_model, 101.30738566828551)
  g = a.d_angle_d_sites()
  g = matrix.row(tuple(r_inv_cart_ji*matrix.col(g[0])) + g[1] +
                 tuple(r_inv_cart_ki*matrix.col(g[2])))
  f = g * matrix.sqr(cov_a.matrix_packed_u_as_symmetric()) * g.transpose()
  assert approx_equal(
    a.variance(cov_a, uc, (rt_mx_ji, sgtbx.rt_mx(), rt_mx_ki)), f[0], eps=1e-15)
  assert approx_equal(0.0042632511984529199,
    a.variance(cov_a, cell_vcv, uc, (rt_mx_ji, sgtbx.rt_mx(), rt_mx_ki)))
Exemple #7
0
def exercise_high_symmetry_case():
  """
  BF6 sitting on inversion centre in high symmetry space group.

  The angles formed between F20, B17 and either F18 or F19 are necessarily
  exactly equal to 90 degrees, and hence their variance should be exactly zero.
  The angles formed by F18, B17 and F19 are free to refine, and hence should
  have an associated variance.
  """
  xs = xray.structure(
    crystal_symmetry=crystal.symmetry(
    unit_cell=(22.543, 22.543, 35.5167, 90, 90, 90),
    space_group_symbol='hall: -I 4bd 2'),
    scatterers=flex.xray_scatterer((
      xray.scatterer( #24
        label='F18',
        site=(0.500000, 0.970584, -0.041027),
        u=(0.000258, 0.000675, 0.000138, -0.000000, -0.000000, -0.000043),
        fp=0.017939,
        fdp=0.010330),
                     xray.scatterer( #25
        label='F19',
        site=(0.500000, 0.933678, 0.021766),
        u=(0.000178, 0.001046, 0.000158, -0.000000, -0.000000, 0.000144),
        fp=0.017939,
        fdp=0.010330),
                     xray.scatterer( #26
        label='F20',
        site=(0.438015, 1.000000, 0.000000),
        u=(0.000231, 0.000500, 0.000106, -0.000000, -0.000000, 0.000078),
        fp=0.017939,
        fdp=0.010330),
                     xray.scatterer( #27
        label='B17',
        site=(0.500000, 1.000000, 0.000000),
        u=(0.000133, 0.000624, 0.000051, -0.000000, -0.000000, 0.000048),
        fp=0.001413,
        fdp=0.000674)
        )))

  flags = xs.scatterer_flags()
  for f in flags: f.set_grad_site(True)
  xs.set_scatterer_flags(flags)
  sites_frac = xs.sites_frac()
  unit_cell = xs.unit_cell()
  cov = flex.double([
    0,0,0,0,0,0,0,0,0,0,0,0,5.5895145222321514e-07,-1.7223269587621895e-08,0,
    -2.0367609296594096e-07,-6.6231210988833185e-08,-2.6525243183929821e-09,0,0,
    0,0,0,1.1503438451957222e-07,0,-3.5665932804823073e-08,
    7.4165082206213702e-09,-6.8444182449209374e-09,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    9.0344019852871238e-07,1.2109549448751337e-07,-7.4794454124745421e-09,0,0,
    0,0,0,1.5840179985755122e-07,9.1193835484941833e-09,0,0,0,0,0,
    1.447679091961411e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])
  cell_cov = flex.double([
    2.4999999999999999e-07,2.4999999999999999e-07,0,0,0,0,
    2.4999999999999999e-07,0,0,0,0,1.4399999999999998e-06,0,0,0,0,0,0,0,0,0])
  param_map = xs.parameter_map()
  cov_cart = covariance.orthogonalize_covariance_matrix(
    cov, unit_cell, param_map)
  i_seqs = flex.size_t((2,3,1))
  cov_i_seqs = covariance.extract_covariance_matrix_for_sites(
    i_seqs, cov_cart, param_map)
  for sym_ops in (
      (sgtbx.rt_mx(),sgtbx.rt_mx(),sgtbx.rt_mx()),
      (sgtbx.rt_mx("1-x,2-y,-z"), sgtbx.rt_mx(), sgtbx.rt_mx()),
      (sgtbx.rt_mx(), sgtbx.rt_mx(), sgtbx.rt_mx("1-x,2-y,-z")),
      (sgtbx.rt_mx("1-x,2-y,-z"), sgtbx.rt_mx(), sgtbx.rt_mx("1-x,2-y,-z"))):
    site_frac_ji = sym_ops[0] * sites_frac[i_seqs[0]]
    site_frac_i = sym_ops[1] * sites_frac[i_seqs[1]]
    site_frac_ki = sym_ops[2] * sites_frac[i_seqs[2]]
    a = geometry.angle((unit_cell.orthogonalize(site_frac_ji),
                        unit_cell.orthogonalize(site_frac_i),
                        unit_cell.orthogonalize(site_frac_ki)))
    var = a.variance(cov_i_seqs, cell_cov, unit_cell, sym_ops)
    assert approx_equal(var, 0, eps=2e-16)
  pair_asu_table = xs.pair_asu_table(distance_cutoff=2)
  import libtbx.load_env
  if libtbx.env.has_module('iotbx'):
    import iotbx.cif
    s = StringIO()
    print >> s, iotbx.cif.distances_as_cif_loop(
      pair_asu_table,
      xs.scatterers().extract_labels(),
      sites_frac=xs.sites_frac(),
      covariance_matrix=cov,
      cell_covariance_matrix=cell_cov,
      parameter_map=param_map).loop
    assert not show_diff(s.getvalue(), """\
loop_
  _geom_bond_atom_site_label_1
  _geom_bond_atom_site_label_2
  _geom_bond_distance
  _geom_bond_site_symmetry_2
  F18  B17  1.601(13)  4_575
  F19  B17  1.683(18)  .
  F20  B17   1.397(9)  .

""")
    s = StringIO()
    print >> s, iotbx.cif.angles_as_cif_loop(
      pair_asu_table,
      xs.scatterers().extract_labels(),
      sites_frac=xs.sites_frac(),
      covariance_matrix=cov,
      cell_covariance_matrix=cell_cov,
      parameter_map=param_map).loop
    assert not show_diff(s.getvalue(), """\
loop_
  _geom_angle_atom_site_label_1
  _geom_angle_atom_site_label_2
  _geom_angle_atom_site_label_3
  _geom_angle
  _geom_angle_site_symmetry_1
  _geom_angle_site_symmetry_3
  F18  B17  F18    180.0  .      4_575
  F19  B17  F18  87.1(7)  .      4_575
  F19  B17  F18  92.9(7)  .      .
  F19  B17  F18  92.9(7)  4_575  4_575
  F19  B17  F18  87.1(7)  4_575  .
  F19  B17  F19    180.0  4_575  .
  F20  B17  F18     90.0  .      4_575
  F20  B17  F18     90.0  .      .
  F20  B17  F19     90.0  .      .
  F20  B17  F19     90.0  .      4_575
  F20  B17  F18     90.0  9_675  4_575
  F20  B17  F18     90.0  9_675  .
  F20  B17  F19     90.0  9_675  .
  F20  B17  F19     90.0  9_675  4_575
  F20  B17  F20    180.0  9_675  .

""")
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)