IMP logo
IMP Reference Guide  develop.63b38c487d,2024/12/22
The Integrative Modeling Platform
refine_fft.py
1 #!/usr/bin/env python
2 
3 import math
4 import IMP.multifit
5 import IMP.atom
6 import IMP.em
7 from IMP import ArgumentParser
8 
9 __doc__ = "Refine fitting subunits into a density map with FFT."
10 
11 
12 class Fitter:
13 
14  def __init__(
15  self,
16  em_map,
17  spacing,
18  resolution,
19  origin,
20  density_threshold,
21  pdb,
22  fits_fn,
23  angle,
24  num_fits,
25  angles_per_voxel,
26  max_trans,
27  max_angle,
28  ref_pdb=''):
29  self.em_map = em_map
30  self.spacing = spacing
31  self.resolution = resolution
32  self.threshold = density_threshold
33  self.originx = origin[0]
34  self.originy = origin[1]
35  self.originz = origin[2]
36  self.pdb = pdb
37  self.fits_fn = fits_fn
38  self.angle = angle
39  self.num_fits = num_fits
40  self.angles_per_voxel = angles_per_voxel
41  self.max_trans = max_trans
42  self.max_angle = max_angle
43  self.ref_pdb = ref_pdb
44 
45  # TODO - update function
46  def run_local_fitting(self, mol2fit, rb, initial_transformation):
47  print("resolution is:", self.resolution)
48  dmap = IMP.em.read_map(self.em_map)
49  dmap.get_header().set_resolution(self.resolution)
50  dmap.update_voxel_size(self.spacing)
51  dmap.set_origin(IMP.algebra.Vector3D(self.originx,
52  self.originy,
53  self.originz))
54  dmap.set_was_used(True)
55  dmap.get_header().show()
56  mh_xyz = IMP.core.XYZs(IMP.core.get_leaves(mol2fit))
58  ff.set_was_used(True)
59  #
60  do_cluster_fits = True
61  max_clustering_translation = 3
62  max_clustering_rotation = 5
63  num_fits_to_report = 100
64  #
65  fits = ff.do_local_fitting(dmap, self.threshold, mol2fit,
66  self.angle / 180.0 * math.pi,
67  self.max_angle / 180.0 * math.pi,
68  self.max_trans, num_fits_to_report,
69  do_cluster_fits, self.angles_per_voxel,
70  max_clustering_translation,
71  max_clustering_rotation)
72  fits.set_was_used(True)
73  final_fits = fits.best_fits_
74  if self.ref_pdb != '':
75  ref_mh = IMP.atom.read_pdb(self.ref_pdb, mdl) # noqa: F821
76  ref_mh_xyz = IMP.core.XYZs(IMP.core.get_leaves(ref_mh))
77  cur_low = [1e4, 0]
78  for i, fit in enumerate(final_fits):
79  fit.set_index(i)
80  if self.ref_pdb != '':
81  trans = fit.get_fit_transformation()
82  IMP.atom.transform(mol2fit, trans)
83  rmsd = IMP.atom.get_rmsd(mh_xyz, ref_mh_xyz)
84  if rmsd < cur_low[0]:
85  cur_low[0] = rmsd
86  cur_low[1] = i
87  fit.set_rmsd_to_reference(rmsd)
88  IMP.atom.transform(mol2fit, trans.get_inverse())
89  fit.set_fit_transformation(trans * initial_transformation)
90  if self.ref_pdb != '':
91  print('from all fits, lowest rmsd to ref:', cur_low)
92  IMP.multifit.write_fitting_solutions(self.fits_fn, final_fits)
93 
94 
95 def do_work(f):
96  f.run()
97 
98 
99 def parse_args():
100  desc = """
101 Fit subunits locally around a combination solution with FFT."""
102  p = ArgumentParser(description=desc)
103  p.add_argument("-a", "--angle", dest="angle", type=float, default=5,
104  help="angle delta (degrees) for FFT rotational "
105  "search (default 5)")
106 
107  p.add_argument("-n", "--num", dest="num", type=int, default=100,
108  help="Number of fits to report (default 100)")
109 
110  p.add_argument("-v", "--angle_voxel", dest="angle_voxel", type=int,
111  default=10,
112  help="Number of angles to keep per voxel (default 10)")
113 
114  p.add_argument("-t", "--max_trans", dest="max_trans", type=float,
115  default=10.,
116  help="maximum translational search in A (default 10)")
117 
118  p.add_argument("-m", "--max_angle", dest="max_angle", type=float,
119  default=30.,
120  help="maximum angular search in degrees (default 50)")
121  p.add_argument("assembly_file", help="assembly file name")
122  p.add_argument("ref_assembly_file", help="refined assembly file name")
123  p.add_argument("proteomics_file", help="proteomics file name")
124  p.add_argument("mapping_file", help="mapping file name")
125  p.add_argument("combinations_file", help="combinations file name")
126  p.add_argument("combination_index", type=int,
127  help="number of the combination to read from the "
128  "combinations file")
129  return p.parse_args()
130 
131 
132 def run(
133  asmb_fn,
134  asmb_refined_fn,
135  proteomics_fn,
136  mapping_fn,
137  combs_fn,
138  comb_ind,
139  options):
140  # get rmsd for subunits
141  mdl1 = IMP.Model()
142  mdl2 = IMP.Model()
143  combs = IMP.multifit.read_paths(combs_fn)
144  asmb_input = IMP.multifit.read_settings(asmb_fn)
145  asmb_input.set_was_used(True)
146  asmb_refined_input = IMP.multifit.read_settings(asmb_refined_fn)
147  asmb_refined_input.set_was_used(True)
148  prot_data = IMP.multifit.read_proteomics_data(proteomics_fn)
149  mapping_data = IMP.multifit.read_protein_anchors_mapping(prot_data,
150  mapping_fn)
151  ensmb = IMP.multifit.load_ensemble(asmb_input, mdl1, mapping_data)
152  ensmb.set_was_used(True)
153  mhs = ensmb.get_molecules()
154 
155  ensmb_ref = IMP.multifit.load_ensemble(asmb_input, mdl2, mapping_data)
156  ensmb_ref.set_was_used(True)
157  _ = ensmb_ref.get_molecules()
158 
159  ensmb.load_combination(combs[comb_ind])
160 
161  em_map = asmb_input.get_assembly_header().get_dens_fn()
162  resolution = asmb_input.get_assembly_header().get_resolution()
163  spacing = asmb_input.get_assembly_header().get_spacing()
164  origin = asmb_input.get_assembly_header().get_origin()
165 
166  rbs_ref = ensmb_ref.get_rigid_bodies()
167  rbs = ensmb.get_rigid_bodies()
168 
169  for i, mh in enumerate(mhs):
170  fits_fn = asmb_refined_input.get_component_header(
171  i).get_transformations_fn()
172 
173  # todo - get the initial transformation
174  rb_ref = rbs_ref[i]
175  rb = rbs[i]
176 
177  initial_transformation = \
179  rb_ref.get_reference_frame(), rb.get_reference_frame())
180 
181  pdb_fn = asmb_input.get_component_header(i).get_filename()
182 
183  f = Fitter(em_map, spacing, resolution, origin,
184  asmb_input.get_assembly_header().get_threshold(), pdb_fn,
185  fits_fn, options.angle, options.num, options.angle_voxel,
186  options.max_trans, options.max_angle)
187  f.run_local_fitting(mh, rb, initial_transformation)
188 
189 
190 def main():
191  args = parse_args()
192  run(args.assembly_file, args.ref_assembly_file, args.proteomics_file,
193  args.mapping_file, args.combinations_file, args.combination_index,
194  args)
195 
196 
197 if __name__ == "__main__":
198  main()
Fit a molecule inside its density by local or global FFT.
SettingsData * read_settings(const char *filename)
GenericHierarchies get_leaves(Hierarchy mhd)
Get all the leaves of the bit of hierarchy.
Transformation3D get_transformation_from_first_to_second(const ReferenceFrame3D &a, const ReferenceFrame3D &b)
ProteinsAnchorsSamplingSpace read_protein_anchors_mapping(multifit::ProteomicsData *prots, const std::string &anchors_prot_map_fn, int max_paths=INT_MAX)
void read_pdb(TextInput input, int model, Hierarchy h)
Class for storing model, its restraints, constraints, and particles.
Definition: Model.h:86
double get_rmsd(const Selection &s0, const Selection &s1)
void transform(Hierarchy h, const algebra::Transformation3D &tr)
Transform a hierarchy. This is aware of rigid bodies.
def __init__
input a list of particles, the slope and theta of the sigmoid potential theta is the cutoff distance ...
Ensemble * load_ensemble(multifit::SettingsData *sd, Model *mdl, const ProteinsAnchorsSamplingSpace &mapping_data)
Fitting atomic structures into a cryo-electron microscopy density map.
Basic utilities for handling cryo-electron microscopy 3D density maps.
void write_fitting_solutions(const char *fitting_fn, const FittingSolutionRecords &fit_sols, int num_sols=-1)
Write fitting solutions to a file.
ProteomicsData * read_proteomics_data(const char *proteomics_fn)
Proteomics reader.
IntsList read_paths(const char *txt_filename, int max_paths=INT_MAX)
Read paths.
VectorD< 3 > Vector3D
Definition: VectorD.h:408
double get_resolution(Model *m, ParticleIndex pi)
Estimate the resolution of the hierarchy as used by Representation.
Functionality for loading, creating, manipulating and scoring atomic structures.