Ejemplo n.º 1
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))
Ejemplo n.º 2
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))
Ejemplo n.º 3
0
    def __init__(self,
                 xray_structure,
                 covariance_matrix=None,
                 cell_covariance_matrix=None):
        crystal_symmetry_as_cif_block.__init__(
            self,
            xray_structure.crystal_symmetry(),
            cell_covariance_matrix=cell_covariance_matrix)
        scatterers = xray_structure.scatterers()
        uc = xray_structure.unit_cell()
        if covariance_matrix is not None:
            param_map = xray_structure.parameter_map()
            covariance_diagonal = covariance_matrix.matrix_packed_u_diagonal()
            u_star_to_u_cif_linear_map_pow2 = flex.pow2(
                flex.double(uc.u_star_to_u_cif_linear_map()))
            u_star_to_u_iso_linear_form = matrix.row(
                uc.u_star_to_u_iso_linear_form())
        fmt = "%.6f"

        # _atom_site_* loop
        atom_site_loop = model.loop(
            header=('_atom_site_label', '_atom_site_type_symbol',
                    '_atom_site_fract_x', '_atom_site_fract_y',
                    '_atom_site_fract_z', '_atom_site_U_iso_or_equiv',
                    '_atom_site_adp_type', '_atom_site_occupancy'))
        for i_seq, sc in enumerate(scatterers):
            # site
            if covariance_matrix is not None and sc.flags.grad_site():
                site = []
                for i in range(3):
                    idx = param_map[i_seq].site
                    if idx > -1:
                        var = covariance_diagonal[idx + i]
                    else:
                        var = 0
                    if var > 0:
                        site.append(
                            format_float_with_su(sc.site[i], math.sqrt(var)))
                    else:
                        site.append(fmt % sc.site[i])
            else:
                site = [fmt % sc.site[i] for i in range(3)]
            # u_eq
            if (covariance_matrix is not None
                    and (sc.flags.grad_u_iso() or sc.flags.grad_u_aniso())):
                if sc.flags.grad_u_iso():
                    u_iso_or_equiv = format_float_with_su(
                        sc.u_iso,
                        math.sqrt(
                            covariance.variance_for_u_iso(
                                i_seq, covariance_matrix, param_map)))
                else:
                    cov = covariance.extract_covariance_matrix_for_u_aniso(
                        i_seq, covariance_matrix,
                        param_map).matrix_packed_u_as_symmetric()
                    var = (u_star_to_u_iso_linear_form *
                           matrix.sqr(cov)).dot(u_star_to_u_iso_linear_form)
                    u_iso_or_equiv = format_float_with_su(
                        sc.u_iso_or_equiv(uc), math.sqrt(var))
            else:
                u_iso_or_equiv = fmt % sc.u_iso_or_equiv(uc)
            if sc.flags.use_u_aniso():
                adp_type = 'Uani'
            else:
                adp_type = 'Uiso'
            atom_site_loop.add_row(
                (sc.label, sc.scattering_type, site[0], site[1], site[2],
                 u_iso_or_equiv, adp_type, fmt % sc.occupancy))
        self.cif_block.add_loop(atom_site_loop)

        # _atom_site_aniso_* loop
        aniso_scatterers = scatterers.select(scatterers.extract_use_u_aniso())
        if aniso_scatterers.size():
            labels = list(scatterers.extract_labels())
            aniso_loop = model.loop(
                header=('_atom_site_aniso_label', '_atom_site_aniso_U_11',
                        '_atom_site_aniso_U_22', '_atom_site_aniso_U_33',
                        '_atom_site_aniso_U_12', '_atom_site_aniso_U_13',
                        '_atom_site_aniso_U_23'))
            for sc in aniso_scatterers:
                u_cif = adptbx.u_star_as_u_cif(uc, sc.u_star)
                if covariance_matrix is not None:
                    row = [sc.label]
                    idx = param_map[labels.index(sc.label)].u_aniso
                    if idx > -1:
                        var = covariance_diagonal[
                            idx:idx + 6] * u_star_to_u_cif_linear_map_pow2
                        for i in range(6):
                            if var[i] > 0:
                                row.append(
                                    format_float_with_su(
                                        u_cif[i], math.sqrt(var[i])))
                            else:
                                row.append(fmt % u_cif[i])
                    else:
                        row = [sc.label] + [fmt % u_cif[i] for i in range(6)]
                else:
                    row = [sc.label] + [fmt % u_cif[i] for i in range(6)]
                aniso_loop.add_row(row)
            self.cif_block.add_loop(aniso_loop)
            self.cif_block.add_loop(atom_type_cif_loop(xray_structure))
Ejemplo n.º 4
0
    def __init__(self, xray_structure, covariance_matrix=None, cell_covariance_matrix=None):
        crystal_symmetry_as_cif_block.__init__(
            self, xray_structure.crystal_symmetry(), cell_covariance_matrix=cell_covariance_matrix
        )
        scatterers = xray_structure.scatterers()
        uc = xray_structure.unit_cell()
        if covariance_matrix is not None:
            param_map = xray_structure.parameter_map()
            covariance_diagonal = covariance_matrix.matrix_packed_u_diagonal()
            u_star_to_u_cif_linear_map_pow2 = flex.pow2(flex.double(uc.u_star_to_u_cif_linear_map()))
            u_star_to_u_iso_linear_form = matrix.row(uc.u_star_to_u_iso_linear_form())
        fmt = "%.6f"

        # _atom_site_* loop
        atom_site_loop = model.loop(
            header=(
                "_atom_site_label",
                "_atom_site_type_symbol",
                "_atom_site_fract_x",
                "_atom_site_fract_y",
                "_atom_site_fract_z",
                "_atom_site_U_iso_or_equiv",
                "_atom_site_adp_type",
                "_atom_site_occupancy",
            )
        )
        for i_seq, sc in enumerate(scatterers):
            site = occu = u_iso_or_equiv = None
            # site
            if covariance_matrix is not None:
                params = param_map[i_seq]
                if sc.flags.grad_site() and params.site >= 0:
                    site = []
                    for i in range(3):
                        site.append(format_float_with_su(sc.site[i], math.sqrt(covariance_diagonal[params.site + i])))
                # occupancy
                if sc.flags.grad_occupancy() and params.occupancy >= 0:
                    occu = format_float_with_su(sc.occupancy, math.sqrt(covariance_diagonal[params.occupancy]))
                # Uiso/eq
                if sc.flags.grad_u_iso() or sc.flags.grad_u_aniso():
                    if sc.flags.grad_u_iso():
                        u_iso_or_equiv = format_float_with_su(
                            sc.u_iso, math.sqrt(covariance.variance_for_u_iso(i_seq, covariance_matrix, param_map))
                        )
                    else:
                        cov = covariance.extract_covariance_matrix_for_u_aniso(
                            i_seq, covariance_matrix, param_map
                        ).matrix_packed_u_as_symmetric()
                        var = (u_star_to_u_iso_linear_form * matrix.sqr(cov)).dot(u_star_to_u_iso_linear_form)
                        u_iso_or_equiv = format_float_with_su(sc.u_iso_or_equiv(uc), math.sqrt(var))

            if site is None:
                site = [fmt % sc.site[i] for i in range(3)]
            if occu is None:
                occu = fmt % sc.occupancy
            if u_iso_or_equiv is None:
                u_iso_or_equiv = fmt % sc.u_iso_or_equiv(uc)

            if sc.flags.use_u_aniso():
                adp_type = "Uani"
            else:
                adp_type = "Uiso"
            atom_site_loop.add_row(
                (sc.label, sc.scattering_type, site[0], site[1], site[2], u_iso_or_equiv, adp_type, occu)
            )
        self.cif_block.add_loop(atom_site_loop)

        # _atom_site_aniso_* loop
        aniso_scatterers = scatterers.select(scatterers.extract_use_u_aniso())
        if aniso_scatterers.size():
            labels = list(scatterers.extract_labels())
            aniso_loop = model.loop(
                header=(
                    "_atom_site_aniso_label",
                    "_atom_site_aniso_U_11",
                    "_atom_site_aniso_U_22",
                    "_atom_site_aniso_U_33",
                    "_atom_site_aniso_U_12",
                    "_atom_site_aniso_U_13",
                    "_atom_site_aniso_U_23",
                )
            )
            for sc in aniso_scatterers:
                u_cif = adptbx.u_star_as_u_cif(uc, sc.u_star)
                if covariance_matrix is not None:
                    row = [sc.label]
                    idx = param_map[labels.index(sc.label)].u_aniso
                    if idx > -1:
                        var = covariance_diagonal[idx : idx + 6] * u_star_to_u_cif_linear_map_pow2
                        for i in range(6):
                            if var[i] > 0:
                                row.append(format_float_with_su(u_cif[i], math.sqrt(var[i])))
                            else:
                                row.append(fmt % u_cif[i])
                    else:
                        row = [sc.label] + [fmt % u_cif[i] for i in range(6)]
                else:
                    row = [sc.label] + [fmt % u_cif[i] for i in range(6)]
                aniso_loop.add_row(row)
            self.cif_block.add_loop(aniso_loop)
            self.cif_block.add_loop(atom_type_cif_loop(xray_structure))