Пример #1
0
    def show(self, out=None):
        def format_p(p_value):
            if p_value is None: return "n/a"
            elif p_value >= 1e-2: return "%.3f" % p_value
            else: return "%.3e" % p_value

        if out is None: out = sys.stdout
        print("Bijvoet pair analysis using %s distribution" %
              self.distribution,
              file=out)
        print("Bijvoet pairs (all): %i" % self.n_bijvoet_pairs, file=out)
        print("Bijvoet pairs (used): %i" % self.delta_fo2.size(), file=out)
        print("Bijvoet pairs coverage: %.2f" %
              (self.n_bijvoet_pairs / self.delta_fo2.customized_copy(
                  anomalous_flag=True).complete_set().n_bijvoet_pairs()),
              file=out)
        print("G: %s" % format_float_with_su(self.G, self.sigma_G), file=out)
        print("P2(true): %s" % format_p(self.p2_true), file=out)
        print("P2(false): %s" % format_p(self.p2_false), file=out)
        print("P3(true): %s" % format_p(self.p3_true), file=out)
        print("P3(false): %s" % format_p(self.p3_false), file=out)
        print("P3(racemic twin): %s" % format_p(self.p3_racemic_twin),
              file=out)
        print("Hooft y: %s" % format_float_with_su(self.hooft_y, self.sigma_y),
              file=out)
Пример #2
0
    def __init__(self,
                 crystal_symmetry,
                 cell_covariance_matrix=None,
                 format="coreCIF"):
        self.format = format.lower()
        assert self.format in ("corecif", "mmcif")
        if self.format == "mmcif": self.separator = '.'
        else: self.separator = '_'
        self.cif_block = model.block()
        cell_prefix = '_cell%s' % self.separator
        if crystal_symmetry.space_group() is not None:
            sym_loop = model.loop(data=OrderedDict((
                ('_space_group_symop' + self.separator + 'id',
                 range(1,
                       len(crystal_symmetry.space_group()) + 1)),
                ('_space_group_symop' + self.separator + 'operation_xyz',
                 [s.as_xyz() for s in crystal_symmetry.space_group()]))))
            self.cif_block.add_loop(sym_loop)
            sg_prefix = '_space_group%s' % self.separator
            sg_type = crystal_symmetry.space_group_info().type()
            sg = sg_type.group()
            self.cif_block[sg_prefix +
                           'crystal_system'] = sg.crystal_system().lower()
            self.cif_block[sg_prefix + 'IT_number'] = sg_type.number()
            self.cif_block[sg_prefix +
                           'name_H-M_alt'] = sg_type.lookup_symbol()
            self.cif_block[sg_prefix + 'name_Hall'] = sg_type.hall_symbol()

            sg_prefix = '_symmetry%s' % self.separator
            self.cif_block[sg_prefix +
                           'space_group_name_H-M'] = sg_type.lookup_symbol()
            self.cif_block[sg_prefix +
                           'space_group_name_Hall'] = sg_type.hall_symbol()
            self.cif_block[sg_prefix + 'Int_Tables_number'] = sg_type.number()

        if crystal_symmetry.unit_cell() is not None:
            uc = crystal_symmetry.unit_cell()
            params = list(uc.parameters())
            volume = uc.volume()
            if cell_covariance_matrix is not None:
                diag = cell_covariance_matrix.matrix_packed_u_diagonal()
                for i in range(6):
                    if diag[i] > 0:
                        params[i] = format_float_with_su(
                            params[i], math.sqrt(diag[i]))
                d_v_d_params = matrix.row(uc.d_volume_d_params())
                vcv = matrix.sqr(
                    cell_covariance_matrix.matrix_packed_u_as_symmetric())
                var_v = (d_v_d_params * vcv).dot(d_v_d_params)
                volume = format_float_with_su(volume, math.sqrt(var_v))
            a, b, c, alpha, beta, gamma = params
            self.cif_block[cell_prefix + 'length_a'] = a
            self.cif_block[cell_prefix + 'length_b'] = b
            self.cif_block[cell_prefix + 'length_c'] = c
            self.cif_block[cell_prefix + 'angle_alpha'] = alpha
            self.cif_block[cell_prefix + 'angle_beta'] = beta
            self.cif_block[cell_prefix + 'angle_gamma'] = gamma
            self.cif_block[cell_prefix + 'volume'] = volume
Пример #3
0
 def __init__(self,
              pair_asu_table,
              site_labels,
              sites_frac=None,
              sites_cart=None,
              covariance_matrix=None,
              cell_covariance_matrix=None,
              parameter_map=None,
              include_bonds_to_hydrogen=False,
              fixed_angles=None,
              conformer_indices=None,
              eps=2e-16):
     assert [sites_frac, sites_cart].count(None) == 1
     fmt = "%.1f"
     asu_mappings = pair_asu_table.asu_mappings()
     space_group_info = sgtbx.space_group_info(
         group=asu_mappings.space_group())
     unit_cell = asu_mappings.unit_cell()
     if sites_cart is not None:
         sites_frac = unit_cell.fractionalize(sites_cart)
     self.loop = model.loop(header=("_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"))
     angles = crystal.calculate_angles(
         pair_asu_table,
         sites_frac,
         covariance_matrix=covariance_matrix,
         cell_covariance_matrix=cell_covariance_matrix,
         parameter_map=parameter_map,
         conformer_indices=conformer_indices)
     for a in angles:
         i_seq, j_seq, k_seq = a.i_seqs
         if (not include_bonds_to_hydrogen
                 and (site_labels[i_seq].startswith('H')
                      or site_labels[k_seq].startswith('H'))):
             continue
         sym_code_ji = space_group_info.cif_symmetry_code(a.rt_mx_ji)
         sym_code_ki = space_group_info.cif_symmetry_code(a.rt_mx_ki)
         if sym_code_ji == "1": sym_code_ji = "."
         if sym_code_ki == "1": sym_code_ki = "."
         if (a.variance is not None and a.variance > eps
                 and not (fixed_angles is not None and
                          ((i_seq, j_seq, k_seq) in fixed_angles or
                           (k_seq, j_seq, i_seq) in fixed_angles))):
             angle = format_float_with_su(a.angle, math.sqrt(a.variance))
         else:
             angle = fmt % a.angle
         self.loop.add_row((
             site_labels[i_seq],
             site_labels[j_seq],
             site_labels[k_seq],
             angle,
             sym_code_ji,
             sym_code_ki,
         ))
     self.angles = angles.angles
     self.variances = angles.variances
Пример #4
0
 def __init__(self,
              pair_asu_table,
              site_labels,
              sites_frac=None,
              sites_cart=None,
              covariance_matrix=None,
              cell_covariance_matrix=None,
              parameter_map=None,
              include_bonds_to_hydrogen=False,
              fixed_angles=None,
              conformer_indices=None,
              eps=2e-16):
   assert [sites_frac, sites_cart].count(None) == 1
   fmt = "%.1f"
   asu_mappings = pair_asu_table.asu_mappings()
   space_group_info = sgtbx.space_group_info(group=asu_mappings.space_group())
   unit_cell = asu_mappings.unit_cell()
   if sites_cart is not None:
     sites_frac = unit_cell.fractionalize(sites_cart)
   self.loop = model.loop(header=(
     "_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"
   ))
   angles = crystal.calculate_angles(
     pair_asu_table, sites_frac,
     covariance_matrix=covariance_matrix,
     cell_covariance_matrix=cell_covariance_matrix,
     parameter_map=parameter_map,
     conformer_indices=conformer_indices)
   for a in angles:
     i_seq, j_seq, k_seq = a.i_seqs
     if (not include_bonds_to_hydrogen
         and (site_labels[i_seq].startswith('H') or
              site_labels[k_seq].startswith('H'))):
       continue
     sym_code_ji = space_group_info.cif_symmetry_code(a.rt_mx_ji)
     sym_code_ki = space_group_info.cif_symmetry_code(a.rt_mx_ki)
     if sym_code_ji == "1": sym_code_ji = "."
     if sym_code_ki == "1": sym_code_ki = "."
     if (a.variance is not None and a.variance > eps
         and not(fixed_angles is not None and
                 ((i_seq, j_seq, k_seq) in fixed_angles or
                  (k_seq, j_seq, i_seq) in fixed_angles))):
       angle = format_float_with_su(a.angle, math.sqrt(a.variance))
     else:
       angle = fmt % a.angle
     self.loop.add_row((site_labels[i_seq],
                        site_labels[j_seq],
                        site_labels[k_seq],
                        angle,
                        sym_code_ji,
                        sym_code_ki,
                        ))
   self.angles = angles.angles
   self.variances = angles.variances
Пример #5
0
  def show(self, out=None):

    def format_p(p_value):
      if p_value is None: return "n/a"
      elif p_value >= 1e-2: return "%.3f" %p_value
      else: return "%.3e" %p_value

    if out is None: out=sys.stdout
    print >> out, "Bijvoet pair analysis using %s distribution" %self.distribution
    print >> out, "Bijvoet pairs (all): %i" %self.n_bijvoet_pairs
    print >> out, "Bijvoet pairs (used): %i" %self.delta_fo2.size()
    print >> out, "Bijvoet pairs coverage: %.2f" %(
      self.n_bijvoet_pairs/self.delta_fo2.customized_copy(
        anomalous_flag=True).complete_set().n_bijvoet_pairs())
    print >> out, "G: %s" %format_float_with_su(self.G, self.sigma_G)
    print >> out,  "P2(true): %s" %format_p(self.p2_true)
    print >> out,  "P2(false): %s" %format_p(self.p2_false)
    print >> out,  "P3(true): %s" %format_p(self.p3_true)
    print >> out,  "P3(false): %s" %format_p(self.p3_false)
    print >> out,  "P3(racemic twin): %s" %format_p(self.p3_racemic_twin)
    print >> out, "Hooft y: %s" %format_float_with_su(
      self.hooft_y, self.sigma_y)
Пример #6
0
 def __init__(self,
              pair_asu_table,
              site_labels,
              sites_frac=None,
              sites_cart=None,
              covariance_matrix=None,
              cell_covariance_matrix=None,
              parameter_map=None,
              include_bonds_to_hydrogen=False,
              fixed_distances=None,
              eps=2e-16):
   assert [sites_frac, sites_cart].count(None) == 1
   fmt = "%.4f"
   asu_mappings = pair_asu_table.asu_mappings()
   space_group_info = sgtbx.space_group_info(group=asu_mappings.space_group())
   unit_cell = asu_mappings.unit_cell()
   if sites_cart is not None:
     sites_frac = unit_cell.fractionalize(sites_cart)
   self.loop = model.loop(header=(
     "_geom_bond_atom_site_label_1",
     "_geom_bond_atom_site_label_2",
     "_geom_bond_distance",
     "_geom_bond_site_symmetry_2"
   ))
   distances = crystal.calculate_distances(
     pair_asu_table, sites_frac,
     covariance_matrix=covariance_matrix,
     cell_covariance_matrix=cell_covariance_matrix,
     parameter_map=parameter_map)
   for d in distances:
     if (not include_bonds_to_hydrogen
         and (site_labels[d.i_seq].startswith('H') or
              site_labels[d.j_seq].startswith('H'))):
       continue
     if (d.variance is not None and d.variance > eps
         and not(fixed_distances is not None and
                 ((d.i_seq, d.j_seq) in fixed_distances or
                  (d.j_seq, d.i_seq) in fixed_distances))):
       distance = format_float_with_su(d.distance, math.sqrt(d.variance))
     else:
       distance = fmt % d.distance
     sym_code = space_group_info.cif_symmetry_code(d.rt_mx_ji)
     if sym_code == "1": sym_code = "."
     self.loop.add_row((site_labels[d.i_seq],
                        site_labels[d.j_seq],
                        distance,
                        sym_code))
   self.distances = distances.distances
   self.variances = distances.variances
   self.pair_counts = distances.pair_counts
Пример #7
0
 def formatted_angle(self, i_seq, j_seq, k_seq, angle, rt_mx_ki):
   if rt_mx_ki is None: rt_mx_ki = unit_mx
   if self.covariance_matrix_cart is not None:
     cov = covariance.extract_covariance_matrix_for_sites(
       flex.size_t((i_seq,j_seq,k_seq)),
       self.covariance_matrix_cart,
       self.parameter_map)
     if self.cell_covariance_matrix is not None:
       var = angle.variance(cov, self.cell_covariance_matrix, self.unit_cell,
                            (unit_mx, unit_mx, rt_mx_ki))
     else:
       var = angle.variance(cov, self.unit_cell, (unit_mx, unit_mx, rt_mx_ki))
     if var > self.eps:
       return format_float_with_su(angle.angle_model, math.sqrt(var))
   return "%.1f" %angle.angle_model
Пример #8
0
 def formatted_distance(self, i_seq, j_seq, distance, rt_mx_ji):
   if rt_mx_ji is None: rt_mx_ji = unit_mx
   if self.covariance_matrix_cart is not None:
     cov = covariance.extract_covariance_matrix_for_sites(
       flex.size_t((i_seq,j_seq)),
       self.covariance_matrix_cart,
       self.parameter_map)
     if self.cell_covariance_matrix is not None:
       var = distance.variance(
         cov, self.cell_covariance_matrix, self.unit_cell, rt_mx_ji)
     else:
       var = distance.variance(cov, self.unit_cell, rt_mx_ji)
     if var > self.eps:
       return format_float_with_su(distance.distance_model, math.sqrt(var))
   return "%.4f" %distance.distance_model
Пример #9
0
 def __init__(self,
              angles,
              space_group_info,
              site_labels,
              include_bonds_to_hydrogen=False,
              eps=2e-16):
   fmt = "%.1f"
   self.loop = model.loop(header=(
     "_geom_torsion_atom_site_label_1",
     "_geom_torsion_atom_site_label_2",
     "_geom_torsion_atom_site_label_3",
     "_geom_torsion_atom_site_label_4",
     "_geom_torsion",
     "_geom_torsion_site_symmetry_1",
     "_geom_torsion_site_symmetry_2",
     "_geom_torsion_site_symmetry_3",
     "_geom_torsion_site_symmetry_4"
   ))
   for a in angles:
     i_seq, j_seq, k_seq, l_seq = a.i_seqs
     if (not include_bonds_to_hydrogen
         and (site_labels[i_seq].startswith('H') or
              site_labels[j_seq].startswith('H') or
              site_labels[k_seq].startswith('H') or
              site_labels[l_seq].startswith('H'))):
       continue
     sym_code_i = space_group_info.cif_symmetry_code(a.rt_mxs[0])
     sym_code_j = space_group_info.cif_symmetry_code(a.rt_mxs[1])
     sym_code_k = space_group_info.cif_symmetry_code(a.rt_mxs[2])
     sym_code_l = space_group_info.cif_symmetry_code(a.rt_mxs[3])
     if sym_code_i == "1": sym_code_i = "."
     if sym_code_j == "1": sym_code_j = "."
     if sym_code_k == "1": sym_code_k = "."
     if sym_code_l == "1": sym_code_l = "."
     if a.variance is not None and a.variance > eps:
       angle = format_float_with_su(a.angle, math.sqrt(a.variance))
     else:
       angle = fmt % a.angle
     self.loop.add_row((site_labels[i_seq],
                        site_labels[j_seq],
                        site_labels[k_seq],
                        site_labels[l_seq],
                        angle,
                        sym_code_i,
                        sym_code_j,
                        sym_code_k,
                        sym_code_l,
                        ))
Пример #10
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))
Пример #11
0
def run(args):

  # adjust file names
  in_root, in_ext = os.path.splitext(args.ref_structure)

  # Check that input files exist
  for filename in (args.ref_structure, args.reflections):
    if not os.path.isfile(filename):
      raise command_line_error("No such file %s" % filename)

  # Check output file
  if args.outfile and os.path.isfile(args.outfile) and not args.overwrite:
    raise command_line_error("Output file {} exists.".format(args.outfile))

  # Load input model and reflections
  if in_ext == '.cif':
    xm = refinement.model.from_cif(model=args.ref_structure,
                                   reflections=args.reflections + '=hklf4')
  else:
    xm = refinement.model.from_shelx(ins_or_res=args.ref_structure,
                                     hkl=args.reflections,
                                     strictly_shelxl=False)

  # Look for beam energy
  if args.energy:
    energy = args.energy
    wvl = 12398 / energy
  elif args.energy_in_fname:
    estart,elength = args.energy_in_fname.split(',')
    estart = int(estart)
    elength = int(elength)
    energy = float(args.reflections[estart:estart+elength])
    wvl = 12398 / energy
  else:
    energy = None
    sys.stderr.write('''WARNING: Using beam energy from reference model. \
Inelastic form factors for \n non-refined atoms may be inaccurate.\n''')
    wvl = xm.wavelength




  # Load default anomalous scattering factors if wavelength is available
  if wvl:
    xm.xray_structure.set_inelastic_form_factors(wvl, 'sasaki')
  else:
    raise energy_missing_error()

  # At last...
  anom_sc_list=[]
  for i, sc in enumerate(xm.xray_structure.scatterers()):
    sc.flags.set_grad_site(False)
    sc.flags.set_grad_u_iso(False)
    sc.flags.set_grad_u_aniso(False)
    sc.flags.set_grad_occupancy(False)
    if sc.element_symbol().lower() == args.anom_atom.lower():
      sc.flags.set_use_fp_fdp(True)
      sc.flags.set_grad_fp(True)
      sc.flags.set_grad_fdp(True)
      anom_sc_list.append((i, sc))

  ls = xm.least_squares()
  steps = lstbx.normal_eqns_solving.levenberg_marquardt_iterations(
    non_linear_ls=ls,
    n_max_iterations=args.max_cycles,
    gradient_threshold=args.stop_deriv,
    step_threshold=args.stop_shift)

  cov = ls.covariance_matrix()
  cov_diag = cov.matrix_packed_u_diagonal()
  param_map = xm.xray_structure.parameter_map()

  # Prepare output
  result = ''

  if args.table or args.table_with_su:
    if energy: label = "{:.1f} ".format(energy)
    else: label = "{} ".format(args.reflections)
    result += label
    for i, sc in anom_sc_list:
      result += "{:6.3f} ".format(sc.fp)
    for i, sc in anom_sc_list:
      result += "{:6.3f} ".format(sc.fdp)
    result += '\n'

  if args.table_with_su:
    result += ' ' * len(label)
    for i, sc in anom_sc_list:
      sigma_fp = None
      params = param_map[i]
      if params.fp >= 0:
        sigma_fp = sqrt(cov_diag[params.fp])
        result += "{:6.3f} ".format(sigma_fp)
      else:
        result += "       "
    for i, sc in anom_sc_list:
      sigma_fdp = None
      params = param_map[i]
      if params.fdp >= 0:
        sigma_fdp = sqrt(cov_diag[params.fdp])
        result += "{:6.3f} ".format(sigma_fdp)
      else:
        result += "       "
    result += '\n'

  if not (args.table or args.table_with_su):
    from libtbx.utils import format_float_with_standard_uncertainty \
        as format_float_with_su
    result += "\n### REFINE ANOMALOUS SCATTERING FACTORS ###\n"
    result += "Reflections: {}\n\n".format(args.reflections)
    for i, sc in anom_sc_list:
      sigma_fp = sigma_fdp = None
      params = param_map[i]
      if params.fp >= 0:
        sigma_fp = sqrt(cov_diag[params.fp])
      if params.fdp >= 0:
        sigma_fdp = sqrt(cov_diag[params.fdp])
      result += "{}:\n\tfp: {}\n\tfdp: {}\n".format(
          sc.label,
          format_float_with_su(sc.fp, sigma_fp),
          format_float_with_su(sc.fdp, sigma_fdp))

  # Write to file or stdout
  if args.outfile:
    with open(args.outfile, 'w') as f:
      f.write(result)
  else:
    print(result)
Пример #12
0
 def show(self, out=None):
   if out is None: out = sys.stdout
   print("Flack x: %s" %format_float_with_su(self.flack_x, self.sigma_x), file=out)
Пример #13
0
 def show(self, out=None):
   if out is None: out = sys.stdout
   print >> out, "Flack x: %s" %format_float_with_su(self.flack_x, self.sigma_x)
Пример #14
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))
Пример #15
0
    def __init__(self, crystal_symmetry, cell_covariance_matrix=None, format="coreCIF", numeric_format="%.3f"):
        self.format = format.lower()
        assert self.format in ("corecif", "mmcif")
        if self.format == "mmcif":
            self.separator = "."
        else:
            self.separator = "_"
        assert numeric_format.startswith("%")
        self.cif_block = model.block()
        cell_prefix = "_cell%s" % self.separator
        if crystal_symmetry.space_group() is not None:
            sym_loop = model.loop(
                data=OrderedDict(
                    (
                        (
                            "_space_group_symop" + self.separator + "id",
                            range(1, len(crystal_symmetry.space_group()) + 1),
                        ),
                        (
                            "_space_group_symop" + self.separator + "operation_xyz",
                            [s.as_xyz() for s in crystal_symmetry.space_group()],
                        ),
                    )
                )
            )
            self.cif_block.add_loop(sym_loop)
            sg_prefix = "_space_group%s" % self.separator
            sg_type = crystal_symmetry.space_group_info().type()
            sg = sg_type.group()
            self.cif_block[sg_prefix + "crystal_system"] = sg.crystal_system().lower()
            self.cif_block[sg_prefix + "IT_number"] = sg_type.number()
            self.cif_block[sg_prefix + "name_H-M_alt"] = sg_type.lookup_symbol()
            self.cif_block[sg_prefix + "name_Hall"] = sg_type.hall_symbol()

            sg_prefix = "_symmetry%s" % self.separator
            self.cif_block[sg_prefix + "space_group_name_H-M"] = sg_type.lookup_symbol()
            self.cif_block[sg_prefix + "space_group_name_Hall"] = sg_type.hall_symbol()
            self.cif_block[sg_prefix + "Int_Tables_number"] = sg_type.number()

        if crystal_symmetry.unit_cell() is not None:
            uc = crystal_symmetry.unit_cell()
            params = list(uc.parameters())
            volume = uc.volume()
            if cell_covariance_matrix is not None:
                diag = cell_covariance_matrix.matrix_packed_u_diagonal()
                for i in range(6):
                    if diag[i] > 0:
                        params[i] = format_float_with_su(params[i], math.sqrt(diag[i]))
                d_v_d_params = matrix.row(uc.d_volume_d_params())
                vcv = matrix.sqr(cell_covariance_matrix.matrix_packed_u_as_symmetric())
                var_v = (d_v_d_params * vcv).dot(d_v_d_params)
                volume = format_float_with_su(volume, math.sqrt(var_v))
                numeric_format = "%s"
            a, b, c, alpha, beta, gamma = params
            self.cif_block[cell_prefix + "length_a"] = numeric_format % a
            self.cif_block[cell_prefix + "length_b"] = numeric_format % b
            self.cif_block[cell_prefix + "length_c"] = numeric_format % c
            self.cif_block[cell_prefix + "angle_alpha"] = numeric_format % alpha
            self.cif_block[cell_prefix + "angle_beta"] = numeric_format % beta
            self.cif_block[cell_prefix + "angle_gamma"] = numeric_format % gamma
            self.cif_block[cell_prefix + "volume"] = numeric_format % volume
Пример #16
0
def atom_type_cif_loop(xray_structure, format="mmcif", covariance_matrix=None):
    format = format.lower()
    assert format in ("corecif", "mmcif")
    if format == "mmcif": separator = '.'
    else: separator = '_'

    sources = {
        "it1992": "International Tables Volume C Table 6.1.1.4 (pp. 500-502)",
        "wk1995": "Waasmaier & Kirfel (1995), Acta Cryst. A51, 416-431",
    }
    inelastic_references = {
        "henke":
        "Henke, Gullikson and Davis, At. Data and Nucl. Data Tables, 1993, 54, 2",
        "sasaki": "Sasaki, KEK Report, 1989, 88-14, 1",
    }

    scattering_type_registry = xray_structure.scattering_type_registry()
    unique_gaussians = scattering_type_registry.unique_gaussians_as_list()
    max_n_gaussians = max(
        [gaussian.n_terms() for gaussian in unique_gaussians])
    max_n_gaussians = max(max_n_gaussians,
                          4)  # Need for compliance with mmcif_pdbx_v50
    # _atom_type_* loop
    header = [
        '_atom_type%ssymbol' % separator,
        '_atom_type%sscat_dispersion_real' % separator,
        '_atom_type%sscat_dispersion_imag' % separator
    ]
    header.extend([
        '_atom_type%sscat_Cromer_Mann_a%i' % (separator, i + 1)
        for i in range(max_n_gaussians)
    ])
    header.extend([
        '_atom_type%sscat_Cromer_Mann_b%i' % (separator, i + 1)
        for i in range(max_n_gaussians)
    ])
    header.extend([
        '_atom_type%sscat_Cromer_Mann_c' % separator,
        '_atom_type%sscat_source' % separator,
        '_atom_type%sscat_dispersion_source' % separator
    ])
    atom_type_loop = model.loop(header=header)
    gaussian_dict = scattering_type_registry.as_type_gaussian_dict()
    scattering_type_registry = xray_structure.scattering_type_registry()
    params = xray_structure.scattering_type_registry_params
    if covariance_matrix:
        param_map = xray_structure.parameter_map()
        covariance_diagonal = covariance_matrix.matrix_packed_u_diagonal()
    fp_fdp_table = {}
    for i_seq, sc in enumerate(xray_structure.scatterers()):
        covariance_diagonal
        sc_params = param_map[i_seq]
        fp, fdp = sc.fp, sc.fdp
        if covariance_matrix:
            if sc.flags.grad_fp():
                fp = format_float_with_su(
                    sc.fp, math.sqrt(covariance_diagonal[sc_params.fp]))
            if sc.flags.grad_fdp():
                fdp = format_float_with_su(
                    sc.fdp, math.sqrt(covariance_diagonal[sc_params.fdp]))
        fp_fdp_table.setdefault(sc.scattering_type, (fp, fdp))

    disp_source = inelastic_references.get(
        xray_structure.inelastic_form_factors_source)
    # custom?
    if disp_source is None:
        disp_source = xray_structure.inelastic_form_factors_source
    if disp_source is None:
        disp_source = "."
    for atom_type, gaussian in six.iteritems(
            scattering_type_registry.as_type_gaussian_dict()):
        scat_source = sources.get(params.table)
        if params.custom_dict and atom_type in params.custom_dict:
            scat_source = "Custom %i-Gaussian" % gaussian.n_terms()
        elif scat_source is None:
            scat_source = """\
%i-Gaussian fit: Grosse-Kunstleve RW, Sauter NK, Adams PD:
Newsletter of the IUCr Commission on Crystallographic Computing 2004, 3, 22-31."""
            scat_source = scat_source % gaussian.n_terms()
        if disp_source == ".":
            fp, fdp = ".", "."
        else:
            fp, fdp = fp_fdp_table[atom_type]
            if not isinstance(fp, str):
                fp = "%.5f" % fp
            if not isinstance(fdp, str):
                fdp = "%.5f" % fdp
        row = [atom_type, fp, fdp]
        #gaussian = gaussian_dict[sc.scattering_type]
        gaussian_a = ["%.5f" % a for a in gaussian.array_of_a()]
        gaussian_b = ["%.5f" % a for a in gaussian.array_of_b()]
        gaussian_c = "%.5f" % gaussian.c()
        gaussian_a.extend(["."] * (max_n_gaussians - gaussian.n_terms()))
        gaussian_b.extend(["."] * (max_n_gaussians - gaussian.n_terms()))
        row.extend(gaussian_a + gaussian_b)
        row.extend([gaussian_c, scat_source, disp_source])
        atom_type_loop.add_row(row)

    return atom_type_loop