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