IMP logo
IMP Reference Guide  develop.eb1b99edaa,2026/06/22
The Integrative Modeling Platform
optimize_em2d_with_montecarlo.py
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  super().__init__(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 
61 bb = IMP.algebra.BoundingBox3D(IMP.algebra.Vector3D(-25, -40, -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)
A Monte Carlo optimizer.
Definition: MonteCarlo.h:44
Simple 3D transformation class.
Restraints using electron microscopy 2D images (class averages).
Strings setup_from_argv(const Strings &argv, std::string description, std::string positional_description, int num_positional)
Various classes to hold sets of particles.
Rotation3D get_random_rotation_3d(const Rotation3D &center, double distance)
Pick a rotation at random near the provided one.
void add_radii(Hierarchy d, const ForceFieldParameters *ffp=get_all_atom_CHARMM_parameters(), FloatKey radius_key=FloatKey("radius"))
Add vdW radius from given force field.
std::string get_example_path(std::string file_name)
Return the full path to one of this module's example files.
Modify the transformation of a rigid body.
void write_pdb(const Selection &mhd, TextOutput out, unsigned int model=1)
Create a scoring function on a list of restraints.
GenericHierarchies get_leaves(Hierarchy mhd)
Get all the leaves of the bit of hierarchy.
Distance restraint between two particles.
void read_pdb(TextInput input, int model, Hierarchy h)
Transformation3D get_rotation_about_point(const Vector3D &point, const Rotation3D &rotation)
Generate a Transformation3D object from a rotation around a point.
Vector3D get_random_vector_in(const Cylinder3D &c)
Generate a random vector in a cylinder with uniform density.
Object used to hold a set of restraints.
Definition: RestraintSet.h:41
Class for storing model, its restraints, constraints, and particles.
Definition: Model.h:86
Select all non-alternative ATOM records.
Definition: pdb.h:128
Store a list of ParticleIndexes.
void transform(XYZ a, const algebra::Transformation3D &tr)
Apply a transformation to the particle.
Images read_images(const Strings &names, const ImageReaderWriter *rw)
std::string get_relative_path(std::string base, std::string relative)
Return a path to a file relative to another file.
Transformation3D compose(const Transformation3D &a, const Transformation3D &b)
Compose two transformations.
void set_log_level(LogLevel l)
Set the current global log level.
double get_distance(const SphereD< D > &a, const SphereD< D > &b)
Return the distance between the two spheres if they are disjoint.
Definition: SphereD.h:119
Basic functionality that is expected to be used by a wide variety of IMP users.
General purpose algebraic and geometric methods that are expected to be used by a wide variety of IMP...
Parameters used by Em2DRestraint and ProjectionFinder.
Shared optimizer state that is invoked upon commitment of new coordinates.
Functionality for loading, creating, manipulating and scoring atomic structures.
static RigidBody setup_particle(Model *m, ParticleIndex pi, ParticleIndexesAdaptor ps)
Definition: rigid_bodies.h:178
Harmonic function (symmetric about the mean)
Definition: core/Harmonic.h:27