def OnUpdatePlot(self, evt): elements_str = self.elem_ctrl.GetPhilValue() elements = elements_str.replace(",", " ").split() from cctbx.eltbx import chemical_elements allowed_list = chemical_elements.proper_upper_list() for elem in elements: if (len(elem) > 2): raise Sorry( "You must enter standard chemical element symbols (H, Zn, etc.)." ) if (not elem.upper() in allowed_list): raise Sorry( "The symbol '%s' is not a recognized chemical element." % elem) range_min = self.range_min.GetPhilValue() range_max = self.range_max.GetPhilValue() range_type = self.range_choice.GetStringSelection().lower() table = self.table_choice.GetStringSelection().lower() if (range_max <= range_min): raise Sorry("The range maximum must be greater than the minimum") self.GetParent().update_plot(elements=elements, range_type=range_type, range=(range_min, range_max), table=table, include_fp=True)
def run(args, out=sys.stdout): usage_string = """ mmtbx.water_screen model.pdb data.mtz [options ...] Utility to flag waters that may actually be elemental ions, based on local environment, electron density maps, and atomic properties. """ import mmtbx.ions.identify import mmtbx.command_line cmdline = mmtbx.command_line.load_model_and_data( args=args, master_phil=master_phil(), out=out, process_pdb_file=True, set_wavelength_from_model_header=True, set_inelastic_form_factors="sasaki", create_fmodel=True, prefer_anomalous=True) fmodel = cmdline.fmodel xray_structure = cmdline.xray_structure params = cmdline.params if (params.use_svm): if (params.elements is Auto): raise Sorry( "You must specify elements to consider when using the SVM " + "prediction method.") pdb_hierarchy = cmdline.pdb_hierarchy geometry = cmdline.geometry make_header("Inspecting water molecules", out=out) manager_class = None if (params.use_svm): manager_class = mmtbx.ions.svm.manager manager = mmtbx.ions.identify.create_manager( pdb_hierarchy=pdb_hierarchy, fmodel=fmodel, geometry_restraints_manager=geometry, wavelength=params.input.wavelength, params=params, verbose=params.debug, nproc=params.nproc, log=out, manager_class=manager_class) manager.show_current_scattering_statistics(out=out) candidates = Auto if (params.elements is not Auto) and (params.elements is not None): from cctbx.eltbx import chemical_elements lu = chemical_elements.proper_upper_list() elements = params.elements.replace(",", " ") candidates = elements.split() for elem in candidates: if (elem.upper() not in lu): raise Sorry("Unrecognized element '%s'" % elem) results = manager.analyze_waters(out=out, debug=params.debug, candidates=candidates) return results, pdb_hierarchy
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("%s --> %s, B-iso = %.2f" % (id_str, atom.id_str(), atom.b), file=log) n_converted += 1 return pdb_hierarchy, n_converted
def run (args, out=sys.stdout) : usage_string = """ mmtbx.water_screen model.pdb data.mtz [options ...] Utility to flag waters that may actually be elemental ions, based on local environment, electron density maps, and atomic properties. """ import mmtbx.ions.identify import mmtbx.command_line cmdline = mmtbx.command_line.load_model_and_data( args=args, master_phil=master_phil(), out=out, process_pdb_file=True, set_wavelength_from_model_header=True, set_inelastic_form_factors="sasaki", create_fmodel=True, prefer_anomalous=True) fmodel = cmdline.fmodel xray_structure = cmdline.xray_structure params = cmdline.params if (params.use_svm) : if (params.elements is Auto) : raise Sorry("You must specify elements to consider when using the SVM "+ "prediction method.") pdb_hierarchy = cmdline.pdb_hierarchy geometry = cmdline.geometry make_header("Inspecting water molecules", out=out) manager_class = None if (params.use_svm) : manager_class = mmtbx.ions.svm.manager manager = mmtbx.ions.identify.create_manager( pdb_hierarchy = pdb_hierarchy, fmodel = fmodel, geometry_restraints_manager = geometry, wavelength = params.input.wavelength, params = params, verbose = params.debug, nproc = params.nproc, log = out, manager_class = manager_class) manager.show_current_scattering_statistics(out=out) candidates = Auto if (params.elements is not Auto) and (params.elements is not None) : from cctbx.eltbx import chemical_elements lu = chemical_elements.proper_upper_list() elements = params.elements.replace(",", " ") candidates = elements.split() for elem in candidates : if (elem.upper() not in lu) : raise Sorry("Unrecognized element '%s'" % elem) results = manager.analyze_waters( out = out, debug = params.debug, candidates = candidates) return results, pdb_hierarchy
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 validate_params(params): from cctbx.eltbx import chemical_elements all_elems = chemical_elements.proper_upper_list() if (params.element is None): raise Sorry("Element symbol not specified.") elif (not params.element.upper() in all_elems): raise Sorry("Element symbol '%s' not recognized." % params.element) if (params.n_sites is None): raise Sorry("Number of sites not specified.") if ([params.fdp, params.energy, params.wavelength].count(None) != 2): print[params.fdp, params.energy, params.wavelength] raise Sorry("Please specify either an X-ray wavelength or energy " + "(but not both), or the expected f''.") if ([params.n_res, params.mw].count(None) != 1): raise Sorry("Please specify either the number of residues or the " + "approximate molecular weight (but not both).") return True
def exercise(): lc = chemical_elements.proper_caps_list() assert len(lc) == 111 assert lc[:3] == ["H", "He", "Li"] lu = chemical_elements.proper_upper_list() assert len(lu) == len(lc) assert lu[:3] == ["H", "HE", "LI"] for c,u in zip(lc,lu): assert c.upper() == u sc = chemical_elements.proper_caps_set() assert len(sc) == len(lc) assert list(sc) == list(stl.set.stl_string(lc)) su = chemical_elements.proper_upper_set() assert len(su) == len(lc) assert list(su) == list(stl.set.stl_string(lu)) su = chemical_elements.proper_and_isotopes_upper_set() assert len(su) == len(lc) + 2 assert list(su) == list(stl.set.stl_string(lu+["D", "T"])) print("OK")
def exercise(): lc = chemical_elements.proper_caps_list() assert len(lc) == 111 assert lc[:3] == ["H", "He", "Li"] lu = chemical_elements.proper_upper_list() assert len(lu) == len(lc) assert lu[:3] == ["H", "HE", "LI"] for c,u in zip(lc,lu): assert c.upper() == u sc = chemical_elements.proper_caps_set() assert len(sc) == len(lc) assert list(sc) == list(stl.set.stl_string(lc)) su = chemical_elements.proper_upper_set() assert len(su) == len(lc) assert list(su) == list(stl.set.stl_string(lu)) su = chemical_elements.proper_and_isotopes_upper_set() assert len(su) == len(lc) + 2 assert list(su) == list(stl.set.stl_string(lu+["D", "T"])) print "OK"
def CheckFormat (self, value) : from cctbx.eltbx import chemical_elements allowed = chemical_elements.proper_upper_list() ctrl = self.GetWindow() style = ctrl.GetWxtbxStyle() elem_strings = strings.parse_strings(value) if (self.single_element) and (len(elem_strings) > 1) : raise ValueError("Only a single element may be specified here!") for elem in elem_strings : elem = elem.upper() # used in Phaser EP if (elem == "AX" or elem == "RX") and (style & WXTBX_ELEMENTS_CTRL_ALLOW_AX) : pass elif (elem in clusters) and (style & WXTBX_ELEMENTS_CTRL_ALLOW_CLUSTERS): pass elif (not elem in allowed) : raise ValueError("'%s' is not a valid element symbol." % elem) if (self.single_element) : return elem_strings[0] else : return elem_strings
def CheckFormat(self, value): from cctbx.eltbx import chemical_elements allowed = chemical_elements.proper_upper_list() + list(clusters) ctrl = self.GetWindow() style = ctrl.GetWxtbxStyle() elem_strings = strings.parse_strings(value) if (self.single_element) and (len(elem_strings) > 1): raise ValueError("Only a single element may be specified here!") for elem in elem_strings : elem = elem.upper() # used in Phaser EP if (elem == "AX" or elem == "RX") and (style & WXTBX_ELEMENTS_CTRL_ALLOW_AX): pass elif (elem in clusters) and (style & WXTBX_ELEMENTS_CTRL_ALLOW_CLUSTERS): pass elif (not elem in allowed): raise ValueError("'%s' is not a valid element symbol." % elem) if (self.single_element): return elem_strings[0] else : return elem_strings
def OnUpdatePlot (self, evt) : elements_str = self.elem_ctrl.GetPhilValue() elements = elements_str.replace(",", " ").split() from cctbx.eltbx import chemical_elements allowed_list = chemical_elements.proper_upper_list() for elem in elements : if (len(elem) > 2) : raise Sorry( "You must enter standard chemical element symbols (H, Zn, etc.).") if (not elem.upper() in allowed_list) : raise Sorry("The symbol '%s' is not a recognized chemical element." % elem) range_min = self.range_min.GetPhilValue() range_max = self.range_max.GetPhilValue() range_type = self.range_choice.GetStringSelection().lower() table = self.table_choice.GetStringSelection().lower() if (range_max <= range_min) : raise Sorry("The range maximum must be greater than the minimum") self.GetParent().update_plot( elements=elements, range_type=range_type, range=(range_min,range_max), table=table, include_fp=True)
def collect_ions(pdb_hierarchy): """ Collects a list of all ions in pdb_hierarchy. Parameters ---------- pdb_hierarchy : iotbx.pdb.hierarchy.root Returns ------- list of iotbx.pdb.hierarchy.atom """ elements = chemical_elements.proper_upper_list() ions = [] 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 elements: atoms = atom_group.atoms() assert len(atoms) == 1 for atom in atoms: ions.append(atom) return ions
def process_other(self, arg): if (len(arg) <= 2): if (arg.upper() in chemical_elements.proper_upper_list()): return iotbx.phil.parse("element=%s" % arg)
def exercise(): from mmtbx.ions import server as s import iotbx.pdb.hierarchy import iotbx.pdb from cctbx.eltbx import chemical_elements # Assert that valence parameters exist for all common ions with their # coordinating atoms for elem in [ "NA", "MG", "K", "CA", "MN", "FE", "NI", "CO", "CU", "ZN", "CD" ]: params = s.get_metal_parameters(elem) assert (len(params.allowed_coordinating_atoms) > 0) assert (params.charge is not None) for elem2 in params.allowed_coordinating_atoms: atom1 = iotbx.pdb.hierarchy.atom() atom1.name = elem atom1.element = elem atom1.charge = "+" + str(params.charge) atom2 = iotbx.pdb.hierarchy.atom() atom2.name = elem2 atom2.element = elem2 atom2.charge = "{:+}".format(s.get_charge(elem2)) assert (s.get_valence_params(atom1, atom2) != (None, None)) # Make sure we don't crash on any ion residue names for elem in chemical_elements.proper_upper_list(): s.get_element(elem) s.get_charge(elem) # Make sure we don't crash on any common residue names either from mmtbx import monomer_library from mmtbx.rotamer.rotamer_eval import mon_lib_query mon_lib_srv = monomer_library.server.server() common_residues = [ getattr(iotbx.pdb, i) for i in dir(iotbx.pdb) if i.startswith("common_residue_names") and isinstance(getattr(iotbx.pdb, i), list) ] common_atoms = { "H": -1, "C": 4, "N": -3, "O": -2, "S": -2, } for common in common_residues: for resn in common: mlq = mon_lib_query(resn, mon_lib_srv) if mlq is None: continue for atom in mlq.atom_dict().values(): elem, charge = s._get_charge_params(resname=resn, element=atom.type_symbol) from libtbx import group_args class GAtom(group_args): def fetch_labels(self): return group_args(resname=self.resname) def id_str(self): return "gatom=\"{} {}\"".format( self.resname, self.element) def charge_as_int(self): return int(self.charge) gatom = GAtom( element=atom.type_symbol, resname=resn, charge="0", ) get_charge_val, get_elem_val = s.get_charge( gatom), s.get_element(gatom) if elem in common_atoms: assert charge == common_atoms[elem] assert get_charge_val == charge assert get_elem_val == elem # And we support all waters for resn in iotbx.pdb.common_residue_names_water: assert s.get_element(resn) == "O" assert s.get_charge(resn) == -2 print "OK"
def exercise () : from mmtbx.ions import server as s import iotbx.pdb.hierarchy import iotbx.pdb from cctbx.eltbx import chemical_elements # Assert that valence parameters exist for all common ions with their # coordinating atoms for elem in ["NA", "MG", "K", "CA", "MN", "FE", "NI", "CO", "CU", "ZN", "CD"]: params = s.get_metal_parameters(elem) assert (len(params.allowed_coordinating_atoms) > 0) assert (params.charge is not None) for elem2 in params.allowed_coordinating_atoms : atom1 = iotbx.pdb.hierarchy.atom() atom1.name = elem atom1.element = elem atom1.charge = "+" + str(params.charge) atom2 = iotbx.pdb.hierarchy.atom() atom2.name = elem2 atom2.element = elem2 atom2.charge = "{:+}".format(s.get_charge(elem2)) assert (s.get_valence_params(atom1, atom2) != (None, None)) # Make sure we don't crash on any ion residue names for elem in chemical_elements.proper_upper_list(): s.get_element(elem) s.get_charge(elem) # Make sure we don't crash on any common residue names either from mmtbx import monomer_library from mmtbx.rotamer.rotamer_eval import mon_lib_query mon_lib_srv = monomer_library.server.server() common_residues = [getattr(iotbx.pdb, i) for i in dir(iotbx.pdb) if i.startswith("common_residue_names") and isinstance(getattr(iotbx.pdb, i), list)] common_atoms = { "H": -1, "C": 4, "N": -3, "O": -2, "S": -2, } for common in common_residues: for resn in common: mlq = mon_lib_query(resn, mon_lib_srv) if mlq is None: continue for atom in mlq.atom_dict().values(): elem, charge = s._get_charge_params(resname = resn, element = atom.type_symbol) from libtbx import group_args class GAtom(group_args): def fetch_labels(self): return group_args(resname = self.resname) def id_str(self): return "gatom=\"{} {}\"".format(self.resname, self.element) def charge_as_int(self): return int(self.charge) gatom = GAtom( element = atom.type_symbol, resname = resn, charge = "0", ) get_charge_val, get_elem_val = s.get_charge(gatom), s.get_element(gatom) if elem in common_atoms: assert charge == common_atoms[elem] assert get_charge_val == charge assert get_elem_val == elem # And we support all waters for resn in iotbx.pdb.common_residue_names_water: assert s.get_element(resn) == "O" assert s.get_charge(resn) == -2 print "OK"