def GetRefractionIndexDeltaBeta(self): """ Refraction index, n=1-delta-i*beta. returns a tuple delta,beta""" delta=0.0 beta=0.0 density=self.GetAtomDensity() wav=W2E(self.scatt[0].nrj)*1e-10 #assume all scatterers have same list of nrjs density=self.GetAtomDensity() for s in self.scatt: z = sasaki.table(s.label).atomic_number() fp_fdp_sasaki=sasaki.table(s.element_symbol()).at_ev(self.scatt[0].nrj) delta+=wav**2*density[s.label]*re/(2*pi)*(z-s.fp0) beta +=wav**2*density[s.label]*re/(2*pi)*s.fs0 return delta,beta
def get_fp_fpp_from_sasaki (guess_ha,wavelength): from cctbx.eltbx import sasaki from decimal import Decimal, ROUND_HALF_UP if wavelength is None or guess_ha is None : return None, None try: table = sasaki.table(guess_ha) except Exception, e : return None, None
def __init__(self,label,site,occup,u,energy,fp=None,fs=None): xray.scatterer.__init__(self,label=label,site=site,occupancy=occup,u=u) self.nrj=energy if fp==None or fs==None: fp_fdp_sasaki=sasaki.table(self.element_symbol()).at_ev(self.nrj) self.fp0=fp_fdp_sasaki.fp() self.fs0=fp_fdp_sasaki.fdp() else: self.fp0=fp0 self.fs0=fs
def get_fo(atom_type=None, wavelength=None, out=sys.stdout): if not atom_type or not wavelength: raise Sorry("Please specify either f_double_prime or " + "atom_type and wavelength") from cctbx.eltbx import sasaki try: table = sasaki.table(atom_type) fo = table.atomic_number() except ValueError: raise Sorry("Unable to get scattering factors for %s" % (atom_type)) return fo
def anonymize_ions(pdb_hierarchy, log=sys.stdout): """ Convert any elemental ions in the PDB hierarchy to water, resetting the occupancy and scaling the B-factor. The atom segids will be set to the old resname. NOTE: this does not change the corresponding scatterer in the xray structure, but a new xray structure can be obtained by calling hierarchy.extract_xray_structure(crystal_symmetry). Parameters ---------- pdb_hierarchy : iotbx.pdb.hierarchy.root log : file, optional Returns ------- iotbx.pdb.hierarchy.root New pdb hierarchy with its ions anonymized int Number of atoms that were anonymized. """ ion_resnames = set(chemical_elements.proper_upper_list()) for resname in server.params["_lib_charge.resname"]: if resname not in WATER_RES_NAMES: ion_resnames.add(resname) n_converted = 0 pdb_hierarchy = pdb_hierarchy.deep_copy() for model in pdb_hierarchy.models(): for chain in model.chains(): for residue_group in chain.residue_groups(): for atom_group in residue_group.atom_groups(): if atom_group.resname.strip() in ion_resnames: atoms = atom_group.atoms() id_strs = [] for atom in atoms: elem = atom.element.strip() if elem in ["H", "D"]: atomic_number = 1 elif elem in ["HE"]: atomic_number = 2 else: atomic_number = sasaki.table(elem).atomic_number() id_strs.append(atom.id_str()) atom.segid = atom_group.resname atom.name = " O " atom.element = "O" atom.charge = "" atom.occupancy = 1.0 atom.b = atom.b * (10 / atomic_number) atom_group.resname = "HOH" for atom, id_str in zip(atoms, id_strs): print >> log, "%s --> %s, B-iso = %.2f" % (id_str, atom.id_str(), atom.b) n_converted += 1 return pdb_hierarchy, n_converted
def get_fp_fdp(atom_type=None,wavelength=None,out=sys.stdout): if not atom_type or not wavelength: raise Sorry("Please specify either f_double_prime or " + "atom_type and wavelength") from cctbx.eltbx import sasaki try: table = sasaki.table(atom_type) fp_fdp = table.at_angstrom(wavelength) except ValueError : raise Sorry("Unable to get scattering factors for %s" %(atom_type)) if fp_fdp.is_valid(): return fp_fdp else: return None
def guess_the_atom(hklin, nsites): '''Guess the atom which gives rise to the observed anomalous differences in intensities (i.e. I(+) and I(-)) though CCTBX code internally computes F(+) etc.''' mtz_obj = mtz.object(hklin) mi = mtz_obj.extract_miller_indices() sg = mtz_obj.space_group() for crystal in mtz_obj.crystals(): if crystal.name() != 'HKL_base': uc = crystal.unit_cell() n_ops = len(sg.all_ops()) v_asu = uc.volume() / n_ops mw = v_asu / 2.7 atoms = ['Cr', 'Mn', 'Fe', 'Co', 'Ni', 'Cu', 'Zn', 'Se', 'Br', 'S', 'P'] tables = [sasaki.table(atom) for atom in atoms] for crystal in mtz_obj.crystals(): if crystal.name() == 'HKL_base': continue assert(len(crystal.datasets()) == 1) for dataset in crystal.datasets(): wavelength = dataset.wavelength() energy = wavelength_energy(wavelength) mas = mtz_obj.as_miller_arrays() best_atom = None best_diff = 100.0 for ma in mas: columns = ma.info().label_string() if 'I(+)' in columns and 'I(-)' in columns: signal = ma.anomalous_signal() for j, atom in enumerate(atoms): for energy_offset in (-100.0, 0.0, 100.0): wavelength = wavelength_energy(energy + energy_offset) fdp = tables[j].at_angstrom(wavelength).fdp() p_signal = fdp * math.sqrt(nsites / mw) if math.fabs(p_signal - signal) < best_diff: best_diff = math.fabs(p_signal - signal) best_atom = atom return best_atom
def ion_anomalous_vector(scatter_env, elements=None, ratios=True, anom_peak=False): """ Creates a vector of the anomalous features of a site. These can either include the f'' / f''_expected for a variety of ion identities or the exact anomalous peak height. Parameters ---------- scatter_env : mmtbx.ions.environment.ScatteringEnvironment An object containing information about the scattering environment at a site. elements : list of str, optional List of elements to include when calculating f''_expected values. If unset, takes the list from mmtbx.ions.ALLOWED_IONS. ratios : bool, optional If False, instead of calculating ratios, just return a vector of the wavelength, f', and f''. anom_peak : bool, optional Whether to use the actual height of the anomalous map instead of the calculated f'' values. Returns ------- numpy.array of float A vector containing quantitative properties for classification. """ if elements is None: elements = [i for i in ALLOWED_IONS if i not in WATER_RES_NAMES] if scatter_env.fpp is None or scatter_env.wavelength is None: if ratios: return np.zeros(len(elements)) else: return np.zeros(1) if anom_peak: height = scatter_env.anom_density[0] else: height = scatter_env.fpp if ratios: ret = np.fromiter(( height / sasaki.table(element).at_angstrom(scatter_env.wavelength).fdp() for element in elements), float) else: ret = _flatten_list([height,]) return ret
def exercise(): t = sasaki.table("SI") assert t.label() == "Si" assert t.atomic_number() == 14 f = t.at_angstrom(2) assert f.is_valid_fp() assert f.is_valid_fdp() assert f.is_valid() from cctbx import factor_kev_angstrom assert approx_equal(f.fp(), t.at_kev(factor_kev_angstrom / 2).fp()) assert approx_equal(f.fdp(), t.at_kev(factor_kev_angstrom / 2).fdp()) assert approx_equal(f.fp(), t.at_ev(1000 * factor_kev_angstrom / 2).fp()) assert approx_equal(f.fdp(), t.at_ev(1000 * factor_kev_angstrom / 2).fdp()) c = f.as_complex() assert c.real == f.fp() assert c.imag == f.fdp() verify(t, 0.1, -0.0226, 0.0010) # wide first verify(t, 2.89, 0.3824, 1.0517) # wide last verify(t, 6.7289, -6.9495, 4.1042) # K edge t = sasaki.table("ag") assert t.label() == "Ag" assert t.atomic_number() == 47 verify(t, 3.2426, -8.6870, 14.1062) # L1 edge verify(t, 3.5169, -16.5123, 13.7723) # L2 edge verify(t, 3.6995, -29.9836, 10.5137) # L3 edge, right before edge verify(t, 3.6996, -32.2967, 3.1759) # L3 edge, right after edge n = 0 for t in sasaki.table_iterator(): n += 1 if (n == 1): assert t.label() == "Li" elif (n == 82): assert t.label() == "U" u = sasaki.table(t.label()) assert u.label() == t.label() assert n == 82
def show_plot (self, elements, range_type="wavelength", range=(0.75,2.5), n_points=100, include_fp=True, table="sasaki") : assert (range_type in ["wavelength", "energy"]) assert (table in ["sasaki", "henke"]) assert (n_points >= 10) x_min, x_max = range assert (x_max > x_min) if (range_type == "wavelength") : x_label = "Wavelength (Angstroms)" else : x_label= "Energy (eV)" table_module = None if (table == "sasaki") : from cctbx.eltbx import sasaki as table_module elif (table == "henke") : from cctbx.eltbx import henke as table_module assert (table_module is not None) increment = (x_max - x_min) / n_points x_points = [ x_min + increment*x for x in xrange(n_points+1) ] self.figure.clear() ax = self.figure.add_subplot(111) labels = [] for element in elements : try : scatt_table = table_module.table(element.upper()) except ValueError, e : raise Sorry(str(e)) fp = [] fdp = [] for x in x_points : if (range_type == "wavelength") : scatt = scatt_table.at_angstrom(x) else : scatt = scatt_table.at_ev(x) fp.append(scatt.fp()) fdp.append(scatt.fdp()) fdp_line = ax.plot(x_points, fdp)[0] ax.plot(x_points, fp, linestyle='--', color=fdp_line.get_color()) labels.append("%s f''" % scatt_table.label()) labels.append("%s f'" % scatt_table.label())
def show_scatterers(self,fpp,wave): print ("""Label f" Coordinates Occupancy """ "Uiso, Ustar as Uiso") scatterers = self.scatterers() types_used = {} for j,sc in enumerate(scatterers): sc.fdp = fpp[j] show_scatterer(sc, unit_cell=self.unit_cell()) types_used[sc.scattering_type]=None print "Tabular values for %7.1f eV (%8.5f Angstrom):"%(12398/wave,wave) from cctbx.eltbx import sasaki, henke for tag in types_used.keys(): fpp_expected_sasaki = sasaki.table(tag).at_angstrom( wave).fdp() fpp_expected_henke = henke.table(tag).at_angstrom( wave).fdp() print " %-4s"%tag, print "%6.3f" % (max(fpp_expected_sasaki,fpp_expected_henke))
def find_anomalous_scatterer_groups ( pdb_atoms, xray_structure, group_same_element=True, # XXX should this be True by default? out=None) : """ Automatic setup of anomalously scattering atoms, defined here as anything with atomic number 15 (P) or greater. Not yet accessible from phenix.refine. """ from cctbx.eltbx import sasaki from cctbx import xray if (out is None) : out = sys.stdout element_i_seqs = {} groups = [] if (out is None) : out = null_out() hd_selection = xray_structure.hd_selection() for i_seq, scatterer in enumerate(xray_structure.scatterers()) : if (hd_selection[i_seq]) : continue element = scatterer.element_symbol().strip() try : atomic_number = sasaki.table(element).atomic_number() except RuntimeError, e : print >> out, "Error for %s" % pdb_atoms[i_seq].id_str() print >> out, " " + str(e) continue if (atomic_number >= 15) : if (group_same_element) : if (not element in element_i_seqs) : element_i_seqs[element] = flex.size_t() element_i_seqs[element].append(i_seq) else : print >> out, " creating anomalous group for %s" % \ pdb_atoms[i_seq].id_str() asg = xray.anomalous_scatterer_group( iselection=flex.size_t([i_seq]), f_prime=0, f_double_prime=0, refine=["f_prime","f_double_prime"], selection_string=get_single_atom_selection_string(pdb_atoms[i_seq])) groups.append(asg)
def sort_atoms_permutation(pdb_atoms, xray_structure): """ Creates a list of atoms in pdb_atoms, sorted first by their atomic number, then by occupancy, and finally, by isotropic b-factor. Parameters ---------- pdb_atoms : iotbx.pdb.hierarchy.af_shared_atom xray_structure : cctbx.xray.structure.structure Returns ------- flex.size_t of int i_seqs of sorted atoms """ assert pdb_atoms.size() == xray_structure.scatterers().size() pdb_atoms.reset_i_seq() atoms_sorted = sorted( pdb_atoms, key=lambda x: (sasaki.table(x.element.strip().upper()).atomic_number(), x.occ, x.b), reverse=True ) sele = flex.size_t([atom.i_seq for atom in atoms_sorted]) return sele
def get_fp_fdp(atom_type=None,wavelength=None,out=sys.stdout): if not atom_type or not wavelength: raise Sorry("Please specify either f_double_prime or " + "atom_type and wavelength") from cctbx.eltbx import sasaki try: table = sasaki.table(atom_type) fp_fdp = table.at_angstrom(wavelength) except Exception: return None # if not fp_fdp.is_valid(): from cctbx.eltbx import henke try: table = henke.table(atom_type) fp_fdp = table.at_angstrom(wavelength) except Exception: return None #print "Using Henke tables for scattering factors" if fp_fdp.is_valid(): return fp_fdp else: return None
def find_and_build_ions ( manager, fmodels, model, wavelength, params, nproc=1, elements=Auto, out=None, run_ordered_solvent=False, occupancy_strategy_enabled=False, group_anomalous_strategy_enabled=False, use_svm=None) : """ Analyzes the water molecules in a structure and re-labels them as ions if they scatter and bind environments that we expect of that ion. Parameters ---------- manager : mmtbx.ions.identity.manager fmodels : mmtbx.fmodels model : mmtbx.model.manager wavelength : float params : libtbx.phil.scope_extract nproc : int, optional elements : list of str, optional out : file, optional run_ordered_solvent : bool, optional occupancy_strategy_enabled : bool, optional group_anomalous_strategy_enabled : bool, optional use_svm : bool, optional See Also -------- mmtbx.ions.identify.manager.analyze_waters """ import mmtbx.refinement.minimization from mmtbx.refinement.anomalous_scatterer_groups import \ get_single_atom_selection_string from mmtbx.refinement import anomalous_scatterer_groups import mmtbx.ions.identify import mmtbx.ions.svm from cctbx.eltbx import sasaki from cctbx import crystal from cctbx import adptbx from cctbx import xray from scitbx.array_family import flex import scitbx.lbfgs if (use_svm is None) : use_svm = getattr(params, "use_svm", False) assert (1.0 >= params.initial_occupancy >= 0) fmodel = fmodels.fmodel_xray() anomalous_flag = fmodel.f_obs().anomalous_flag() if (out is None) : out = sys.stdout model.xray_structure = fmodel.xray_structure model.xray_structure.tidy_us() pdb_hierarchy = model.pdb_hierarchy(sync_with_xray_structure=True) pdb_atoms = pdb_hierarchy.atoms() pdb_atoms.reset_i_seq() # FIXME why does B for anisotropic waters end up negative? u_iso = model.xray_structure.extract_u_iso_or_u_equiv() for i_seq, atom in enumerate(pdb_atoms) : labels = atom.fetch_labels() if (labels.resname == "HOH") and (atom.b < 0) : assert (u_iso[i_seq] >= 0) atom.b = adptbx.u_as_b(u_iso[i_seq]) if (manager is None) : manager_class = None if (use_svm) : manager_class = mmtbx.ions.svm.manager if params.svm.svm_name == "merged_high_res" : params.find_anomalous_substructure = False params.use_phaser = False manager = mmtbx.ions.identify.create_manager( pdb_hierarchy=pdb_hierarchy, geometry_restraints_manager=model.restraints_manager.geometry, fmodel=fmodel, wavelength=wavelength, params=params, nproc=nproc, verbose=params.debug, log=out, manager_class=manager_class) else : grm = model.restraints_manager.geometry connectivity = grm.shell_sym_tables[0].full_simple_connectivity() manager.update_structure( pdb_hierarchy=pdb_hierarchy, xray_structure=fmodel.xray_structure, connectivity=connectivity, log=out) manager.update_maps() model.update_anomalous_groups(out=out) make_sub_header("Analyzing water molecules", out=out) manager.show_current_scattering_statistics(out=out) anomalous_groups = [] # XXX somehow comma-separation of phil strings fields doesn't work if (isinstance(elements, list)) and (len(elements) == 1) : elements = elements[0].split(",") water_ion_candidates = manager.analyze_waters( out=out, candidates=elements) modified_iselection = flex.size_t() default_b_iso = manager.get_initial_b_iso() # Build in the identified ions for_building = [] if (use_svm) : for result in water_ion_candidates : for_building.append((result.i_seq, result.final_choice)) else : for i_seq, final_choices, two_fofc in water_ion_candidates : if (len(final_choices) == 1) : for_building.append((i_seq, final_choices[0])) skipped = [] if (len(for_building) > 0) : make_sub_header("Adding %d ions to model" % len(for_building), out) for k, (i_seq, final_choice) in enumerate(for_building) : atom = manager.pdb_atoms[i_seq] skip = False for other_i_seq, other_ion in for_building[:k] : if (other_i_seq in skipped) : continue if (((other_ion.charge > 0) and (final_choice.charge > 0)) or ((other_ion.charge < 0) and (final_choice.charge < 0))) : other_atom = manager.pdb_atoms[other_i_seq] dxyz = atom.distance(other_atom) if (dxyz < params.max_distance_between_like_charges) : print >> out, \ " %s (%s%+d) is only %.3fA from %s (%s%+d), skipping for now" %\ (atom.id_str(), final_choice.element, final_choice.charge, dxyz, other_atom.id_str(), other_ion.element, other_ion.charge) skipped.append(i_seq) skip = True break if (skip) : continue print >> out, " %s becomes %s%+d" % \ (atom.id_str(), final_choice.element, final_choice.charge) refine_adp = params.refine_ion_adp if (refine_adp == "Auto") : if (fmodel.f_obs().d_min() <= 1.5) : refine_adp = "anisotropic" elif (fmodel.f_obs().d_min() < 2.5) : atomic_number = sasaki.table(final_choice.element).atomic_number() if (atomic_number >= 19) : refine_adp = "anisotropic" # Modify the atom object - this is clumsy but they will be grouped into # a single chain at the end of refinement initial_b_iso = params.initial_b_iso if (initial_b_iso is Auto) : initial_b_iso = manager.guess_b_iso_real(i_seq) element = final_choice.element if (element == "IOD") : # FIXME element = "I" modified_atom = model.convert_atom( i_seq=i_seq, scattering_type=final_choice.scattering_type(), atom_name=element, element=element, charge=final_choice.charge, residue_name=final_choice.element, initial_occupancy=params.initial_occupancy, initial_b_iso=initial_b_iso, chain_id=params.ion_chain_id, segid="ION", refine_adp=refine_adp, refine_occupancies=False) #params.refine_ion_occupancies) if (params.refine_anomalous) and (anomalous_flag) : scatterer = model.xray_structure.scatterers()[i_seq] if (wavelength is not None) : fp_fdp_info = sasaki.table(final_choice.element).at_angstrom( wavelength) scatterer.fp = fp_fdp_info.fp() scatterer.fdp = fp_fdp_info.fdp() print >> out, " setting f'=%g, f''=%g" % (scatterer.fp, scatterer.fdp) group = xray.anomalous_scatterer_group( iselection=flex.size_t([i_seq]), f_prime=scatterer.fp, f_double_prime=scatterer.fdp, refine=["f_prime","f_double_prime"], selection_string=get_single_atom_selection_string(modified_atom), update_from_selection=True) anomalous_groups.append(group) modified_iselection.append(i_seq) if (len(modified_iselection) > 0) : scatterers = model.xray_structure.scatterers() # FIXME not sure this is actually working as desired... site_symmetry_table = model.xray_structure.site_symmetry_table() for i_seq in site_symmetry_table.special_position_indices() : scatterers[i_seq].site = crystal.correct_special_position( crystal_symmetry=model.xray_structure, special_op=site_symmetry_table.get(i_seq).special_op(), site_frac=scatterers[i_seq].site, site_label=scatterers[i_seq].label, tolerance=1.0) model.xray_structure.replace_scatterers(scatterers=scatterers) def show_r_factors () : return "r_work=%6.4f r_free=%6.4f" % (fmodel.r_work(), fmodel.r_free()) fmodel.update_xray_structure( xray_structure=model.xray_structure, update_f_calc=True, update_f_mask=True) n_anom = len(anomalous_groups) refine_anomalous = anomalous_flag and params.refine_anomalous and n_anom>0 refine_occupancies = ((params.refine_ion_occupancies or refine_anomalous) and ((not occupancy_strategy_enabled) or (model.refinement_flags.s_occupancies is None) or (len(model.refinement_flags.s_occupancies) == 0))) if (refine_anomalous) : if ((model.anomalous_scatterer_groups is not None) and (group_anomalous_strategy_enabled)) : model.anomalous_scatterer_groups.extend(anomalous_groups) refine_anomalous = False if (refine_occupancies) or (refine_anomalous) : print >> out, "" print >> out, " occupancy refinement (new ions only): start %s" % \ show_r_factors() fmodel.xray_structure.scatterers().flags_set_grads(state = False) fmodel.xray_structure.scatterers().flags_set_grad_occupancy( iselection = modified_iselection) lbfgs_termination_params = scitbx.lbfgs.termination_parameters( max_iterations = 25) minimized = mmtbx.refinement.minimization.lbfgs( restraints_manager = None, fmodels = fmodels, model = model, is_neutron_scat_table = False, lbfgs_termination_params = lbfgs_termination_params) fmodel.xray_structure.adjust_occupancy( occ_max = 1.0, occ_min = 0, selection = modified_iselection) zero_occ = [] for i_seq in modified_iselection : occ = fmodel.xray_structure.scatterers()[i_seq].occupancy if (occ == 0) : zero_occ.append(i_seq) fmodel.update_xray_structure( update_f_calc=True, update_f_mask=True) print >> out, " final %s" % \ show_r_factors() if (len(zero_occ) > 0) : print >> out, " WARNING: occupancy dropped to zero for %d atoms:" atoms = model.pdb_hierarchy().atoms() for i_seq in zero_occ : print >> out, " %s" % atoms[i_seq].id_str(suppress_segid=True) print >> out, "" if (refine_anomalous) : assert fmodel.f_obs().anomalous_flag() print >> out, " anomalous refinement (new ions only): start %s" % \ show_r_factors() fmodel.update(target_name="ls") anomalous_scatterer_groups.minimizer( fmodel=fmodel, groups=anomalous_groups) fmodel.update(target_name="ml") print >> out, " final %s" % \ show_r_factors() print >> out, "" return manager
def find_and_build_ions(manager, fmodels, model, wavelength, params, nproc=1, elements=Auto, out=None, run_ordered_solvent=False, occupancy_strategy_enabled=False, group_anomalous_strategy_enabled=False, use_svm=None): """ Analyzes the water molecules in a structure and re-labels them as ions if they scatter and bind environments that we expect of that ion. Parameters ---------- manager : mmtbx.ions.identity.manager fmodels : mmtbx.fmodels model : mmtbx.model.manager wavelength : float params : libtbx.phil.scope_extract nproc : int, optional elements : list of str, optional out : file, optional run_ordered_solvent : bool, optional occupancy_strategy_enabled : bool, optional group_anomalous_strategy_enabled : bool, optional use_svm : bool, optional See Also -------- mmtbx.ions.identify.manager.analyze_waters """ import mmtbx.refinement.minimization from mmtbx.refinement.anomalous_scatterer_groups import \ get_single_atom_selection_string from mmtbx.refinement import anomalous_scatterer_groups import mmtbx.ions.identify import mmtbx.ions.svm from cctbx.eltbx import sasaki from cctbx import crystal from cctbx import adptbx from cctbx import xray from scitbx.array_family import flex import scitbx.lbfgs if (use_svm is None): use_svm = getattr(params, "use_svm", False) assert (1.0 >= params.initial_occupancy >= 0) fmodel = fmodels.fmodel_xray() anomalous_flag = fmodel.f_obs().anomalous_flag() if (out is None): out = sys.stdout model.set_xray_structure(fmodel.xray_structure) model.get_xray_structure().tidy_us() pdb_hierarchy = model.get_hierarchy() pdb_atoms = pdb_hierarchy.atoms() pdb_atoms.reset_i_seq() # FIXME why does B for anisotropic waters end up negative? u_iso = model.get_xray_structure().extract_u_iso_or_u_equiv() for i_seq, atom in enumerate(pdb_atoms): labels = atom.fetch_labels() if (labels.resname == "HOH") and (atom.b < 0): assert (u_iso[i_seq] >= 0) atom.b = adptbx.u_as_b(u_iso[i_seq]) if (manager is None): manager_class = None if (use_svm): manager_class = mmtbx.ions.svm.manager if params.svm.svm_name == "merged_high_res": params.find_anomalous_substructure = False params.use_phaser = False manager = mmtbx.ions.identify.create_manager( pdb_hierarchy=pdb_hierarchy, geometry_restraints_manager=model.restraints_manager.geometry, fmodel=fmodel, wavelength=wavelength, params=params, nproc=nproc, verbose=params.debug, log=out, manager_class=manager_class) else: grm = model.get_restraints_manager().geometry connectivity = grm.shell_sym_tables[0].full_simple_connectivity() manager.update_structure(pdb_hierarchy=pdb_hierarchy, xray_structure=fmodel.xray_structure, connectivity=connectivity, log=out) manager.update_maps() model.update_anomalous_groups(out=out) make_sub_header("Analyzing water molecules", out=out) manager.show_current_scattering_statistics(out=out) anomalous_groups = [] # XXX somehow comma-separation of phil strings fields doesn't work if (isinstance(elements, list)) and (len(elements) == 1): elements = elements[0].split(",") water_ion_candidates = manager.analyze_waters(out=out, candidates=elements) modified_iselection = flex.size_t() default_b_iso = manager.get_initial_b_iso() # Build in the identified ions for_building = [] if (use_svm): for result in water_ion_candidates: for_building.append((result.i_seq, result.final_choice)) else: for i_seq, final_choices, two_fofc in water_ion_candidates: if (len(final_choices) == 1): for_building.append((i_seq, final_choices[0])) skipped = [] if (len(for_building) > 0): make_sub_header("Adding %d ions to model" % len(for_building), out) for k, (i_seq, final_choice) in enumerate(for_building): atom = manager.pdb_atoms[i_seq] skip = False for other_i_seq, other_ion in for_building[:k]: if (other_i_seq in skipped): continue if (((other_ion.charge > 0) and (final_choice.charge > 0)) or ((other_ion.charge < 0) and (final_choice.charge < 0))): other_atom = manager.pdb_atoms[other_i_seq] dxyz = atom.distance(other_atom) if (dxyz < params.max_distance_between_like_charges): print(" %s (%s%+d) is only %.3fA from %s (%s%+d), skipping for now" %\ (atom.id_str(), final_choice.element, final_choice.charge, dxyz, other_atom.id_str(), other_ion.element, other_ion.charge), file=out) skipped.append(i_seq) skip = True break if (skip): continue print(" %s becomes %s%+d" % \ (atom.id_str(), final_choice.element, final_choice.charge), file=out) refine_adp = params.refine_ion_adp if (refine_adp == "Auto"): if (fmodel.f_obs().d_min() <= 1.5): refine_adp = "anisotropic" elif (fmodel.f_obs().d_min() < 2.5): atomic_number = sasaki.table( final_choice.element).atomic_number() if (atomic_number >= 19): refine_adp = "anisotropic" # Modify the atom object - this is clumsy but they will be grouped into # a single chain at the end of refinement initial_b_iso = params.initial_b_iso if (initial_b_iso is Auto): initial_b_iso = manager.guess_b_iso_real(i_seq) element = final_choice.element if (element == "IOD"): # FIXME element = "I" modified_atom = model.convert_atom( i_seq=i_seq, scattering_type=final_choice.scattering_type(), atom_name=element, element=element, charge=final_choice.charge, residue_name=final_choice.element, initial_occupancy=params.initial_occupancy, initial_b_iso=initial_b_iso, chain_id=params.ion_chain_id, segid="ION", refine_adp=refine_adp, refine_occupancies=False) #params.refine_ion_occupancies) if (params.refine_anomalous) and (anomalous_flag): scatterer = model.get_xray_structure().scatterers()[i_seq] if (wavelength is not None): fp_fdp_info = sasaki.table( final_choice.element).at_angstrom(wavelength) scatterer.fp = fp_fdp_info.fp() scatterer.fdp = fp_fdp_info.fdp() print(" setting f'=%g, f''=%g" % (scatterer.fp, scatterer.fdp), file=out) group = xray.anomalous_scatterer_group( iselection=flex.size_t([i_seq]), f_prime=scatterer.fp, f_double_prime=scatterer.fdp, refine=["f_prime", "f_double_prime"], selection_string=get_single_atom_selection_string( modified_atom), update_from_selection=True) anomalous_groups.append(group) modified_iselection.append(i_seq) if (len(modified_iselection) > 0): scatterers = model.get_xray_structure().scatterers() # FIXME not sure this is actually working as desired... site_symmetry_table = model.get_xray_structure().site_symmetry_table() for i_seq in site_symmetry_table.special_position_indices(): scatterers[i_seq].site = crystal.correct_special_position( crystal_symmetry=model.get_xray_structure(), special_op=site_symmetry_table.get(i_seq).special_op(), site_frac=scatterers[i_seq].site, site_label=scatterers[i_seq].label, tolerance=1.0) model.get_xray_structure().replace_scatterers(scatterers=scatterers) model.set_xray_structure(model.get_xray_structure()) def show_r_factors(): return "r_work=%6.4f r_free=%6.4f" % (fmodel.r_work(), fmodel.r_free()) fmodel.update_xray_structure(xray_structure=model.get_xray_structure(), update_f_calc=True, update_f_mask=True) n_anom = len(anomalous_groups) refine_anomalous = anomalous_flag and params.refine_anomalous and n_anom > 0 refine_occupancies = ( (params.refine_ion_occupancies or refine_anomalous) and ((not occupancy_strategy_enabled) or (model.refinement_flags.s_occupancies is None) or (len(model.refinement_flags.s_occupancies) == 0))) if (refine_anomalous): if (model.have_anomalous_scatterer_groups() and (group_anomalous_strategy_enabled)): model.set_anomalous_scatterer_groups( model.get_anomalous_scatterer_groups() + anomalous_groups) refine_anomalous = False if (refine_occupancies) or (refine_anomalous): print("", file=out) print(" occupancy refinement (new ions only): start %s" % \ show_r_factors(), file=out) fmodel.xray_structure.scatterers().flags_set_grads(state=False) fmodel.xray_structure.scatterers().flags_set_grad_occupancy( iselection=modified_iselection) lbfgs_termination_params = scitbx.lbfgs.termination_parameters( max_iterations=25) minimized = mmtbx.refinement.minimization.lbfgs( restraints_manager=None, fmodels=fmodels, model=model, is_neutron_scat_table=False, lbfgs_termination_params=lbfgs_termination_params) fmodel.xray_structure.adjust_occupancy( occ_max=1.0, occ_min=0, selection=modified_iselection) zero_occ = [] for i_seq in modified_iselection: occ = fmodel.xray_structure.scatterers()[i_seq].occupancy if (occ == 0): zero_occ.append(i_seq) fmodel.update_xray_structure(update_f_calc=True, update_f_mask=True) print(" final %s" % \ show_r_factors(), file=out) if (len(zero_occ) > 0): print(" WARNING: occupancy dropped to zero for %d atoms:", file=out) atoms = model.get_atoms() for i_seq in zero_occ: print(" %s" % atoms[i_seq].id_str(suppress_segid=True), file=out) print("", file=out) if (refine_anomalous): assert fmodel.f_obs().anomalous_flag() print(" anomalous refinement (new ions only): start %s" % \ show_r_factors(), file=out) fmodel.update(target_name="ls") anomalous_scatterer_groups.minimizer(fmodel=fmodel, groups=anomalous_groups) fmodel.update(target_name="ml") print(" final %s" % \ show_r_factors(), file=out) print("", file=out) return manager
def examples(): # Generate space groups (in matrix/vector form) based on spacegroup number # (names are *not* a pain) # See also: http://cctbx.sourceforge.net/current/c_plus_plus/classcctbx_1_1sgtbx_1_1space__group__symbols.html#_details from cctbx import sgtbx for s in sgtbx.space_group_info(symbol="I41/amd").group(): print(s) # in "xyz" notation print(s.r().as_rational().mathematica_form(), \ s.t().as_rational().transpose().mathematica_form()) print() # now with a space group number space_group_info = sgtbx.space_group_info(number=123) space_group_info.show_summary() print() # Generate conditions for allowed reflections etc from cctbx import crystal from cctbx import miller crystal_symmetry = crystal.symmetry(unit_cell=(10, 10, 13, 90, 90, 90), space_group_info=space_group_info) miller_set = miller.build_set(crystal_symmetry=crystal_symmetry, anomalous_flag=False, d_min=4) # change the space group in order to get a few systematic absences miller_set = miller_set.customized_copy( space_group_info=sgtbx.space_group_info(symbol="I41/amd")) sys_absent_flags = miller_set.sys_absent_flags() for h, f in zip(sys_absent_flags.indices(), sys_absent_flags.data()): print(h, f) print() # try also (from the command line): libtbx.help cctbx.miller # Generate point group of space group in matrix form point_group = miller_set.space_group().build_derived_point_group() point_group_info = sgtbx.space_group_info(group=point_group) point_group_info.show_summary() for s in point_group: print(s) print() # Generate point-group matrices for given coordinate # first we have to define what we consider as special position special_position_settings = crystal.special_position_settings( crystal_symmetry=miller_set, min_distance_sym_equiv=0.5) # <<<<< here site_symmetry = special_position_settings.site_symmetry(site=(0, 0.48, 0)) print("special position operator:", site_symmetry.special_op_simplified()) print("distance to original site:", site_symmetry.distance_moved()) print("point group of the special position:") for s in site_symmetry.matrices(): print(s) print() # See also: http://cci.lbl.gov/~rwgk/my_papers/iucr/au0265_reprint.pdf # Access database for form factors from cctbx.eltbx import xray_scattering si_form_factor = xray_scattering.it1992("Si") gaussians = si_form_factor.fetch() for stol in [0, 0.01, 0.02, 0.5]: print(stol, gaussians.at_stol(stol)) print() # anomalous scattering factors: Sasaki tables from cctbx.eltbx import sasaki si_table = sasaki.table("Si") for wavelength in [0.5, 0.8, 0.9]: data = si_table.at_angstrom(wavelength) print(wavelength, data.fp(), data.fdp()) print() # anomalous scattering factors: Henke tables from cctbx.eltbx import henke si_table = henke.table("Si") for wavelength in [0.5, 0.8, 0.9]: data = si_table.at_angstrom(wavelength) print(wavelength, data.fp(), data.fdp()) print() print("OK")
def examples(): # Generate space groups (in matrix/vector form) based on spacegroup number # (names are *not* a pain) # See also: http://cctbx.sourceforge.net/current/c_plus_plus/classcctbx_1_1sgtbx_1_1space__group__symbols.html#_details from cctbx import sgtbx for s in sgtbx.space_group_info(symbol="I41/amd").group(): print s # in "xyz" notation print s.r().as_rational().mathematica_form(), \ s.t().as_rational().transpose().mathematica_form() print # now with a space group number space_group_info = sgtbx.space_group_info(number=123) space_group_info.show_summary() print # Generate conditions for allowed reflections etc from cctbx import crystal from cctbx import miller crystal_symmetry = crystal.symmetry( unit_cell=(10,10,13,90,90,90), space_group_info=space_group_info) miller_set = miller.build_set( crystal_symmetry=crystal_symmetry, anomalous_flag=False, d_min=4) # change the space group in order to get a few systematic absences miller_set = miller_set.customized_copy( space_group_info=sgtbx.space_group_info(symbol="I41/amd")) sys_absent_flags = miller_set.sys_absent_flags() for h,f in zip(sys_absent_flags.indices(), sys_absent_flags.data()): print h, f print # try also (from the command line): libtbx.help cctbx.miller # Generate point group of space group in matrix form point_group = miller_set.space_group().build_derived_point_group() point_group_info = sgtbx.space_group_info(group=point_group) point_group_info.show_summary() for s in point_group: print s print # Generate point-group matrices for given coordinate # first we have to define what we consider as special position special_position_settings = crystal.special_position_settings( crystal_symmetry=miller_set, min_distance_sym_equiv=0.5) # <<<<< here site_symmetry = special_position_settings.site_symmetry( site=(0,0.48,0)) print "special position operator:", site_symmetry.special_op_simplified() print "distance to original site:", site_symmetry.distance_moved() print "point group of the special position:" for s in site_symmetry.matrices(): print s print # See also: http://cci.lbl.gov/~rwgk/my_papers/iucr/au0265_reprint.pdf # Access database for form factors from cctbx.eltbx import xray_scattering si_form_factor = xray_scattering.it1992("Si") gaussians = si_form_factor.fetch() for stol in [0, 0.01, 0.02, 0.5]: print stol, gaussians.at_stol(stol) print # anomalous scattering factors: Sasaki tables from cctbx.eltbx import sasaki si_table = sasaki.table("Si") for wavelength in [0.5, 0.8, 0.9]: data = si_table.at_angstrom(wavelength) print wavelength, data.fp(), data.fdp() print # anomalous scattering factors: Henke tables from cctbx.eltbx import henke si_table = henke.table("Si") for wavelength in [0.5, 0.8, 0.9]: data = si_table.at_angstrom(wavelength) print wavelength, data.fp(), data.fdp() print print "OK"