IMP logo
IMP Reference Guide  develop.d97d4ead1f,2024/11/22
The Integrative Modeling Platform
em2d/optimize_em2d_with_montecarlo.py

Example of optimizing an EM2D restraint using Monte Carlo.

1 ## \example em2d/optimize_em2d_with_montecarlo.py
2 # Example of optimizing an EM2D restraint using Monte Carlo.
3 #
4 
5 import IMP
6 import IMP.core
7 import IMP.atom
8 import IMP.em2d
9 import IMP.algebra
10 import IMP.container
11 import sys
12 
13 IMP.setup_from_argv(sys.argv, "optimize EM2D with MonteCarlo")
14 
15 
16 # An Optimizer score to get the values of the statistics after a given set
17 # of evaluations
18 class WriteStatisticsOptimizerScore(IMP.OptimizerState):
19 
20  def __init__(self, m, restraints):
21  IMP.OptimizerState.__init__(self, m, "WriteStats")
22  self.count = 0
23  self.restraints = restraints
24 
25  def update(self):
26  if (self.count != 10):
27  self.count += 1
28  return
29  else:
30  self.count = 0
31  for r in self.restraints:
32  print(r.get_name(), r.get_last_score())
33  # for i in range(0,m.get_number_of_restraints()):
34  # r=m.get_restraint(i)
35  # print "restraint",r.get_name(),"value",r.evaluate(False)
36 
37 
38 # Get model from PDB file
39 IMP.set_log_level(IMP.TERSE)
40 m = IMP.Model()
41 prot = IMP.atom.read_pdb(
44 
45 # get the chains
46 chains = IMP.atom.get_by_type(prot, IMP.atom.CHAIN_TYPE)
47 print("there are", len(chains), "chains in 1z5s.pdb")
48 
49 # set the chains as rigid bodies
50 native_chain_centers = []
51 rigid_bodies = []
52 for c in chains:
53  atoms = IMP.core.get_leaves(c)
54  rbd = IMP.core.RigidBody.setup_particle(c, atoms)
55  rbd.set_coordinates_are_optimized(True)
56  rigid_bodies.append(rbd)
57  print("chain has", rbd.get_number_of_members(),
58  "atoms", "coordinates: ", rbd.get_coordinates())
59  native_chain_centers.append(rbd.get_coordinates())
60 
62  IMP.algebra.Vector3D(25, 40, 60))
63 # rotate and translate the chains
64 for rbd in rigid_bodies:
65  # rotation
67  transformation1 = IMP.algebra.get_rotation_about_point(
68  rbd.get_coordinates(), rotation)
69  # translation
70  transformation2 = IMP.algebra.Transformation3D(
72  # Apply
73  final_transformation = IMP.algebra.compose(
74  transformation1, transformation2)
75  IMP.core.transform(rbd, final_transformation)
76 print("Writing transformed assembly")
77 IMP.atom.write_pdb(prot, "1z5s-transformed.pdb")
78 
79 # set distance restraints measuring some distances between rigid bodies
80 # for the solution.
82  native_chain_centers[0], native_chain_centers[1])
84  m, IMP.core.Harmonic(d01, 1), chains[0], chains[1])
85 r01.set_name("distance 0-1")
87  native_chain_centers[1], native_chain_centers[2])
89  m, IMP.core.Harmonic(d12, 1), chains[1], chains[2])
90 r12.set_name("distance 1-2")
92  native_chain_centers[2], native_chain_centers[3])
94  m, IMP.core.Harmonic(d23, 1), chains[2], chains[3])
95 r23.set_name("distance 2-3")
97  native_chain_centers[3], native_chain_centers[0])
99  m, IMP.core.Harmonic(d30, 1), chains[3], chains[0])
100 r30.set_name("distance 3-0")
101 print("Distances in the solution: d01 =",
102  d01, "d12 =", d12, "d23 =", d23, "d30 =", d30)
103 
104 # set em2D restraint
106 selection_file = IMP.em2d.get_example_path("all-1z5s-projections.sel")
107 images_to_read_names = [IMP.get_relative_path(selection_file, x) for x in
108  IMP.em2d.read_selection_file(selection_file)]
109 em_images = IMP.em2d.read_images(images_to_read_names, srw)
110 print(len(em_images), "images read")
111 
112 em2d_restraint = IMP.em2d.Em2DRestraint(m)
113 apix = 1.5 # sampling rate of the available EM images
114 # resolution at which you want to generate the projections of the model
115 # In principle you want "perfect" projections, so use the highest resolution
116 resolution = 1
117 # Number of projections to use for the initial registration
118 # (coarse registration) to estimate the registration parameters
119 n_projections = 20
120 params = IMP.em2d.Em2DRestraintParameters(apix, resolution, n_projections)
121 
122 # This method (recommended) uses preprocessing of the images and projections
123 # to speed-up the registration
124 params.coarse_registration_method = IMP.em2d.ALIGN2D_PREPROCESSING
125 # use true if you want to save the projections from the model that best
126 # match the Em images
127 params.save_match_images = False
128 
129 score_function = IMP.em2d.EM2DScore()
130 em2d_restraint = IMP.em2d.Em2DRestraint(m)
131 em2d_restraint.setup(score_function, params)
132 em2d_restraint.set_images(em_images)
133 em2d_restraint.set_name("em2d restraint")
135 em2d_restraint.set_particles(container)
136 em2d_restraints_set = IMP.RestraintSet(m)
137 
138 # The next two lines are commented, because the optimization of the example
139 # is expensive. To run the full example, uncomment them (It can take a few
140 # hours).
141 # em2d_restraints_set.add_restraint(em2d_restraint)
142 # em2d_restraints_set.set_weight(1000) # weight for the em2D restraint
143 
144 # Create scoring function using all restraints
145 all_restraints = [r01, r12, r23, r30, em2d_restraints_set]
146 sf = IMP.core.RestraintsScoringFunction(all_restraints)
147 
148 # MONTECARLO OPTIMIZATION
149 s = IMP.core.MonteCarlo(m)
150 s.set_scoring_function(sf)
151 # Add movers for the rigid bodies
152 movers = []
153 for rbd in rigid_bodies:
154  movers.append(IMP.core.RigidBodyMover(m, rbd, 5, 2))
155 s.add_movers(movers)
156 print("MonteCarlo sampler has", s.get_number_of_movers(), "movers")
157 # Add an optimizer state to save intermediate configurations of the hierarchy
158 o_state = IMP.atom.WritePDBOptimizerState(chains, "intermediate-step-%1%.pdb")
159 o_state.set_period(10)
160 s.add_optimizer_state(o_state)
161 
162 ostate2 = WriteStatisticsOptimizerScore(m, all_restraints)
163 s.add_optimizer_state(ostate2)
164 
165 # Perform optimization
166 temperatures = [200, 100, 60, 40, 20, 5]
167 # 200 steps recommended for accurate optimization; a smaller number is used
168 # here for demonstration purposes
169 optimization_steps = 10
170 for T in temperatures:
171  s.set_kt(T)
172  s.optimize(optimization_steps)
173 IMP.atom.write_pdb(prot, "solution.pdb")
174 
175 
176 # Check that the optimization achieves distances close to the solution
177 print("*** End optimization ***")
178 new_centers = []
179 for rbd in rigid_bodies:
180  print("chain has", rbd.get_number_of_members(),
181  "atoms", "coordinates: ", rbd.get_coordinates())
182  new_centers.append(rbd.get_coordinates())
183 
184 d01 = IMP.algebra.get_distance(new_centers[0], new_centers[1])
185 d12 = IMP.algebra.get_distance(new_centers[1], new_centers[2])
186 d23 = IMP.algebra.get_distance(new_centers[2], new_centers[3])
187 d30 = IMP.algebra.get_distance(new_centers[3], new_centers[0])
188 print("Distances at the end of the optimization: d01 =",
189  d01, "d12 =", d12, "d23 =", d23, "d30 =", d30)