Cookbook¶
This cookbook aims to give short, self-contained, runnable code samples to perform common tasks that would be assembled into a larger script. This document is a work in progress. Our Python API is extremely extensive and we’ll continue to add to the recipes here each release.
All the code is run as part of our test suite, so should be up to date and reliable.
In almost every case, the API is more powerful than we can capture in small code samples. The online documentation or the same documentation accessed inside an interactive IPython session is often the next step for exploring each of these examples.
Cookbook Contents
IO¶
We’ll use the following helper to fix the path for the structure files used in examples below:
>>> from schrodinger.test import mmshare_data_file
Of course when working with your own structures you’ll want to supply your own path.
Read the structures in a file¶
A structure.StructureReader instance can read files in many different formats. Formats are determined by extension (e.g., mae, pdb, sdf, maegz, etc.)
It is recommended that you use the structure.StructureReader as a context manager, as below:
>>> fname = mmshare_data_file('cookbook/1fjs.maegz') # just the name of file to load
>>> from schrodinger import structure
>>> with structure.StructureReader(fname) as reader:
... for st in reader:
... pass # do something with the structure
Note
A structure reader instance is a memory efficient generator that you can only iterate through once. If you need to process the structures in a file twice, you can pull them all into memory in a list or create a new structure reader instance.
Read the structures in a file, starting at the nth structure entry¶
You can begin iterating through the structures in a file at any point. The index is 1-based.
>>> from schrodinger import structure
>>> fname = mmshare_data_file('cookbook/tautomers-form-1.maegz') # just the name of file to load
>>> with structure.StructureReader(fname, index=2) as reader:
... for st in reader:
... pass # do something with the structure
Read the first structure in a file¶
If all you need is the first structure, the read
method on the
structure.Structure class is convenient.
>>> from schrodinger import structure
>>> fname = mmshare_data_file('cookbook/1fjs.maegz') # just the name of file to load
>>> st = structure.StructureReader.read(fname)
Read the nth structure in a file¶
The read
method takes an optional (1-based) index
argument.
>>> from schrodinger import structure
>>> fname = mmshare_data_file('r_group_enumeration_library/Diverse_R-groups.maegz') # just the name of file to load
>>> n = 3 # 1-based index
>>> st = structure.StructureReader.read(fname, index=n)
Split a file name from its extension¶
Python’s splitext function doesn’t handle a few Schrödinger-specific file extensions, so we offer a utility function to make this easy.
>>> from schrodinger.utils import fileutils
>>> my_file_name = "structures.mae.gz"
>>> root, ext = fileutils.splitext(my_file_name)
>>> root, ext
('structures', '.mae.gz')
Determine the format of a file¶
Although the structure.StructureReader can read structure files with several
extensions, if you’re interested in identifying the file format
programmatically, fileutils
has a convenience function for this:
>>> file_format = fileutils.get_structure_file_format("1cmy.pdb")
>>> file_format
'pdb'
Write a structure to a file¶
>>> # First get a structure and modify it in some way
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> from schrodinger import structure
>>> st = structure.StructureReader.read(fname)
>>> del st.atom[4]
>>> modified_fname = 'modified_1cmy.mae'
>>> # Now write our modified structure to disk.
>>> with structure.StructureWriter(modified_fname) as writer:
... writer.append(st)
Write several structures to a file¶
>>> # First get several structures and modify them in some way.
>>> poses_file = mmshare_data_file('cookbook/1fjs.maegz')
>>> from schrodinger import structure
>>> with structure.StructureReader(poses_file) as reader:
... # First structure will be the receptor.
... # ligands is a list of remaining structures in the file
... receptor, *ligands = reader
>>> for st in ligands:
... pass # do something with the ligands
>>> poses_output = 'poses_output.mae'
>>> with structure.StructureWriter(poses_output) as writer:
... # First write the receptor back, then the modified ligands
... writer.append(receptor)
... writer.extend(ligands)
Sort a structure file¶
>>> from schrodinger import structure
>>> from schrodinger.structutils import sort
>>> out_fname = 'H2O.maegz'
>>> sort_key = [('r_lp_Energy', sort.DESCENDING)]
>>> file_to_sort = mmshare_data_file('r_group_enumeration_library/ligand-designer_displace-H2O.maegz')
>>> # Print out r_lp_Energy for each structure.
>>> with structure.StructureReader(file_to_sort) as reader:
... props = [st.property.get(('r_lp_Energy')) for st in reader]
>>> props[0], props[4], props[5], props[-1]
(9.43441, 7.726383, 10.386864, 1.506364)
>>> sort.sort_file(file_to_sort, sort_key, out_file_name=out_fname)
>>> # The structures in the output file should be sorted according to the property
>>> with structure.StructureReader(out_fname) as reader:
... sorted_props = [st.property.get(('r_lp_Energy')) for st in reader]
>>> sorted_props[0], sorted_props[4], sorted_props[5], sorted_props[-1]
(19.278198, 14.811804, 12.913156, -3.996859)
Read protein residue order for each chain¶
>>> from schrodinger import structure
>>> from schrodinger.protein import seqres
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> seqres = seqres.get_seqres(st)
>>> # seqres is a dictionary mapping chain names to residue names
>>> seqres['A'][1] # read the first record for chain 'A'
'ILE'
Structures¶
Get the title of a structure¶
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> st.title
'1FJS'
Get the attributes of a structure¶
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> st.atom_total
2475
>>> st.formal_charge
1
>>> st.mol_total
171
>>> st.title
'1FJS'
>>> f"{st.total_weight:.2f}"
'36062.83'
View all the current properties for an atom or structure¶
Note
- See the Property section for details
about properties. These property names match the names in a .mae formatted file.
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> st_level_properties = st.property.keys() # ct-level properties
>>> list(sorted(st_level_properties))[0:3] # view the first few
['i_m_Source_File_Index', 'i_pdb_PDB_CRYST1_z', 'r_pdb_PDB_CRYST1_a']
>>> atom = st.atom[1]
>>> atom_level_properties = atom.property.keys()
>>> list(sorted(atom_level_properties))[:3] # view the first few
['i_m_atomic_number', 'i_m_color', 'i_m_formal_charge']
Add a property to an atom¶
See the Property section for details about properties, including the required name scheme.
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> atom = st.atom[1]
>>> # A float property, hence the 'r'
>>> atom.property['r_user_energy'] = 1.0
>>> # A bool property, hence the 'b'
>>> atom.property['b_user_processed'] = True
Get the attributes of an atom¶
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> atom = st.atom[5]
>>> atom.atom_type
4
>>> atom.atomic_number
6
>>> f'{atom.atomic_weight:.2f}'
'13.02'
>>> atom.color
gray
>>> atom.formal_charge
0
>>> atom.index # warning: subject to change when the structure changes
5
>>> atom.is_halogen
False
>>> atom.isotope
0
>>> atom.molecule_number
1
>>> atom.partial_charge
0.0
>>> atom.pdbcode
'I'
>>> atom.pdbname
' CB '
>>> atom.pdbres
'ILE '
>>> atom.radius
1.8
>>> atom.resnum
16
>>> atom.secondary_structure
0
>>> atom.solvation_charge
0.0
>>> atom.temperature_factor
14.48
Get the index of an atom in a structure¶
Atom indices change when items are added and removed. For this reason it’s often preferable to work with a collection of _StructureAtom instances, which persist through changes to the structure.
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> atom = st.atom[4] # grab a _StructureAtom in the structure
>>> atom.index
4
>>> atom == st.atom[4]
True
>>> del st.atom[3]
>>> atom.index # index has been updated
3
>>> atom == st.atom[3]
True
Find all the rings in a structure, using SSSR¶
SSSR is the Smallest Set of Smallest Rings. If a structure has more than one equivalent SSSR, this function will return one of them.
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> rings = st.find_rings(st)
>>> len(rings) # A list of lists of atom indices
61
>>> rings[0] # indices of atoms in the first ring
[43, 44, 48, 49, 50, 57, 58, 59, 65, 66, 67, 69, 70, 71, 78, 79, 82, 83, 47, 46]
Find all the atoms bonded to a given atom¶
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> at = st.atom[10]
>>> bonds = list(at.bond)
>>> len(bonds)
3
>>> first_bond = bonds[0]
>>> int(first_bond.atom1), int(first_bond.atom2)
(10, 9)
Determine the type of a bond¶
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> at = st.atom[848]
>>> bonds = (at.bond for at in st.atom)
>>> bond0, bond1, bond2 = at.bond # This atom happens to have three bonds
>>> bond0.type, bond1.type, bond2.type
(<BondType.Single: 2>, <BondType.Double: 3>, <BondType.Single: 2>)
>>> at = st.atom[450] # An atom zero-order bonded to another atom
>>> [bond.type for bond in at.bond]
[<BondType.Double: 3>, <BondType.Zero: 0>]
Find all the bonds in a structure¶
st.bond lists each bond once, but iterating through bonds via atoms will hit each bond twice.
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> atoms = st.atom
>>> len([bond for at in st.atom for bond in at.bond])
4730
>>> len(st.bond)
2365
Find all the residues in a structure¶
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> # residues are available via the residue iterator
>>> residues = list(st.residue) # create a list of _Residue objects
>>> for res in st.residue:
... pass # do something interesting
Determine if a residue is connected to another residue¶
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> res1, res2, res3, *rest = st.residue
>>> res1.isConnectedToResidue(res2)
True
>>> res1.isConnectedToResidue(res3)
False
Get a residue in a structure by Chain and Resnum¶
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> res = st.findResidue('A:26')
>>> res.chain
'A'
>>> res.resnum
26
Find all the molecules in a structure¶
A structure may be composed of disconnected molecules.
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> for mol in st.molecule:
... pass # Do something with the mol
Extract a given mol into its own structure¶
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> mol = list(st.molecule)[0]
>>> mol_st = mol.extractStructure()
>>> type(mol_st).__name__
'Structure'
>>> # by default, extracted substructures do not inherit parent properties.
>>> mol_st.property.get('s_pdb_PDB_ID')
>>> mol_st_with_properties = mol.extractStructure(copy_props=True)
>>> mol_st_with_properties.property.get('s_pdb_PDB_ID')
'1FJS'
Note that the propagation of properties into the extracted mol structure is not the default.
Properties¶
Note
Properties can be viewed in the Project Table as well as interacted with programmatically.
Retrieve a property defined on a structure or atom¶
Structures and atoms have a dict-like property attribute:
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> st.property['r_pdb_PDB_CRYST1_a']
55.77
>>> atom1 = st.atom[1]
>>> atom1.property['i_pdb_seqres_index']
1
>>> 'i_pdb_seqres_index' in atom1.property
True
>>> st.property.get('does_not_exist', False)
False
Ligands¶
Find the ligands in a structure¶
The rules for ligand detection can be edited in the Maestro preferences.
>>> from schrodinger import structure
>>> from schrodinger.structutils import analyze
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> ligands = analyze.find_ligands(st)
>>> len(ligands)
1
>>> ligand = ligands[0]
>>> type(ligand)
<class 'schrodinger.structutils.analyze.Ligand'>
>>> ligand.is_covalently_bound
False
>>> ligand.pdbres
'Z34 '
>>> ligand.unique_smiles
'CN1CCNC1C1CCCC(OC2NC(OC3CC(C(N)N)CCC3O)C(F)C(N(C)CC(O)O)C2F)C1'
>>> ligand.ligand_asl
'm.n 3'
Atom Specification Language (ASL)¶
Given a residue, generate ASL for it¶
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> res, *rest = st.residue
>>> res.getAsl()
'(chain.name "A" AND res.num 16 AND res.inscode " ")'
Given a collection of residues, generate an ASL for it¶
>>> from schrodinger import structure
>>> from schrodinger.structutils import analyze
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> residues = list(st.residue)[0:25]
>>> analyze.generate_residue_asl(residues)
'((chain. A AND res.num 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40)) AND res.i " "'
Given a structure and a list of atoms in the structure, generate ASL for the atoms¶
>>> from schrodinger import structure
>>> from schrodinger.structutils import analyze
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> atoms = list(st.atom)[3:10] # atoms are 1-indexed, Python lists 0-indexed
>>> analyze.generate_asl(st, atoms)
'at.n 4-10'
Given a structure and an ASL expression, return a list of indices of matching atoms¶
>>> from schrodinger import structure
>>> from schrodinger.structutils import analyze
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> analyze.evaluate_asl(st, '(chain.name "A" AND res.num 16 AND res.inscode " ")')
[1, 2, 3, 4, 5, 6, 7, 8]
Find and delete all water atoms in a structure¶
>>> from schrodinger import structure
>>> from schrodinger.structutils import analyze
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> st.atom_total
2475
>>> water_atoms = analyze.evaluate_asl(st, 'water')
>>> len(water_atoms)
163
>>> water_atoms[:5] # current atom indices, not actual atoms
[2313, 2314, 2315, 2316, 2317]
>>> st.deleteAtoms(water_atoms)
>>> st.atom_total
2312
Find all the atoms in proteins¶
>>> from schrodinger import structure
>>> from schrodinger.structutils import analyze
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> protein_atoms = analyze.evaluate_asl(st, 'protein')
>>> len(protein_atoms)
2236
Measurement¶
Atom based measurements: distance, angle, and dihedral values¶
>>> from schrodinger import structure
>>> from schrodinger.structutils import measure
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file("cookbook/test_lig.sdf")
>>> st = structure.StructureReader.read(fname)
>>> a1 = st.atom[20]
>>> a2 = st.atom[22]
>>> a3 = st.atom[10]
>>> a4 = st.atom[41]
>>> dist = measure.measure_distance(a1, a2)
>>> round(dist, 2)
1.51
>>> angle = measure.measure_bond_angle(a1, a2, a3)
>>> round(angle, 2)
113.69
>>> dihedral = measure.measure_dihedral_angle(a1, a2, a3, a4)
>>> round(dihedral, 2)
-7.36
Note that measure_distance does not honor periodic boundary conditions.
Get all atoms within n Ångströms of a collection of atoms¶
get_atoms_close_to_subset honors periodic boundary conditions by default. Set
honor_pbc
to False
to modify this behavior.
>>> from schrodinger import structure
>>> from schrodinger.structutils import measure
>>> from schrodinger.structutils import analyze
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> # The structure contains a single ligand
>>> ligands = analyze.find_ligands(st)
>>> ligand = ligands.pop()
>>> type(ligand)
<class 'schrodinger.structutils.analyze.Ligand'>
>>> # Find all atoms within 3 Ångströms of a ligand atom
>>> close_atoms = measure.get_atoms_close_to_subset(st, ligand.atom_indexes, 3)
>>> close_atoms
[652, 1422, 1439, 1440, 1460, 2318, 2319, 2400]
Find the centroid of a structure¶
>>> from schrodinger import structure
>>> from schrodinger.structutils import transform
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file("cookbook/test_lig.sdf")
>>> st = structure.StructureReader.read(fname)
>>> centroid = transform.get_centroid(st)
>>> type(centroid)
<class 'numpy.ndarray'>
>>> [f"{item:.2f}" for item in centroid]
['7.01', '5.43', '21.46', '0.00']
Structure Comparison¶
We often want to know whether two structures are the same, but the criteria for ‘sameness’ can vary in different cases. Below are a few different ways of comparing structures.
Determine if two structures are equal¶
Structures are only ‘equal’ if they refer to the exact same object in memory.
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> st1 = structure.StructureReader.read(mmshare_data_file('cookbook/stereoisomers-form-1.maegz'))
>>> st2 = st1.copy()
>>> st1 == st2
False
Determine if two structures are identical¶
Determine if two structures are identical, i.e., do they have the same atoms in the same order with the same bonds (not counting bond color) and properties?
>>> from schrodinger import structure
>>> from schrodinger.infra import mm
>>> from schrodinger.test import mmshare_data_file
>>> st1 = structure.StructureReader.read(mmshare_data_file('cookbook/stereoisomers-form-1.maegz'))
>>> st2 = st1.copy()
>>> result = mm.mmct_ct_compare(st1, st2)
>>> assert result == mm.MMCT_SAME
Possible return values for mm.mmct_ct_compare
are:
MMCT_LESS_ATOMS
MMCT_MORE_ATOMS
MMCT_DIFF_BOND_PROPERTIES
MMCT_DIFF_ATOM_PROPERTIES
MMCT_DIFF_XYZ
MMCT_DIFF_TYPE
MMCT_DIFF_COLOR
MMCT_DIFF_BONDED
MMCT_DIFF_CHARGE1
MMCT_DIFF_CHARGE2
MMCT_DIFF_RESNUM
MMCT_DIFF_MOL_ATOM
Determine if two structures are conformers¶
Determine if two structures have the same connectivity.
The structures may have different three-dimensional orientations. The result is atom order independent.
If use_stereo=True
, chiralities and stereo chemistry labels are used for comparison.
>>> from schrodinger import structure
>>> from schrodinger import comparison
>>> from schrodinger.test import mmshare_data_file
>>> st1 = structure.StructureReader.read(mmshare_data_file('cookbook/stereoisomers-form-1.maegz'))
>>> st2 = structure.StructureReader.read(mmshare_data_file('cookbook/stereoisomers-form-2.maegz'))
>>> comparison.are_conformers(st1, st2, use_stereo=False)
True
Determine if two structures are tautomers¶
Determine if two structures have the same heavy-atom (non-Hydrogen atoms) connectivity. Bond orders may be different.
>>> from schrodinger import structure
>>> from schrodinger import comparison
>>> from schrodinger.test import mmshare_data_file
>>> st1 = structure.StructureReader.read(mmshare_data_file('cookbook/tautomers-form-1.maegz'))
>>> st2 = structure.StructureReader.read(mmshare_data_file('cookbook/tautomers-form-2.maegz'))
>>> comparison.are_tautomers(st1, st2)
True
Determine if two structures have the same geometry¶
Determine if two structures are conformers with the same geometry. Note that this assumes the structures are already consistently numbered.
>>> from schrodinger import structure
>>> from schrodinger import comparison
>>> from schrodinger.test import mmshare_data_file
>>> st1 = structure.StructureReader.read(mmshare_data_file('cookbook/tautomers-form-1.maegz'))
>>> st2 = structure.StructureReader.read(mmshare_data_file('cookbook/tautomers-form-2.maegz'))
>>> comparison.are_same_geometry(st1, st2)
False
Determine if two structures are enantiomers¶
Determine if two structures are stereoisomers that are non-identical mirror images of each other. The result is atom order independent.
>>> from schrodinger import structure
>>> from schrodinger import comparison
>>> from schrodinger.test import mmshare_data_file
>>> st1 = structure.StructureReader.read(mmshare_data_file('cookbook/stereoisomers-form-1.maegz'))
>>> st2 = structure.StructureReader.read(mmshare_data_file('cookbook/stereoisomers-form-2.maegz'))
>>> comparison.are_enantiomers(st1, st2, use_lewis_structure=True)
True
Use SMARTS to match substructures¶
adapter.evaluate_smarts
takes a structure, a SMARTS pattern, and a bool
indicating whether to uniquify results, and returns a list of lists of atom
numbers for matching substructures.
>>> from schrodinger import adapter
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> toluene = structure.StructureReader.read(mmshare_data_file('cookbook/toluene.maegz'))
>>> adapter.evaluate_smarts(toluene, 'c1ccccc1', True) # benzene SMARTS
[(1, 2, 3, 4, 5, 6)]
>>> adapter.evaluate_smarts(toluene, '[CH3]', True)
[(12,)]
Superimpose one structure on another¶
The first structure passed to superimpose is fixed; the other moves.
>>> from schrodinger import structure
>>> from schrodinger.structutils import rmsd
>>> from schrodinger.test import mmshare_data_file
>>> adenosine_fname = mmshare_data_file('cookbook/adenosine.maegz')
>>> adenosine = structure.StructureReader.read(adenosine_fname)
>>> other_fname = mmshare_data_file('cookbook/rmsd_conformers.mae.gz')
>>> other_st = structure.StructureReader.read(other_fname)
>>> comparison_atoms = [at for at in adenosine.atom if at.atomic_number !=1]
>>> other_comparison_atoms = [at for at in other_st.atom if at.atomic_number !=1]
>>> new_rmsd = rmsd.superimpose(adenosine, comparison_atoms, other_st, other_comparison_atoms, move_which=rmsd.MOLECULES)
>>> round(new_rmsd, 5)
2.09915
Modifying and Building Structures¶
Delete atoms in a structure¶
Whenever you delete more than one atom, be sure to use Structure.deleteAtoms for speed and to avoid problems with atom renumbering.
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> st.atom_total
2475
>>> some_atoms = list(st.atom)[30:40]
>>> st.deleteAtoms(some_atoms)
>>> st.atom_total
2465
Mutate a residue in a structure¶
>>> from schrodinger import structure
>>> from schrodinger.structutils import build
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> res, *_ = st.residue
>>> res.pdbres
'ILE '
>>> atom_in_res = res.getAtomIndices()[0]
>>> renumber_map = build.mutate(st, atom_in_res, 'ALA')
>>> res, *_ = st.residue
>>> res.pdbres
'ALA '
Add Hydrogens to a structure¶
>>> from schrodinger import structure
>>> from schrodinger.structutils import build
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file('cookbook/1fjs.maegz')
>>> st = structure.StructureReader.read(fname)
>>> st.atom_total
2475
>>> build.add_hydrogens(st)
>>> st.atom_total
5062
Neutralize a structure¶
>>> from schrodinger.structutils import build
>>> st = structure.StructureReader.read(mmshare_data_file("cookbook/desalt_neutralize.mae.gz"))
>>> st.atom_total
1212
>>> st.formal_charge
3
>>> neutralize_st = build.neutralize_structure(st)
>>> neutralize_st.atom_total
1209
>>> neutralize_st.formal_charge
0
Desalt a structure¶
>>> from schrodinger.structutils import build
>>> st = structure.StructureReader.read(mmshare_data_file("cookbook/desalt_neutralize.mae.gz"))
>>> st.atom_total
1212
>>> st.formal_charge
3
>>> desalted_st = build.desalt_structure(st)
>>> desalted_st.atom_total
237
>>> desalted_st.formal_charge
2
Data Conversions¶
Convert between a structure and an RDKit mol¶
>>> from schrodinger import structure
>>> from schrodinger import adapter
>>> fname = mmshare_data_file('cookbook/methane.maegz')
>>> st = structure.StructureReader.read(fname)
>>> rdkit_mol = adapter.to_rdkit(st)
>>> type(rdkit_mol)
<class 'rdkit.Chem.rdchem.Mol'>
>>> st = adapter.to_structure(rdkit_mol)
Convert a 3D structure to 2D and 1D representations¶
>>> from schrodinger import structure >>> from rdkit.Chem import rdDepictor >>> from rdkit.Chem import MolToSmiles >>> from schrodinger import adapter>>> # Create our 3d structure >>> fname = mmshare_data_file('cookbook/adenosine.maegz') # just the name of file to load >>> st = structure.StructureReader.read(fname)>>> # From 3D -> 1D >>> smiles = adapter.to_smiles(st) >>> smiles 'Nc1ncnc2c1ncn2[C@@H]1O[C@H](COP(=O)([O-])[O-])[C@@H](O)[C@H]1O'>>> # From 3D -> 1D, ignoring stereo annotations >>> smiles_no_stereo = adapter.to_smiles(st, stereo=adapter.StereoChemistry_Ignore) >>> smiles_no_stereo 'Nc1ncnc2c1ncn2C1OC(COP(=O)([O-])[O-])C(O)C1O'>>> # From 3D -> 2D >>> rdk_mol = adapter.to_rdkit(st) >>> with rdDepictor.UsingCoordGen(True): ... rdDepictor.Compute2DCoords(rdk_mol) 0
Extract 2D structure and generate 3D coordinates¶
>>> from schrodinger import adapter
>>> from rdkit.Chem import MolFromSmiles
>>> from rdkit.Chem import rdDepictor
>>> rdk_mol = MolFromSmiles('c1ccccc1')
>>> rdDepictor.Compute2DCoords(rdk_mol)
0
>>> st = adapter.to_structure(rdk_mol, True)
Generate a canonical SMILES for a structure¶
>>> from schrodinger import adapter
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file("cookbook/adenosine.maegz")
>>> st = structure.StructureReader.read(fname)
>>> smi = adapter.to_smiles(st)
>>> smi
'Nc1ncnc2c1ncn2[C@@H]1O[C@H](COP(=O)([O-])[O-])[C@@H](O)[C@H]1O'
>>> # Now generate smiles without stereo annotations
>>> isomeric_smiles = False
>>> smi_no_stereo = adapter.to_smiles(st, stereo=isomeric_smiles)
>>> smi_no_stereo
'Nc1ncnc2c1ncn2C1OC(COP(=O)([O-])[O-])C(O)C1O'
Generate SMARTS for a structure¶
>>> from schrodinger import adapter
>>> from schrodinger import structure
>>> from schrodinger.test import mmshare_data_file
>>> fname = mmshare_data_file("cookbook/adenosine.maegz")
>>> st = structure.StructureReader.read(fname)
>>> smts = adapter.to_smarts(st)
>>> smts
'[#8-]-[#15](=[#8])(-[#8-])-[#8]-[#6]-[#6@H]1-[#8]-[#6@H](-[#6@@H](-[#6@@H]-1-[#8])-[#8])-[#7]1:[#6]:[#7]:[#6]2:[#6](-[#7]):[#7]:[#6]:[#7]:[#6]:1:2'
>>> smts_no_stereo = adapter.to_smarts(st, stereo=False)
>>> smts_no_stereo
'[#8-]-[#15](=[#8])(-[#8-])-[#8]-[#6]-[#6]1-[#8]-[#6](-[#6](-[#6]-1-[#8])-[#8])-[#7]1:[#6]:[#7]:[#6]2:[#6](-[#7]):[#7]:[#6]:[#7]:[#6]:1:2'
>>> atoms = [1, 2, 3, 4, 5, 6]
>>> smts_subset_of_atoms = adapter.to_smarts(st, atoms=atoms)
>>> smts_subset_of_atoms
'[#8-]-[#15](=[#8])(-[#8-])-[#8]-[#6]'
Get a 2D structure from a SMILES representation¶
>>> from schrodinger import adapter
>>> pattern = 'CC(C)(C)[C@@H](F)C[C@H]1CC[C@H](CC1)C[C@H](Cl)C'
>>> two_d_st = adapter.to_structure(pattern)
Get a 3D structure from a SMILES representation¶
>>> from schrodinger import structure
>>> pattern = 'CC(C)(C)[C@@H](F)C[C@H]1CC[C@H](CC1)C[C@H](Cl)C'
>>> sst = adapter.smiles_to_3d_structure(pattern)