IMP  2.4.0
The Integrative Modeling Platform
atom/charmm_forcefield_verbose.py

In this example, a PDB file is read in and scored using the CHARMM forcefield. It is similar to the 'charmm_forcefield.py' example, but fully works through each step of the procedure using lower-level IMP classes. This is useful if you want to customize the way in which the forcefield is applied.

1 ## \example atom/charmm_forcefield_verbose.py
2 # In this example, a PDB file is read in and scored using the CHARMM forcefield. It is similar to the 'charmm_forcefield.py' example, but fully works through each step of the procedure using lower-level IMP classes. This is useful if you want to customize the way in which the forcefield is applied.
3 #
4 
5 from __future__ import print_function
6 import IMP.atom
7 import IMP.container
8 
9 # Create an IMP model and add a heavy atom-only protein from a PDB file
10 m = IMP.kernel.Model()
11 prot = IMP.atom.read_pdb(IMP.atom.get_example_path("example_protein.pdb"), m,
13 
14 # Read in the CHARMM heavy atom topology and parameter files
16 
17 # Using the CHARMM libraries, determine the ideal topology (atoms and their
18 # connectivity) for the PDB file's primary sequence
19 topology = ff.create_topology(prot)
20 
21 # Typically this modifies the C and N termini of each chain in the protein by
22 # applying the CHARMM CTER and NTER patches. Patches can also be manually
23 # applied at this point, e.g. to add disulfide bridges.
24 topology.apply_default_patches()
25 
26 # Each atom is mapped to its CHARMM type. These are needed to look up bond
27 # lengths, Lennard-Jones radii etc. in the CHARMM parameter file. Atom types
28 # can also be manually assigned at this point using the CHARMMAtom decorator.
29 topology.add_atom_types(prot)
30 
31 # Remove any atoms that are in the PDB file but not in the topology, and add
32 # in any that are in the topology but not the PDB.
34 topology.add_missing_atoms(prot)
35 
36 # Construct Cartesian coordinates for any atoms that were added
37 topology.add_coordinates(prot)
38 
39 # Generate and return lists of bonds, angles, dihedrals and impropers for
40 # the protein. Each is a Particle in the model which defines the 2, 3 or 4
41 # atoms that are bonded, and adds parameters such as ideal bond length
42 # and force constant. Note that bonds and impropers are explicitly listed
43 # in the CHARMM topology file, while angles and dihedrals are generated
44 # automatically from an existing set of bonds. These particles only define the
45 # bonds, but do not score them or exclude them from the nonbonded list.
46 bonds = topology.add_bonds(prot)
47 angles = ff.create_angles(bonds)
48 dihedrals = ff.create_dihedrals(bonds)
49 impropers = topology.add_impropers(prot)
50 
51 # Maintain stereochemistry by scoring bonds, angles, dihedrals and impropers
52 
53 # Score all of the bonds. This is done by combining IMP 'building blocks':
54 # - A ListSingletonContainer simply manages a list of the bond particles.
55 # - A BondSingletonScore, when given a bond particle, scores the bond by
56 # calculating the distance between the two atoms it bonds, subtracting the
57 # ideal value, and weighting the result by the bond's "stiffness", such that
58 # an "ideal" bond scores zero, and bonds away from equilibrium score non-zero.
59 # It then hands off to a UnaryFunction to actually penalize the value. In
60 # this case, a Harmonic UnaryFunction is used with a mean of zero, so that
61 # bond lengths are harmonically restrained.
62 # - A SingletonsRestraint simply goes through each of the bonds in the
63 # container and scores each one in turn.
64 cont = IMP.container.ListSingletonContainer(bonds, "bonds")
66 r = IMP.container.SingletonsRestraint(bss, cont, "bonds")
67 m.add_restraint(r)
68 
69 # Score angles, dihedrals, and impropers. In the CHARMM forcefield, angles and
70 # impropers are harmonically restrained, so this is the same as for bonds.
71 # Dihedrals are scored internally by a periodic (cosine) function.
72 cont = IMP.container.ListSingletonContainer(angles, "angles")
74 r = IMP.container.SingletonsRestraint(bss, cont, "angles")
75 m.add_restraint(r)
76 
77 cont = IMP.container.ListSingletonContainer(dihedrals, "dihedrals")
79 r = IMP.container.SingletonsRestraint(bss, cont, "dihedrals")
80 m.add_restraint(r)
81 
82 cont = IMP.container.ListSingletonContainer(impropers, "impropers")
84 m.add_restraint(IMP.container.SingletonsRestraint(bss, cont, "improppers"))
85 
86 # Add non-bonded interaction (in this case, Lennard-Jones). This needs to
87 # know the radii and well depths for each atom, so add them from the forcefield
88 # (they can also be assigned manually using the XYZR or LennardJones
89 # decorators):
90 ff.add_radii(prot)
91 ff.add_well_depths(prot)
92 
93 # Get a list of all atoms in the protein, and put it in a container
94 atoms = IMP.atom.get_by_type(prot, IMP.atom.ATOM_TYPE)
96 
97 # Add a restraint for the Lennard-Jones interaction. Again, this is built from
98 # a collection of building blocks. First, a ClosePairContainer maintains a list
99 # of all pairs of Particles that are close. A StereochemistryPairFilter is used
100 # to exclude atoms from this list that are bonded to each other or are involved
101 # in an angle or dihedral (1-3 or 1-4 interaction). Then, a
102 # LennardJonesPairScore scores a pair of atoms with the Lennard-Jones potential.
103 # Finally, a PairsRestraint is used which simply applies the
104 # LennardJonesPairScore to each pair in the ClosePairContainer.
105 nbl = IMP.container.ClosePairContainer(cont, 4.0)
107 pair_filter.set_bonds(bonds)
108 pair_filter.set_angles(angles)
109 pair_filter.set_dihedrals(dihedrals)
110 nbl.add_pair_filter(pair_filter)
111 
112 sf = IMP.atom.ForceSwitch(6.0, 7.0)
114 m.add_restraint(IMP.container.PairsRestraint(ps, nbl))
115 
116 # it gets awfully slow with internal checks
117 IMP.base.set_check_level(IMP.base.USAGE)
118 
119 # Finally, evaluate the score of the whole system (without derivatives)
120 print(m.evaluate(False))