1 """@namespace IMP.pmi.macros
2 Protocols for sampling structures and analyzing them.
5 from __future__
import print_function, division
18 from operator
import itemgetter
19 from collections
import defaultdict
27 class _RMFRestraints(object):
28 """All restraints that are written out to the RMF file"""
29 def __init__(self, model, user_restraints):
31 self._user_restraints = user_restraints
if user_restraints
else []
34 return (len(self._user_restraints)
35 + self._rmf_rs.get_number_of_restraints())
39 __nonzero__ = __bool__
41 def __getitem__(self, i):
42 class FakePMIWrapper(object):
43 def __init__(self, r):
44 self.r = IMP.RestraintSet.get_from(r)
45 get_restraint =
lambda self: self.r
46 lenuser = len(self._user_restraints)
48 return self._user_restraints[i]
49 elif 0 <= i - lenuser < self._rmf_rs.get_number_of_restraints():
50 r = self._rmf_rs.get_restraint(i - lenuser)
51 return FakePMIWrapper(r)
53 raise IndexError(
"Out of range")
57 """A macro to help setup and run replica exchange.
58 Supports Monte Carlo and molecular dynamics.
59 Produces trajectory RMF files, best PDB structures,
60 and output stat files.
66 monte_carlo_sample_objects=
None,
67 molecular_dynamics_sample_objects=
None,
69 rmf_output_objects=
None,
70 crosslink_restraints=
None,
71 monte_carlo_temperature=1.0,
72 simulated_annealing=
False,
73 simulated_annealing_minimum_temperature=1.0,
74 simulated_annealing_maximum_temperature=2.5,
75 simulated_annealing_minimum_temperature_nframes=100,
76 simulated_annealing_maximum_temperature_nframes=100,
77 replica_exchange_minimum_temperature=1.0,
78 replica_exchange_maximum_temperature=2.5,
79 replica_exchange_swap=
True,
81 number_of_best_scoring_models=500,
84 molecular_dynamics_steps=10,
85 molecular_dynamics_max_time_step=1.0,
86 number_of_frames=1000,
87 save_coordinates_mode=
"lowest_temperature",
88 nframes_write_coordinates=1,
89 write_initial_rmf=
True,
90 initial_rmf_name_suffix=
"initial",
91 stat_file_name_suffix=
"stat",
92 best_pdb_name_suffix=
"model",
94 do_create_directories=
True,
95 global_output_directory=
"./",
98 replica_stat_file_suffix=
"stat_replica",
99 em_object_for_rmf=
None,
101 replica_exchange_object=
None,
104 @param model The IMP model
105 @param representation PMI.representation.Representation object
106 (or list of them, for multi-state modeling)
107 @param root_hier Instead of passing Representation, pass the System hierarchy
108 @param monte_carlo_sample_objects Objects for MC sampling; a list of
109 structural components (generally the representation) that will
110 be moved and restraints with parameters that need to
112 For PMI2: just pass flat list of movers
113 @param molecular_dynamics_sample_objects Objects for MD sampling
114 For PMI2: just pass flat list of particles
115 @param output_objects A list of structural objects and restraints
116 that will be included in output (ie, statistics "stat" files). Any object
117 that provides a get_output() method can be used here. If None is passed
118 the macro will not write stat files.
119 @param rmf_output_objects A list of structural objects and restraints
120 that will be included in rmf. Any object
121 that provides a get_output() method can be used here.
122 @param crosslink_restraints List of cross-link restraints that will
123 be included in output RMF files (for visualization).
124 @param monte_carlo_temperature MC temp (may need to be optimized
125 based on post-sampling analysis)
126 @param simulated_annealing If True, perform simulated annealing
127 @param simulated_annealing_minimum_temperature Should generally be
128 the same as monte_carlo_temperature.
129 @param simulated_annealing_minimum_temperature_nframes Number of
130 frames to compute at minimum temperature.
131 @param simulated_annealing_maximum_temperature_nframes Number of
133 temps > simulated_annealing_maximum_temperature.
134 @param replica_exchange_minimum_temperature Low temp for REX; should
135 generally be the same as monte_carlo_temperature.
136 @param replica_exchange_maximum_temperature High temp for REX
137 @param replica_exchange_swap Boolean, enable disable temperature
139 @param num_sample_rounds Number of rounds of MC/MD per cycle
140 @param number_of_best_scoring_models Number of top-scoring PDB models
141 to keep around for analysis
142 @param monte_carlo_steps Number of MC steps per round
143 @param self_adaptive self adaptive scheme for monte carlo movers
144 @param molecular_dynamics_steps Number of MD steps per round
145 @param molecular_dynamics_max_time_step Max time step for MD
146 @param number_of_frames Number of REX frames to run
147 @param save_coordinates_mode string: how to save coordinates.
148 "lowest_temperature" (default) only the lowest temperatures is saved
149 "25th_score" all replicas whose score is below the 25th percentile
150 "50th_score" all replicas whose score is below the 50th percentile
151 "75th_score" all replicas whose score is below the 75th percentile
152 @param nframes_write_coordinates How often to write the coordinates
154 @param write_initial_rmf Write the initial configuration
155 @param global_output_directory Folder that will be created to house
157 @param test_mode Set to True to avoid writing any files, just test one frame.
164 self.output_objects = output_objects
165 self.rmf_output_objects=rmf_output_objects
166 self.representation = representation
168 if isinstance(representation, list):
169 self.is_multi_state =
True
170 self.root_hiers = [r.prot
for r
in representation]
171 self.vars[
"number_of_states"] = len(representation)
173 self.is_multi_state =
False
174 self.root_hier = representation.prot
175 self.vars[
"number_of_states"] = 1
177 and root_hier.get_name() ==
'System':
179 if self.output_objects
is not None:
181 if self.rmf_output_objects
is not None:
183 self.root_hier = root_hier
184 states = IMP.atom.get_by_type(root_hier,IMP.atom.STATE_TYPE)
185 self.vars[
"number_of_states"] = len(states)
187 self.root_hiers = states
188 self.is_multi_state =
True
190 self.root_hier = root_hier
191 self.is_multi_state =
False
193 raise Exception(
"Must provide representation or System hierarchy (root_hier)")
195 self._rmf_restraints = _RMFRestraints(model, crosslink_restraints)
196 self.em_object_for_rmf = em_object_for_rmf
197 self.monte_carlo_sample_objects = monte_carlo_sample_objects
198 self.vars[
"self_adaptive"]=self_adaptive
199 if sample_objects
is not None:
200 self.monte_carlo_sample_objects+=sample_objects
201 self.molecular_dynamics_sample_objects=molecular_dynamics_sample_objects
202 self.replica_exchange_object = replica_exchange_object
203 self.molecular_dynamics_max_time_step = molecular_dynamics_max_time_step
204 self.vars[
"monte_carlo_temperature"] = monte_carlo_temperature
206 "replica_exchange_minimum_temperature"] = replica_exchange_minimum_temperature
208 "replica_exchange_maximum_temperature"] = replica_exchange_maximum_temperature
209 self.vars[
"replica_exchange_swap"] = replica_exchange_swap
210 self.vars[
"simulated_annealing"]=\
212 self.vars[
"simulated_annealing_minimum_temperature"]=\
213 simulated_annealing_minimum_temperature
214 self.vars[
"simulated_annealing_maximum_temperature"]=\
215 simulated_annealing_maximum_temperature
216 self.vars[
"simulated_annealing_minimum_temperature_nframes"]=\
217 simulated_annealing_minimum_temperature_nframes
218 self.vars[
"simulated_annealing_maximum_temperature_nframes"]=\
219 simulated_annealing_maximum_temperature_nframes
221 self.vars[
"num_sample_rounds"] = num_sample_rounds
223 "number_of_best_scoring_models"] = number_of_best_scoring_models
224 self.vars[
"monte_carlo_steps"] = monte_carlo_steps
225 self.vars[
"molecular_dynamics_steps"]=molecular_dynamics_steps
226 self.vars[
"number_of_frames"] = number_of_frames
227 if not save_coordinates_mode
in [
"lowest_temperature",
"25th_score",
"50th_score",
"75th_score"]:
228 raise Exception(
"save_coordinates_mode has unrecognized value")
230 self.vars[
"save_coordinates_mode"] = save_coordinates_mode
231 self.vars[
"nframes_write_coordinates"] = nframes_write_coordinates
232 self.vars[
"write_initial_rmf"] = write_initial_rmf
233 self.vars[
"initial_rmf_name_suffix"] = initial_rmf_name_suffix
234 self.vars[
"best_pdb_name_suffix"] = best_pdb_name_suffix
235 self.vars[
"stat_file_name_suffix"] = stat_file_name_suffix
236 self.vars[
"do_clean_first"] = do_clean_first
237 self.vars[
"do_create_directories"] = do_create_directories
238 self.vars[
"global_output_directory"] = global_output_directory
239 self.vars[
"rmf_dir"] = rmf_dir
240 self.vars[
"best_pdb_dir"] = best_pdb_dir
241 self.vars[
"atomistic"] = atomistic
242 self.vars[
"replica_stat_file_suffix"] = replica_stat_file_suffix
243 self.vars[
"geometries"] =
None
244 self.test_mode = test_mode
247 if self.vars[
"geometries"]
is None:
248 self.vars[
"geometries"] = list(geometries)
250 self.vars[
"geometries"].extend(geometries)
253 print(
"ReplicaExchange0: it generates initial.*.rmf3, stat.*.out, rmfs/*.rmf3 for each replica ")
254 print(
"--- it stores the best scoring pdb models in pdbs/")
255 print(
"--- the stat.*.out and rmfs/*.rmf3 are saved only at the lowest temperature")
256 print(
"--- variables:")
257 keys = list(self.vars.keys())
260 print(
"------", v.ljust(30), self.vars[v])
262 def get_replica_exchange_object(self):
263 return self.replica_exchange_object
265 def _add_provenance(self, sampler_md, sampler_mc):
266 """Record details about the sampling in the IMP Hierarchies"""
267 if not self.is_multi_state
or self.pmi2:
268 output_hierarchies = [self.root_hier]
270 output_hierarchies = self.root_hiers
274 method =
"Molecular Dynamics"
275 iterations += self.vars[
"molecular_dynamics_steps"]
277 method =
"Hybrid MD/MC" if sampler_md
else "Monte Carlo"
278 iterations += self.vars[
"monte_carlo_steps"]
280 if iterations == 0
or self.vars[
"number_of_frames"] == 0:
282 iterations *= self.vars[
"num_sample_rounds"]
284 for h
in output_hierarchies:
285 pi = self.model.add_particle(
"sampling")
287 self.model, pi, method, self.vars[
"number_of_frames"],
289 p.set_number_of_replicas(
290 self.replica_exchange_object.get_number_of_replicas())
291 IMP.pmi.tools._add_pmi_provenance(h)
294 def execute_macro(self):
295 temp_index_factor = 100000.0
299 if self.monte_carlo_sample_objects
is not None:
300 print(
"Setting up MonteCarlo")
302 self.monte_carlo_sample_objects,
303 self.vars[
"monte_carlo_temperature"])
304 if self.vars[
"simulated_annealing"]:
305 tmin=self.vars[
"simulated_annealing_minimum_temperature"]
306 tmax=self.vars[
"simulated_annealing_maximum_temperature"]
307 nfmin=self.vars[
"simulated_annealing_minimum_temperature_nframes"]
308 nfmax=self.vars[
"simulated_annealing_maximum_temperature_nframes"]
309 sampler_mc.set_simulated_annealing(tmin,tmax,nfmin,nfmax)
310 if self.vars[
"self_adaptive"]:
311 sampler_mc.set_self_adaptive(isselfadaptive=self.vars[
"self_adaptive"])
312 if self.output_objects
is not None:
313 self.output_objects.append(sampler_mc)
314 if self.rmf_output_objects
is not None:
315 self.rmf_output_objects.append(sampler_mc)
316 samplers.append(sampler_mc)
319 if self.molecular_dynamics_sample_objects
is not None:
320 print(
"Setting up MolecularDynamics")
322 self.molecular_dynamics_sample_objects,
323 self.vars[
"monte_carlo_temperature"],
324 maximum_time_step=self.molecular_dynamics_max_time_step)
325 if self.vars[
"simulated_annealing"]:
326 tmin=self.vars[
"simulated_annealing_minimum_temperature"]
327 tmax=self.vars[
"simulated_annealing_maximum_temperature"]
328 nfmin=self.vars[
"simulated_annealing_minimum_temperature_nframes"]
329 nfmax=self.vars[
"simulated_annealing_maximum_temperature_nframes"]
330 sampler_md.set_simulated_annealing(tmin,tmax,nfmin,nfmax)
331 if self.output_objects
is not None:
332 self.output_objects.append(sampler_md)
333 if self.rmf_output_objects
is not None:
334 self.rmf_output_objects.append(sampler_md)
335 samplers.append(sampler_md)
338 print(
"Setting up ReplicaExchange")
341 "replica_exchange_minimum_temperature"],
343 "replica_exchange_maximum_temperature"],
345 replica_exchange_object=self.replica_exchange_object)
346 self.replica_exchange_object = rex.rem
348 myindex = rex.get_my_index()
349 if self.output_objects
is not None:
350 self.output_objects.append(rex)
351 if self.rmf_output_objects
is not None:
352 self.rmf_output_objects.append(rex)
356 min_temp_index = int(min(rex.get_temperatures()) * temp_index_factor)
360 globaldir = self.vars[
"global_output_directory"] +
"/"
361 rmf_dir = globaldir + self.vars[
"rmf_dir"]
362 pdb_dir = globaldir + self.vars[
"best_pdb_dir"]
364 if not self.test_mode:
365 if self.vars[
"do_clean_first"]:
368 if self.vars[
"do_create_directories"]:
371 os.makedirs(globaldir)
379 if not self.is_multi_state:
385 for n
in range(self.vars[
"number_of_states"]):
387 os.makedirs(pdb_dir +
"/" + str(n))
394 if self.output_objects
is not None:
395 self.output_objects.append(sw)
396 if self.rmf_output_objects
is not None:
397 self.rmf_output_objects.append(sw)
399 print(
"Setting up stat file")
401 low_temp_stat_file = globaldir + \
402 self.vars[
"stat_file_name_suffix"] +
"." + str(myindex) +
".out"
405 if not self.test_mode:
408 if not self.test_mode:
409 if self.output_objects
is not None:
410 output.init_stat2(low_temp_stat_file,
412 extralabels=[
"rmf_file",
"rmf_frame_index"])
414 print(
"Stat file writing is disabled")
416 if self.rmf_output_objects
is not None:
417 print(
"Stat info being written in the rmf file")
419 print(
"Setting up replica stat file")
420 replica_stat_file = globaldir + \
421 self.vars[
"replica_stat_file_suffix"] +
"." + str(myindex) +
".out"
422 if not self.test_mode:
423 output.init_stat2(replica_stat_file, [rex], extralabels=[
"score"])
425 if not self.test_mode:
426 print(
"Setting up best pdb files")
427 if not self.is_multi_state:
428 if self.vars[
"number_of_best_scoring_models"] > 0:
429 output.init_pdb_best_scoring(pdb_dir +
"/" +
430 self.vars[
"best_pdb_name_suffix"],
433 "number_of_best_scoring_models"],
434 replica_exchange=
True)
435 output.write_psf(pdb_dir +
"/" +
"model.psf",pdb_dir +
"/" +
436 self.vars[
"best_pdb_name_suffix"]+
".0.pdb")
438 if self.vars[
"number_of_best_scoring_models"] > 0:
439 for n
in range(self.vars[
"number_of_states"]):
440 output.init_pdb_best_scoring(pdb_dir +
"/" + str(n) +
"/" +
441 self.vars[
"best_pdb_name_suffix"],
444 "number_of_best_scoring_models"],
445 replica_exchange=
True)
446 output.write_psf(pdb_dir +
"/" + str(n) +
"/" +
"model.psf",pdb_dir +
"/" + str(n) +
"/" +
447 self.vars[
"best_pdb_name_suffix"]+
".0.pdb")
450 if self.em_object_for_rmf
is not None:
451 if not self.is_multi_state
or self.pmi2:
452 output_hierarchies = [
454 self.em_object_for_rmf.get_density_as_hierarchy(
457 output_hierarchies = self.root_hiers
458 output_hierarchies.append(
459 self.em_object_for_rmf.get_density_as_hierarchy())
461 if not self.is_multi_state
or self.pmi2:
462 output_hierarchies = [self.root_hier]
464 output_hierarchies = self.root_hiers
467 if not self.test_mode:
468 print(
"Setting up and writing initial rmf coordinate file")
469 init_suffix = globaldir + self.vars[
"initial_rmf_name_suffix"]
470 output.init_rmf(init_suffix +
"." + str(myindex) +
".rmf3",
471 output_hierarchies,listofobjects=self.rmf_output_objects)
472 if self._rmf_restraints:
473 output.add_restraints_to_rmf(
474 init_suffix +
"." + str(myindex) +
".rmf3",
475 self._rmf_restraints)
476 output.write_rmf(init_suffix +
"." + str(myindex) +
".rmf3")
477 output.close_rmf(init_suffix +
"." + str(myindex) +
".rmf3")
481 if not self.test_mode:
482 mpivs=IMP.pmi.samplers.MPI_values(self.replica_exchange_object)
486 self._add_provenance(sampler_md, sampler_mc)
488 if not self.test_mode:
489 print(
"Setting up production rmf files")
490 rmfname = rmf_dir +
"/" + str(myindex) +
".rmf3"
491 output.init_rmf(rmfname, output_hierarchies, geometries=self.vars[
"geometries"],
492 listofobjects = self.rmf_output_objects)
494 if self._rmf_restraints:
495 output.add_restraints_to_rmf(rmfname, self._rmf_restraints)
497 ntimes_at_low_temp = 0
501 self.replica_exchange_object.set_was_used(
True)
502 nframes = self.vars[
"number_of_frames"]
505 for i
in range(nframes):
509 for nr
in range(self.vars[
"num_sample_rounds"]):
510 if sampler_md
is not None:
512 self.vars[
"molecular_dynamics_steps"])
513 if sampler_mc
is not None:
514 sampler_mc.optimize(self.vars[
"monte_carlo_steps"])
516 self.model).evaluate(
False)
517 mpivs.set_value(
"score",score)
518 output.set_output_entry(
"score", score)
522 my_temp_index = int(rex.get_my_temp() * temp_index_factor)
524 if self.vars[
"save_coordinates_mode"] ==
"lowest_temperature":
525 save_frame=(min_temp_index == my_temp_index)
526 elif self.vars[
"save_coordinates_mode"] ==
"25th_score":
527 score_perc=mpivs.get_percentile(
"score")
528 save_frame=(score_perc*100.0<=25.0)
529 elif self.vars[
"save_coordinates_mode"] ==
"50th_score":
530 score_perc=mpivs.get_percentile(
"score")
531 save_frame=(score_perc*100.0<=50.0)
532 elif self.vars[
"save_coordinates_mode"] ==
"75th_score":
533 score_perc=mpivs.get_percentile(
"score")
534 save_frame=(score_perc*100.0<=75.0)
537 if save_frame
or not self.test_mode:
541 print(
"--- frame %s score %s " % (str(i), str(score)))
543 if not self.test_mode:
544 if i % self.vars[
"nframes_write_coordinates"]==0:
545 print(
'--- writing coordinates')
546 if self.vars[
"number_of_best_scoring_models"] > 0:
547 output.write_pdb_best_scoring(score)
548 output.write_rmf(rmfname)
549 output.set_output_entry(
"rmf_file", rmfname)
550 output.set_output_entry(
"rmf_frame_index", ntimes_at_low_temp)
552 output.set_output_entry(
"rmf_file", rmfname)
553 output.set_output_entry(
"rmf_frame_index",
'-1')
554 if self.output_objects
is not None:
555 output.write_stat2(low_temp_stat_file)
556 ntimes_at_low_temp += 1
558 if not self.test_mode:
559 output.write_stat2(replica_stat_file)
560 if self.vars[
"replica_exchange_swap"]:
561 rex.swap_temp(i, score)
562 for p, state
in IMP.pmi.tools._all_protocol_outputs(
563 [self.representation],
564 self.root_hier
if self.pmi2
else None):
565 p.add_replica_exchange(state, self)
567 if not self.test_mode:
568 print(
"closing production rmf files")
569 output.close_rmf(rmfname)
575 """A macro to build a IMP::pmi::topology::System based on a TopologyReader object.
576 Easily create multi-state systems by calling this macro
577 repeatedly with different TopologyReader objects!
578 A useful function is get_molecules() which returns the PMI Molecules grouped by state
579 as a dictionary with key = (molecule name), value = IMP.pmi.topology.Molecule
580 Quick multi-state system:
583 reader1 = IMP.pmi.topology.TopologyReader(tfile1)
584 reader2 = IMP.pmi.topology.TopologyReader(tfile2)
585 bs = IMP.pmi.macros.BuildSystem(model)
586 bs.add_state(reader1)
587 bs.add_state(reader2)
588 bs.execute_macro() # build everything including degrees of freedom
589 IMP.atom.show_molecular_hierarchy(bs.get_hierarchy())
590 ### now you have a two state system, you add restraints etc
592 @note The "domain name" entry of the topology reader is not used.
593 All molecules are set up by the component name, but split into rigid bodies
598 sequence_connectivity_scale=4.0,
599 force_create_gmm_files=
False,
602 @param model An IMP Model
603 @param sequence_connectivity_scale For scaling the connectivity restraint
604 @param force_create_gmm_files If True, will sample and create GMMs
605 no matter what. If False, will only sample if the
606 files don't exist. If number of Gaussians is zero, won't
608 @param resolutions The resolutions to build for structured regions
613 self._domain_res = []
615 self.force_create_gmm_files = force_create_gmm_files
616 self.resolutions = resolutions
620 keep_chain_id=
False, fasta_name_map=
None):
621 """Add a state using the topology info in a IMP::pmi::topology::TopologyReader object.
622 When you are done adding states, call execute_macro()
623 @param reader The TopologyReader object
624 @param fasta_name_map dictionary for converting protein names found in the fasta file
626 state = self.system.create_state()
627 self._readers.append(reader)
628 these_domain_res = {}
630 chain_ids = string.ascii_uppercase+string.ascii_lowercase+
'0123456789'
635 for molname
in reader.get_molecules():
636 copies = reader.get_molecules()[molname].domains
637 for nc,copyname
in enumerate(copies):
638 print(
"BuildSystem.add_state: setting up molecule %s copy number %s" % (molname,str(nc)))
639 copy = copies[copyname]
641 if keep_chain_id ==
True:
642 chain_id = copy[0].chain
644 chain_id = chain_ids[numchain]
647 fasta_flag=copy[0].fasta_flag
648 if fasta_flag ==
"RNA" or fasta_flag ==
"DNA": is_nucleic=
True
650 print(
"BuildSystem.add_state: molecule %s sequence has %s residues" % (molname,len(seq)))
651 orig_mol = state.create_molecule(molname,
657 print(
"BuildSystem.add_state: creating a copy for molecule %s" % molname)
658 mol = orig_mol.create_copy(chain_id)
661 for domainnumber,domain
in enumerate(copy):
662 print(
"BuildSystem.add_state: ---- setting up domain %s of molecule %s" % (domainnumber,molname))
665 these_domains[domain.get_unique_name()] = domain
666 if domain.residue_range==[]
or domain.residue_range
is None:
667 domain_res = mol.get_residues()
669 start = domain.residue_range[0]+domain.pdb_offset
670 if domain.residue_range[1]==
'END':
671 end = len(mol.sequence)
673 end = domain.residue_range[1]+domain.pdb_offset
674 domain_res = mol.residue_range(start-1,end-1)
675 print(
"BuildSystem.add_state: -------- domain %s of molecule %s extends from residue %s to residue %s " % (domainnumber,molname,start,end))
676 if domain.pdb_file==
"BEADS":
677 print(
"BuildSystem.add_state: -------- domain %s of molecule %s represented by BEADS " % (domainnumber,molname))
678 mol.add_representation(
680 resolutions=[domain.bead_size],
681 setup_particles_as_densities=(
682 domain.em_residues_per_gaussian!=0),
683 color = domain.color)
684 these_domain_res[domain.get_unique_name()] = (set(),domain_res)
685 elif domain.pdb_file==
"IDEAL_HELIX":
686 print(
"BuildSystem.add_state: -------- domain %s of molecule %s represented by IDEAL_HELIX " % (domainnumber,molname))
687 mol.add_representation(
689 resolutions=self.resolutions,
691 density_residues_per_component=domain.em_residues_per_gaussian,
692 density_prefix=domain.density_prefix,
693 density_force_compute=self.force_create_gmm_files,
694 color = domain.color)
695 these_domain_res[domain.get_unique_name()] = (domain_res,set())
697 print(
"BuildSystem.add_state: -------- domain %s of molecule %s represented by pdb file %s " % (domainnumber,molname,domain.pdb_file))
698 domain_atomic = mol.add_structure(domain.pdb_file,
700 domain.residue_range,
703 domain_non_atomic = domain_res - domain_atomic
704 if not domain.em_residues_per_gaussian:
705 mol.add_representation(domain_atomic,
706 resolutions=self.resolutions,
707 color = domain.color)
708 if len(domain_non_atomic)>0:
709 mol.add_representation(domain_non_atomic,
710 resolutions=[domain.bead_size],
711 color = domain.color)
713 print(
"BuildSystem.add_state: -------- domain %s of molecule %s represented by gaussians " % (domainnumber,molname))
714 mol.add_representation(
716 resolutions=self.resolutions,
717 density_residues_per_component=domain.em_residues_per_gaussian,
718 density_prefix=domain.density_prefix,
719 density_force_compute=self.force_create_gmm_files,
720 color = domain.color)
721 if len(domain_non_atomic)>0:
722 mol.add_representation(domain_non_atomic,
723 resolutions=[domain.bead_size],
724 setup_particles_as_densities=
True,
725 color = domain.color)
726 these_domain_res[domain.get_unique_name()] = (
727 domain_atomic,domain_non_atomic)
728 self._domain_res.append(these_domain_res)
729 self._domains.append(these_domains)
730 print(
'BuildSystem.add_state: State',len(self.system.states),
'added')
733 """Return list of all molecules grouped by state.
734 For each state, it's a dictionary of Molecules where key is the molecule name
736 return [s.get_molecules()
for s
in self.system.get_states()]
738 def get_molecule(self,molname,copy_index=0,state_index=0):
739 return self.system.get_states()[state_index].
get_molecules()[molname][copy_index]
741 def execute_macro(self, max_rb_trans=4.0, max_rb_rot=0.04, max_bead_trans=4.0, max_srb_trans=4.0,max_srb_rot=0.04):
742 """Builds representations and sets up degrees of freedom"""
743 print(
"BuildSystem.execute_macro: building representations")
744 self.root_hier = self.system.build()
746 print(
"BuildSystem.execute_macro: setting up degrees of freedom")
748 for nstate,reader
in enumerate(self._readers):
749 rbs = reader.get_rigid_bodies()
750 srbs = reader.get_super_rigid_bodies()
751 csrbs = reader.get_chains_of_super_rigid_bodies()
754 domains_in_rbs = set()
756 print(
"BuildSystem.execute_macro: -------- building rigid body %s" % (str(rblist)))
757 all_res = IMP.pmi.tools.OrderedSet()
758 bead_res = IMP.pmi.tools.OrderedSet()
760 domain = self._domains[nstate][dname]
761 print(
"BuildSystem.execute_macro: -------- adding %s" % (str(dname )))
762 all_res|=self._domain_res[nstate][dname][0]
763 bead_res|=self._domain_res[nstate][dname][1]
764 domains_in_rbs.add(dname)
766 print(
"BuildSystem.execute_macro: -------- \
767 creating rigid body with max_trans %s \
768 max_rot %s non_rigid_max_trans %s" \
769 % (str(max_rb_trans),str(max_rb_rot),str(max_bead_trans)))
770 self.dof.create_rigid_body(all_res,
771 nonrigid_parts=bead_res,
772 max_trans=max_rb_trans,
774 nonrigid_max_trans=max_bead_trans)
777 for dname, domain
in self._domains[nstate].items():
778 if dname
not in domains_in_rbs:
779 if domain.pdb_file !=
"BEADS":
781 "Making %s flexible. This may distort the "
782 "structure; consider making it rigid" % dname,
784 self.dof.create_flexible_beads(
785 self._domain_res[nstate][dname][1],
786 max_trans=max_bead_trans)
790 print(
"BuildSystem.execute_macro: -------- building super rigid body %s" % (str(srblist)))
791 all_res = IMP.pmi.tools.OrderedSet()
792 for dname
in srblist:
793 print(
"BuildSystem.execute_macro: -------- adding %s" % (str(dname )))
794 all_res|=self._domain_res[nstate][dname][0]
795 all_res|=self._domain_res[nstate][dname][1]
797 print(
"BuildSystem.execute_macro: -------- \
798 creating super rigid body with max_trans %s max_rot %s " \
799 % (str(max_srb_trans),str(max_srb_rot)))
800 self.dof.create_super_rigid_body(all_res,max_trans=max_srb_trans,max_rot=max_srb_rot)
803 for csrblist
in csrbs:
804 all_res = IMP.pmi.tools.OrderedSet()
805 for dname
in csrblist:
806 all_res|=self._domain_res[nstate][dname][0]
807 all_res|=self._domain_res[nstate][dname][1]
808 all_res = list(all_res)
809 all_res.sort(key=
lambda r:r.get_index())
811 self.dof.create_main_chain_mover(all_res)
812 return self.root_hier,self.dof
817 """A macro for running all the basic operations of analysis.
818 Includes clustering, precision analysis, and making ensemble density maps.
819 A number of plots are also supported.
822 merge_directories=[
"./"],
823 stat_file_name_suffix=
"stat",
824 best_pdb_name_suffix=
"model",
826 do_create_directories=
True,
827 global_output_directory=
"output/",
828 replica_stat_file_suffix=
"stat_replica",
829 global_analysis_result_directory=
"./analysis/",
832 @param model The IMP model
833 @param stat_file_name_suffix
834 @param merge_directories The directories containing output files
835 @param best_pdb_name_suffix
836 @param do_clean_first
837 @param do_create_directories
838 @param global_output_directory Where everything is
839 @param replica_stat_file_suffix
840 @param global_analysis_result_directory
841 @param test_mode If True, nothing is changed on disk
845 from mpi4py
import MPI
846 self.comm = MPI.COMM_WORLD
847 self.rank = self.comm.Get_rank()
848 self.number_of_processes = self.comm.size
851 self.number_of_processes = 1
853 self.test_mode = test_mode
854 self._protocol_output = []
855 self.cluster_obj =
None
857 stat_dir = global_output_directory
860 for rd
in merge_directories:
861 stat_files = glob.glob(os.path.join(rd,stat_dir,
"stat.*.out"))
862 if len(stat_files)==0:
863 warnings.warn(
"no stat files found in %s"
864 % os.path.join(rd, stat_dir),
866 self.stat_files += stat_files
869 """Capture details of the modeling protocol.
870 @param p an instance of IMP.pmi.output.ProtocolOutput or a subclass.
873 self._protocol_output.append((p, p._last_state))
876 score_key=
"SimplifiedModel_Total_Score_None",
877 rmf_file_key=
"rmf_file",
878 rmf_file_frame_key=
"rmf_frame_index",
881 nframes_trajectory=10000):
882 """ Get a trajectory of the modeling run, for generating demonstrative movies
883 @param score_key The score for ranking models
884 @param rmf_file_key Key pointing to RMF filename
885 @param rmf_file_frame_key Key pointing to RMF frame number
886 @param outputdir The local output directory used in the run
887 @param get_every Extract every nth frame
888 @param nframes_trajectory Total number of frames of the trajectory
890 from operator
import itemgetter
898 rmf_file_list=trajectory_models[0]
899 rmf_file_frame_list=trajectory_models[1]
900 score_list=list(map(float, trajectory_models[2]))
902 max_score=max(score_list)
903 min_score=min(score_list)
906 bins=[(max_score-min_score)*math.exp(-float(i))+min_score
for i
in range(nframes_trajectory)]
907 binned_scores=[
None]*nframes_trajectory
908 binned_model_indexes=[-1]*nframes_trajectory
910 for model_index,s
in enumerate(score_list):
911 bins_score_diffs=[abs(s-b)
for b
in bins]
912 bin_index=min(enumerate(bins_score_diffs), key=itemgetter(1))[0]
913 if binned_scores[bin_index]==
None:
914 binned_scores[bin_index]=s
915 binned_model_indexes[bin_index]=model_index
917 old_diff=abs(binned_scores[bin_index]-bins[bin_index])
918 new_diff=abs(s-bins[bin_index])
919 if new_diff < old_diff:
920 binned_scores[bin_index]=s
921 binned_model_indexes[bin_index]=model_index
924 print(binned_model_indexes)
927 def _expand_ambiguity(self,prot,d):
928 """If using PMI2, expand the dictionary to include copies as ambiguous options
929 This also keeps the states separate.
934 if '..' in key
or (isinstance(val, tuple)
and len(val) >= 3):
937 states = IMP.atom.get_by_type(prot,IMP.atom.STATE_TYPE)
938 if isinstance(val, tuple):
946 for nst
in range(len(states)):
948 copies = sel.get_selected_particles(with_representation=
False)
950 for nc
in range(len(copies)):
952 newdict[
'%s.%i..%i'%(name,nst,nc)] = (start,stop,name,nc,nst)
954 newdict[
'%s..%i'%(name,nc)] = (start,stop,name,nc,nst)
961 score_key=
"SimplifiedModel_Total_Score_None",
962 rmf_file_key=
"rmf_file",
963 rmf_file_frame_key=
"rmf_frame_index",
968 alignment_components=
None,
969 number_of_best_scoring_models=10,
970 rmsd_calculation_components=
None,
971 distance_matrix_file=
'distances.mat',
972 load_distance_matrix_file=
False,
973 skip_clustering=
False,
974 number_of_clusters=1,
976 exit_after_display=
True,
978 first_and_last_frames=
None,
979 density_custom_ranges=
None,
980 write_pdb_with_centered_coordinates=
False,
982 """ Get the best scoring models, compute a distance matrix, cluster them, and create density maps.
983 Tuple format: "molname" just the molecule, or (start,stop,molname,copy_num(optional),state_num(optional)
984 Can pass None for copy or state to ignore that field.
985 If you don't pass a specific copy number
986 @param score_key The score for ranking models. Use "Total_Score"
987 instead of default for PMI2.
988 @param rmf_file_key Key pointing to RMF filename
989 @param rmf_file_frame_key Key pointing to RMF frame number
990 @param state_number State number to analyze
991 @param prefiltervalue Only include frames where the
992 score key is below this value
993 @param feature_keys Keywords for which you want to
994 calculate average, medians, etc.
995 If you pass "Keyname" it'll include everything that matches "*Keyname*"
996 @param outputdir The local output directory used in the run
997 @param alignment_components Dictionary with keys=groupname, values are tuples
998 for aligning the structures e.g. {"Rpb1": (20,100,"Rpb1"),"Rpb2":"Rpb2"}
999 @param number_of_best_scoring_models Num models to keep per run
1000 @param rmsd_calculation_components For calculating RMSD
1001 (same format as alignment_components)
1002 @param distance_matrix_file Where to store/read the distance matrix
1003 @param load_distance_matrix_file Try to load the distance matrix file
1004 @param skip_clustering Just extract the best scoring models
1006 @param number_of_clusters Number of k-means clusters
1007 @param display_plot Display the distance matrix
1008 @param exit_after_display Exit after displaying distance matrix
1009 @param get_every Extract every nth frame
1010 @param first_and_last_frames A tuple with the first and last frames to be
1011 analyzed. Values are percentages!
1012 Default: get all frames
1013 @param density_custom_ranges For density calculation
1014 (same format as alignment_components)
1015 @param write_pdb_with_centered_coordinates
1016 @param voxel_size Used for the density output
1020 self._outputdir = os.path.abspath(outputdir)
1021 self._number_of_clusters = number_of_clusters
1022 for p, state
in self._protocol_output:
1023 p.add_replica_exchange_analysis(state, self, density_custom_ranges)
1034 if not load_distance_matrix_file:
1035 if len(self.stat_files)==0: print(
"ERROR: no stat file found in the given path");
return
1036 my_stat_files = IMP.pmi.tools.chunk_list_into_segments(
1037 self.stat_files,self.number_of_processes)[self.rank]
1041 orig_score_key = score_key
1042 if score_key
not in po.get_keys():
1043 if 'Total_Score' in po.get_keys():
1044 score_key =
'Total_Score'
1046 "Using 'Total_Score' instead of "
1047 "'SimplifiedModel_Total_Score_None' for the score key",
1049 for k
in [orig_score_key,score_key,rmf_file_key,rmf_file_frame_key]:
1050 if k
in feature_keys:
1052 "no need to pass " + k +
" to feature_keys.",
1054 feature_keys.remove(k)
1062 get_every, provenance=prov)
1063 rmf_file_list=best_models[0]
1064 rmf_file_frame_list=best_models[1]
1065 score_list=best_models[2]
1066 feature_keyword_list_dict=best_models[3]
1072 if self.number_of_processes > 1:
1076 rmf_file_frame_list)
1077 for k
in feature_keyword_list_dict:
1079 feature_keyword_list_dict[k])
1082 score_rmf_tuples = list(zip(score_list,
1084 rmf_file_frame_list,
1085 list(range(len(score_list)))))
1087 if density_custom_ranges:
1088 for k
in density_custom_ranges:
1089 if not isinstance(density_custom_ranges[k], list):
1090 raise Exception(
"Density custom ranges: values must be lists of tuples")
1093 if first_and_last_frames
is not None:
1094 nframes = len(score_rmf_tuples)
1095 first_frame = int(first_and_last_frames[0] * nframes)
1096 last_frame = int(first_and_last_frames[1] * nframes)
1097 if last_frame > len(score_rmf_tuples):
1099 score_rmf_tuples = score_rmf_tuples[first_frame:last_frame]
1102 best_score_rmf_tuples = sorted(score_rmf_tuples,
1103 key=
lambda x: float(x[0]))[:number_of_best_scoring_models]
1104 best_score_rmf_tuples=[t+(n,)
for n,t
in enumerate(best_score_rmf_tuples)]
1106 prov.append(IMP.pmi.io.FilterProvenance(
"Best scoring",
1107 0, number_of_best_scoring_models))
1109 best_score_feature_keyword_list_dict = defaultdict(list)
1110 for tpl
in best_score_rmf_tuples:
1112 for f
in feature_keyword_list_dict:
1113 best_score_feature_keyword_list_dict[f].append(
1114 feature_keyword_list_dict[f][index])
1115 my_best_score_rmf_tuples = IMP.pmi.tools.chunk_list_into_segments(
1116 best_score_rmf_tuples,
1117 self.number_of_processes)[self.rank]
1120 prot_ahead = IMP.pmi.analysis.get_hiers_from_rmf(self.model,
1122 my_best_score_rmf_tuples[0][1])[0]
1124 if rmsd_calculation_components
is not None:
1125 tmp = self._expand_ambiguity(prot_ahead,rmsd_calculation_components)
1126 if tmp!=rmsd_calculation_components:
1127 print(
'Detected ambiguity, expand rmsd components to',tmp)
1128 rmsd_calculation_components = tmp
1129 if alignment_components
is not None:
1130 tmp = self._expand_ambiguity(prot_ahead,alignment_components)
1131 if tmp!=alignment_components:
1132 print(
'Detected ambiguity, expand alignment components to',tmp)
1133 alignment_components = tmp
1139 my_best_score_rmf_tuples[0],
1140 rmsd_calculation_components,
1141 state_number=state_number)
1143 my_best_score_rmf_tuples,
1144 alignment_components,
1145 rmsd_calculation_components,
1146 state_number=state_number)
1151 all_coordinates=got_coords[0]
1152 alignment_coordinates=got_coords[1]
1153 rmsd_coordinates=got_coords[2]
1154 rmf_file_name_index_dict=got_coords[3]
1155 all_rmf_file_names=got_coords[4]
1161 if density_custom_ranges:
1163 density_custom_ranges,
1166 dircluster=os.path.join(outputdir,
"all_models."+str(n))
1172 os.mkdir(dircluster)
1175 clusstat=open(os.path.join(dircluster,
"stat."+str(self.rank)+
".out"),
"w")
1176 for cnt,tpl
in enumerate(my_best_score_rmf_tuples):
1178 rmf_frame_number=tpl[2]
1181 for key
in best_score_feature_keyword_list_dict:
1182 tmp_dict[key]=best_score_feature_keyword_list_dict[key][index]
1185 prots,rs = IMP.pmi.analysis.get_hiers_and_restraints_from_rmf(
1190 linking_successful=IMP.pmi.analysis.link_hiers_and_restraints_to_rmf(
1196 if not linking_successful:
1203 states = IMP.atom.get_by_type(prots[0],IMP.atom.STATE_TYPE)
1204 prot = states[state_number]
1206 prot = prots[state_number]
1211 coords_f1=alignment_coordinates[cnt]
1213 coords_f2=alignment_coordinates[cnt]
1216 transformation = Ali.align()[1]
1238 out_pdb_fn=os.path.join(dircluster,str(cnt)+
"."+str(self.rank)+
".pdb")
1239 out_rmf_fn=os.path.join(dircluster,str(cnt)+
"."+str(self.rank)+
".rmf3")
1240 o.init_pdb(out_pdb_fn,prot)
1241 o.write_pdb(out_pdb_fn,
1242 translate_to_geometric_center=write_pdb_with_centered_coordinates)
1244 tmp_dict[
"local_pdb_file_name"]=os.path.basename(out_pdb_fn)
1245 tmp_dict[
"rmf_file_full_path"]=rmf_name
1246 tmp_dict[
"local_rmf_file_name"]=os.path.basename(out_rmf_fn)
1247 tmp_dict[
"local_rmf_frame_number"]=0
1249 clusstat.write(str(tmp_dict)+
"\n")
1254 h.set_name(
"System")
1256 o.init_rmf(out_rmf_fn, [h], rs)
1258 o.init_rmf(out_rmf_fn, [prot],rs)
1260 o.write_rmf(out_rmf_fn)
1261 o.close_rmf(out_rmf_fn)
1263 if density_custom_ranges:
1264 DensModule.add_subunits_density(prot)
1266 if density_custom_ranges:
1267 DensModule.write_mrc(path=dircluster)
1274 if self.number_of_processes > 1:
1280 rmf_file_name_index_dict)
1282 alignment_coordinates)
1289 [best_score_feature_keyword_list_dict,
1290 rmf_file_name_index_dict],
1296 print(
"setup clustering class")
1299 for n, model_coordinate_dict
in enumerate(all_coordinates):
1300 template_coordinate_dict = {}
1302 if alignment_components
is not None and len(self.cluster_obj.all_coords) == 0:
1304 self.cluster_obj.set_template(alignment_coordinates[n])
1305 self.cluster_obj.fill(all_rmf_file_names[n], rmsd_coordinates[n])
1306 print(
"Global calculating the distance matrix")
1309 self.cluster_obj.dist_matrix()
1313 self.cluster_obj.do_cluster(number_of_clusters)
1316 self.cluster_obj.plot_matrix(figurename=os.path.join(outputdir,
'dist_matrix.pdf'))
1317 if exit_after_display:
1319 self.cluster_obj.save_distance_matrix_file(file_name=distance_matrix_file)
1326 print(
"setup clustering class")
1328 self.cluster_obj.load_distance_matrix_file(file_name=distance_matrix_file)
1329 print(
"clustering with %s clusters" % str(number_of_clusters))
1330 self.cluster_obj.do_cluster(number_of_clusters)
1331 [best_score_feature_keyword_list_dict,
1332 rmf_file_name_index_dict] = self.load_objects(
".macro.pkl")
1335 self.cluster_obj.plot_matrix(figurename=os.path.join(outputdir,
'dist_matrix.pdf'))
1336 if exit_after_display:
1338 if self.number_of_processes > 1:
1346 print(self.cluster_obj.get_cluster_labels())
1347 for n, cl
in enumerate(self.cluster_obj.get_cluster_labels()):
1348 print(
"rank %s " % str(self.rank))
1349 print(
"cluster %s " % str(n))
1350 print(
"cluster label %s " % str(cl))
1351 print(self.cluster_obj.get_cluster_label_names(cl))
1352 cluster_size = len(self.cluster_obj.get_cluster_label_names(cl))
1353 cluster_prov = prov + \
1354 [IMP.pmi.io.ClusterProvenance(cluster_size)]
1357 if density_custom_ranges:
1359 density_custom_ranges,
1362 dircluster = outputdir +
"/cluster." + str(n) +
"/"
1364 os.mkdir(dircluster)
1368 rmsd_dict = {
"AVERAGE_RMSD":
1369 str(self.cluster_obj.get_cluster_label_average_rmsd(cl))}
1370 clusstat = open(dircluster +
"stat.out",
"w")
1371 for k, structure_name
in enumerate(self.cluster_obj.get_cluster_label_names(cl)):
1374 tmp_dict.update(rmsd_dict)
1375 index = rmf_file_name_index_dict[structure_name]
1376 for key
in best_score_feature_keyword_list_dict:
1378 key] = best_score_feature_keyword_list_dict[
1384 rmf_name = structure_name.split(
"|")[0]
1385 rmf_frame_number = int(structure_name.split(
"|")[1])
1386 clusstat.write(str(tmp_dict) +
"\n")
1390 prots,rs = IMP.pmi.analysis.get_hiers_and_restraints_from_rmf(
1395 linking_successful = IMP.pmi.analysis.link_hiers_and_restraints_to_rmf(
1401 if not linking_successful:
1407 states = IMP.atom.get_by_type(prots[0],IMP.atom.STATE_TYPE)
1408 prot = states[state_number]
1410 prot = prots[state_number]
1416 model_index = self.cluster_obj.get_model_index_from_name(
1418 transformation = self.cluster_obj.get_transformation_to_first_member(
1438 if density_custom_ranges:
1439 DensModule.add_subunits_density(prot)
1444 o.init_pdb(dircluster + str(k) +
".pdb", prot)
1445 o.write_pdb(dircluster + str(k) +
".pdb")
1450 h.set_name(
"System")
1452 o.init_rmf(dircluster + str(k) +
".rmf3", [h], rs)
1454 o.init_rmf(dircluster + str(k) +
".rmf3", [prot],rs)
1455 o.write_rmf(dircluster + str(k) +
".rmf3")
1456 o.close_rmf(dircluster + str(k) +
".rmf3")
1461 if density_custom_ranges:
1462 DensModule.write_mrc(path=dircluster)
1465 if self.number_of_processes>1:
1468 def get_cluster_rmsd(self,cluster_num):
1469 if self.cluster_obj
is None:
1471 return self.cluster_obj.get_cluster_label_average_rmsd(cluster_num)
1473 def save_objects(self, objects, file_name):
1475 outf = open(file_name,
'wb')
1476 pickle.dump(objects, outf)
1479 def load_objects(self, file_name):
1481 inputf = open(file_name,
'rb')
1482 objects = pickle.load(inputf)
1489 This class contains analysis utilities to investigate ReplicaExchange results.
1502 Construction of the Class.
1503 @param model IMP.Model()
1504 @param stat_files list of string. Can be ascii stat files, rmf files names
1505 @param best_models Integer. Number of best scoring models, if None: all models will be read
1506 @param alignment boolean (Default=True). Align before computing the rmsd.
1510 self.best_models=best_models
1523 self.clusters.append(c)
1524 for n0
in range(len(self.stath0)):
1526 self.pairwise_rmsd={}
1527 self.pairwise_molecular_assignment={}
1528 self.alignment=alignment
1529 self.symmetric_molecules={}
1530 self.issymmetricsel={}
1532 self.molcopydict0=IMP.pmi.tools.get_molecules_dictionary_by_copy(
IMP.atom.get_leaves(self.stath0))
1533 self.molcopydict1=IMP.pmi.tools.get_molecules_dictionary_by_copy(
IMP.atom.get_leaves(self.stath1))
1537 Setup the selection onto which the rmsd is computed
1538 @param kwargs use IMP.atom.Selection keywords
1546 Store names of symmetric molecules
1548 self.symmetric_molecules[molecule_name]=0
1553 Setup the selection onto which the alignment is computed
1554 @param kwargs use IMP.atom.Selection keywords
1562 def clean_clusters(self):
1563 for c
in self.clusters: del c
1567 def cluster(self, rmsd_cutoff=10, metric=IMP.atom.get_rmsd):
1569 Cluster the models based on RMSD.
1570 @param rmsd_cutoff Float the distance cutoff in Angstrom
1571 @param metric (Default=IMP.atom.get_rmsd) the metric that will be used to compute rmsds
1573 self.clean_clusters()
1574 not_clustered=set(range(len(self.stath1)))
1575 while len(not_clustered)>0:
1576 self.
aggregate(not_clustered, rmsd_cutoff, metric)
1582 Refine the clusters by merging the ones whose centers are close
1583 @param rmsd_cutoff cutoff distance in Angstorms
1586 clusters_copy=self.clusters
1587 for c0,c1
in itertools.combinations(self.clusters,2):
1588 if c0.center_index
is None:
1590 if c1.center_index
is None:
1592 d0=self.stath0[c0.center_index]
1593 d1=self.stath1[c1.center_index]
1594 rmsd, molecular_assignment = self.
rmsd()
1595 if rmsd <= rmsd_cutoff:
1596 if c1
in self.clusters:
1597 clusters_copy.remove(c1)
1599 self.clusters=clusters_copy
1606 def set_cluster_assignments(self, cluster_ids):
1607 if len(cluster_ids)!=len(self.stath0):
1608 raise ValueError(
'cluster ids has to be same length as number of frames')
1611 for i
in sorted(list(set(cluster_ids))):
1613 for i, (idx, d)
in enumerate(zip(cluster_ids, self.stath0)):
1614 self.clusters[idx].add_member(i,d)
1618 Return the model data from a cluster
1619 @param cluster IMP.pmi.output.Cluster object
1628 Save the data for the whole models into a pickle file
1629 @param filename string
1631 self.stath0.save_data(filename)
1635 Set the data from an external IMP.pmi.output.Data
1636 @param data IMP.pmi.output.Data
1638 self.stath0.data=data
1639 self.stath1.data=data
1643 Load the data from an external pickled file
1644 @param filename string
1646 self.stath0.load_data(filename)
1647 self.stath1.load_data(filename)
1648 self.best_models=len(self.stath0)
1650 def add_cluster(self,rmf_name_list):
1652 print(
"creating cluster index "+str(len(self.clusters)))
1653 self.clusters.append(c)
1654 current_len=len(self.stath0)
1656 for rmf
in rmf_name_list:
1657 print(
"adding rmf "+rmf)
1658 self.stath0.add_stat_file(rmf)
1659 self.stath1.add_stat_file(rmf)
1661 for n0
in range(current_len,len(self.stath0)):
1668 Save the clusters into a pickle file
1669 @param filename string
1672 import cPickle
as pickle
1675 fl=open(filename,
'wb')
1676 pickle.dump(self.clusters,fl)
1680 Load the clusters from a pickle file
1681 @param filename string
1682 @param append bool (Default=False), if True. append the clusters to the ones currently present
1685 import cPickle
as pickle
1688 fl=open(filename,
'rb')
1689 self.clean_clusters()
1691 self.clusters+=pickle.load(fl)
1693 self.clusters=pickle.load(fl)
1702 Compute the cluster center for a given cluster
1704 member_distance=defaultdict(float)
1706 for n0,n1
in itertools.combinations(cluster.members,2):
1709 rmsd, _ = self.
rmsd()
1710 member_distance[n0]+=rmsd
1712 if len(member_distance)>0:
1713 cluster.center_index=min(member_distance, key=member_distance.get)
1715 cluster.center_index=cluster.members[0]
1719 Save the coordinates of the current cluster a single rmf file
1721 print(
"saving coordinates",cluster)
1724 if rmf_name
is None:
1725 rmf_name=prefix+
'/'+str(cluster.cluster_id)+
".rmf3"
1727 d1=self.stath1[cluster.members[0]]
1729 o.init_rmf(rmf_name, [self.stath1])
1730 for n1
in cluster.members:
1734 if self.alignment: self.align()
1735 o.write_rmf(rmf_name)
1737 o.close_rmf(rmf_name)
1741 remove structures that are similar
1742 append it to a new cluster
1744 print(
"pruning models")
1747 remaining=range(1,len(self.stath1),10)
1749 while len(remaining)>0:
1750 d0=self.stath0[selected]
1752 for n1
in remaining:
1754 if self.alignment: self.align()
1758 print(
"pruning model %s, similar to model %s, rmsd %s"%(str(n1),str(selected),str(d)))
1759 remaining=[x
for x
in remaining
if x
not in rm]
1760 if len(remaining)==0:
break
1761 selected=remaining[0]
1762 filtered.append(selected)
1765 self.clusters.append(c)
1775 Compute the precision of a cluster
1781 if not cluster.center_index
is None:
1782 members1=[cluster.center_index]
1784 members1=cluster.members
1788 for n1
in cluster.members:
1793 tmp_rmsd, _ = self.
rmsd()
1798 precision=rmsd/npairs
1799 cluster.precision=precision
1804 Compute the bipartite precision (ie the cross-precision)
1805 between two clusters
1809 for cn0,n0
in enumerate(cluster1.members):
1811 for cn1,n1
in enumerate(cluster2.members):
1813 tmp_rmsd, _ =self.
rmsd()
1814 if verbose: print(
"--- rmsd between structure %s and structure %s is %s"%(str(cn0),str(cn1),str(tmp_rmsd)))
1817 precision=rmsd/npairs
1820 def rmsf(self,cluster,molecule,copy_index=0,state_index=0,cluster_ref=None,step=1):
1822 Compute the Root mean square fluctuations
1823 of a molecule in a cluster
1824 Returns an IMP.pmi.tools.OrderedDict() where the keys are the residue indexes and the value is the rmsf
1826 rmsf=IMP.pmi.tools.OrderedDict()
1829 if cluster_ref
is not None:
1830 if not cluster_ref.center_index
is None:
1831 members0 = [cluster_ref.center_index]
1833 members0 = cluster_ref.members
1835 if not cluster.center_index
is None:
1836 members0 = [cluster.center_index]
1838 members0 = cluster.members
1841 copy_index=copy_index,state_index=state_index)
1842 ps0=s0.get_selected_particles()
1856 for n1
in cluster.members[::step]:
1858 print(
"--- rmsf %s %s"%(str(n0),str(n1)))
1861 s1=
IMP.atom.Selection(self.stath1,molecule=molecule,residue_indexes=residue_indexes,resolution=1,
1862 copy_index=copy_index,state_index=state_index)
1863 ps1 = s1.get_selected_particles()
1866 if self.alignment: self.align()
1867 for n,(p0,p1)
in enumerate(zip(ps0,ps1)):
1868 r=residue_indexes[n]
1880 for stath
in [self.stath0,self.stath1]:
1881 if molecule
not in self.symmetric_molecules:
1883 copy_index=copy_index,state_index=state_index)
1886 state_index=state_index)
1888 ps = s.get_selected_particles()
1897 def save_densities(self,cluster,density_custom_ranges,voxel_size=5,reference="Absolute", prefix="./",step=1):
1902 for n1
in cluster.members[::step]:
1903 print(
"density "+str(n1))
1906 if self.alignment: self.align()
1907 dens.add_subunits_density(self.stath1)
1909 dens.write_mrc(path=prefix+
'/',suffix=str(cluster.cluster_id))
1912 def contact_map(self,cluster,contact_threshold=15,log_scale=False,consolidate=False,molecules=None,prefix='./',reference="Absolute"):
1915 import matplotlib.pyplot
as plt
1916 import matplotlib.cm
as cm
1917 from scipy.spatial.distance
import cdist
1919 if molecules
is None:
1923 unique_copies=[mol
for mol
in mols
if mol.get_copy_index() == 0]
1924 mol_names_unique=dict((mol.get_name(),mol)
for mol
in unique_copies)
1925 total_len_unique=sum(max(mol.get_residue_indexes())
for mol
in unique_copies)
1934 seqlen=max(mol.get_residue_indexes())
1935 index_dict[mol] = range(prev_stop, prev_stop + seqlen)
1939 for mol
in unique_copies:
1940 seqlen=max(mol.get_residue_indexes())
1941 index_dict[mol] = range(prev_stop, prev_stop + seqlen)
1945 for ncl,n1
in enumerate(cluster.members):
1949 coord_dict=IMP.pmi.tools.OrderedDict()
1951 mol_name=mol.get_name()
1952 copy_index=mol.get_copy_index()
1953 rindexes = mol.get_residue_indexes()
1954 coords = np.ones((max(rindexes),3))
1955 for rnum
in rindexes:
1957 selpart = sel.get_selected_particles()
1958 if len(selpart) == 0:
continue
1959 selpart = selpart[0]
1960 coords[rnum - 1, :] =
IMP.core.XYZ(selpart).get_coordinates()
1961 coord_dict[mol]=coords
1964 coords=np.concatenate(list(coord_dict.values()))
1965 dists = cdist(coords, coords)
1966 binary_dists = np.where((dists <= contact_threshold) & (dists >= 1.0), 1.0, 0.0)
1968 binary_dists_dict={}
1970 len1 = max(mol1.get_residue_indexes())
1972 name1=mol1.get_name()
1973 name2=mol2.get_name()
1974 dists = cdist(coord_dict[mol1], coord_dict[mol2])
1975 if (name1, name2)
not in binary_dists_dict:
1976 binary_dists_dict[(name1, name2)] = np.zeros((len1,len1))
1977 binary_dists_dict[(name1, name2)] += np.where((dists <= contact_threshold) & (dists >= 1.0), 1.0, 0.0)
1978 binary_dists=np.zeros((total_len_unique,total_len_unique))
1980 for name1,name2
in binary_dists_dict:
1981 r1=index_dict[mol_names_unique[name1]]
1982 r2=index_dict[mol_names_unique[name2]]
1983 binary_dists[min(r1):max(r1)+1,min(r2):max(r2)+1] = np.where((binary_dists_dict[(name1, name2)]>=1.0),1.0,0.0)
1988 contact_freqs = binary_dists
1990 dist_maps.append(dists)
1991 av_dist_map += dists
1992 contact_freqs += binary_dists
1997 contact_freqs =-np.log(1.0-1.0/(len(cluster)+1)*contact_freqs)
1999 contact_freqs =1.0/len(cluster)*contact_freqs
2000 av_dist_map=1.0/len(cluster)*contact_freqs
2002 fig = plt.figure(figsize=(100, 100))
2003 ax = fig.add_subplot(111)
2006 gap_between_components=50
2018 prot_list=list(zip(*sorted_tuple))[1]
2021 prot_list=list(zip(*sorted_tuple))[1]
2023 prot_listx = prot_list
2024 nresx = gap_between_components + \
2025 sum([max(mol.get_residue_indexes())
2026 + gap_between_components
for mol
in prot_listx])
2029 prot_listy = prot_list
2030 nresy = gap_between_components + \
2031 sum([max(mol.get_residue_indexes())
2032 + gap_between_components
for mol
in prot_listy])
2037 res = gap_between_components
2038 for mol
in prot_listx:
2039 resoffsetx[mol] = res
2040 res += max(mol.get_residue_indexes())
2042 res += gap_between_components
2046 res = gap_between_components
2047 for mol
in prot_listy:
2048 resoffsety[mol] = res
2049 res += max(mol.get_residue_indexes())
2051 res += gap_between_components
2053 resoffsetdiagonal = {}
2054 res = gap_between_components
2055 for mol
in IMP.pmi.tools.OrderedSet(prot_listx + prot_listy):
2056 resoffsetdiagonal[mol] = res
2057 res += max(mol.get_residue_indexes())
2058 res += gap_between_components
2063 for n, prot
in enumerate(prot_listx):
2064 res = resoffsetx[prot]
2066 for proty
in prot_listy:
2067 resy = resoffsety[proty]
2068 endy = resendy[proty]
2069 ax.plot([res, res], [resy, endy], linestyle=
'-',color=
'gray', lw=0.4)
2070 ax.plot([end, end], [resy, endy], linestyle=
'-',color=
'gray', lw=0.4)
2071 xticks.append((float(res) + float(end)) / 2)
2076 for n, prot
in enumerate(prot_listy):
2077 res = resoffsety[prot]
2079 for protx
in prot_listx:
2080 resx = resoffsetx[protx]
2081 endx = resendx[protx]
2082 ax.plot([resx, endx], [res, res], linestyle=
'-',color=
'gray', lw=0.4)
2083 ax.plot([resx, endx], [end, end], linestyle=
'-',color=
'gray', lw=0.4)
2084 yticks.append((float(res) + float(end)) / 2)
2089 tmp_array = np.zeros((nresx, nresy))
2091 for px
in prot_listx:
2092 for py
in prot_listy:
2093 resx = resoffsetx[px]
2094 lengx = resendx[px] - 1
2095 resy = resoffsety[py]
2096 lengy = resendy[py] - 1
2097 indexes_x = index_dict[px]
2098 minx = min(indexes_x)
2099 maxx = max(indexes_x)
2100 indexes_y = index_dict[py]
2101 miny = min(indexes_y)
2102 maxy = max(indexes_y)
2103 tmp_array[resx:lengx,resy:lengy] = contact_freqs[minx:maxx,miny:maxy]
2104 ret[(px,py)]=np.argwhere(contact_freqs[minx:maxx,miny:maxy] == 1.0)+1
2106 cax = ax.imshow(tmp_array,
2111 interpolation=
'nearest')
2113 ax.set_xticks(xticks)
2114 ax.set_xticklabels(xlabels, rotation=90)
2115 ax.set_yticks(yticks)
2116 ax.set_yticklabels(ylabels)
2117 plt.setp(ax.get_xticklabels(), fontsize=6)
2118 plt.setp(ax.get_yticklabels(), fontsize=6)
2121 fig.set_size_inches(0.005 * nresx, 0.005 * nresy)
2122 [i.set_linewidth(2.0)
for i
in ax.spines.values()]
2127 plt.savefig(prefix+
"/contact_map."+str(cluster.cluster_id)+
".pdf", dpi=300,transparent=
"False")
2131 def plot_rmsd_matrix(self,filename):
2133 self.compute_all_pairwise_rmsd()
2134 distance_matrix = np.zeros(
2135 (len(self.stath0), len(self.stath1)))
2136 for (n0,n1)
in self.pairwise_rmsd:
2137 distance_matrix[n0, n1] = self.pairwise_rmsd[(n0,n1)]
2139 import matplotlib
as mpl
2141 import matplotlib.pylab
as pl
2142 from scipy.cluster
import hierarchy
as hrc
2144 fig = pl.figure(figsize=(10,8))
2145 ax = fig.add_subplot(212)
2146 dendrogram = hrc.dendrogram(
2147 hrc.linkage(distance_matrix),
2150 leaves_order = dendrogram[
'leaves']
2151 ax.set_xlabel(
'Model')
2152 ax.set_ylabel(
'RMSD [Angstroms]')
2154 ax2 = fig.add_subplot(221)
2156 distance_matrix[leaves_order,
2159 interpolation=
'nearest')
2160 cb = fig.colorbar(cax)
2161 cb.set_label(
'RMSD [Angstroms]')
2162 ax2.set_xlabel(
'Model')
2163 ax2.set_ylabel(
'Model')
2165 pl.savefig(filename, dpi=300)
2174 Update the cluster id numbers
2176 for n,c
in enumerate(self.clusters):
2179 def get_molecule(self, hier, name, copy):
2187 self.seldict0=IMP.pmi.tools.get_selections_dictionary(self.sel0_rmsd.get_selected_particles())
2188 self.seldict1=IMP.pmi.tools.get_selections_dictionary(self.sel1_rmsd.get_selected_particles())
2189 for mol
in self.seldict0:
2190 for sel
in self.seldict0[mol]:
2191 self.issymmetricsel[sel]=
False
2192 for mol
in self.symmetric_molecules:
2193 self.symmetric_molecules[mol]=len(self.seldict0[mol])
2194 for sel
in self.seldict0[mol]:
2195 self.issymmetricsel[sel]=
True
2201 for rb
in self.rbs1:
2204 for bead
in self.beads1:
2213 def aggregate(self, idxs, rmsd_cutoff=10, metric=IMP.atom.get_rmsd):
2215 initial filling of the clusters.
2218 print(
"clustering model "+str(n0))
2219 d0 = self.stath0[n0]
2221 print(
"creating cluster index "+str(len(self.clusters)))
2222 self.clusters.append(c)
2224 clustered = set([n0])
2226 print(
"--- trying to add model "+str(n1)+
" to cluster "+str(len(self.clusters)))
2227 d1 = self.stath1[n1]
2228 if self.alignment: self.align()
2229 rmsd, _ = self.
rmsd(metric=metric)
2230 if rmsd<rmsd_cutoff:
2231 print(
"--- model "+str(n1)+
" added, rmsd="+str(rmsd))
2235 print(
"--- model "+str(n1)+
" NOT added, rmsd="+str(rmsd))
2240 merge the clusters that have close members
2241 @param rmsd_cutoff cutoff distance in Angstorms
2247 for c0, c1
in filter(
lambda x: len(x[0].members)>1, itertools.combinations(self.clusters, 2)):
2248 n0, n1 = [c.members[0]
for c
in (c0,c1)]
2249 d0 = self.stath0[n0]
2250 d1 = self.stath1[n1]
2251 rmsd, _ = self.
rmsd()
2253 to_merge.append((c0,c1))
2255 for c0, c
in reversed(to_merge):
2259 self.clusters = [c
for c
in filter(
lambda x: len(x.members)>0, self.clusters)]
2264 returns true if c0 and c1 have members that are closer than rmsd_cutoff
2266 print(
"check close members for clusters "+str(c0.cluster_id)+
" and "+str(c1.cluster_id))
2267 for n0, n1
in itertools.product(c0.members[1:], c1.members):
2268 d0 = self.stath0[n0]
2269 d1 = self.stath1[n1]
2270 rmsd, _ = self.
rmsd(metric=metric)
2271 if rmsd<rmsd_cutoff:
2287 a function that returns the permutation best_sel of sels0 that minimizes metric
2289 best_rmsd2 = float(
'inf')
2291 if self.issymmetricsel[sels0[0]]:
2294 for offset
in range(N):
2295 order=[(offset+i)%N
for i
in range(N)]
2296 sels = [sels0[(offset+i)%N]
for i
in range(N)]
2299 r=metric(sel0, sel1)
2302 if rmsd2 < best_rmsd2:
2307 for sels
in itertools.permutations(sels0):
2309 for sel0, sel1
in itertools.takewhile(
lambda x: rmsd2<best_rmsd2, zip(sels, sels1)):
2310 r=metric(sel0, sel1)
2312 if rmsd2 < best_rmsd2:
2326 return best_sel, best_rmsd2
2328 def compute_all_pairwise_rmsd(self):
2329 for d0
in self.stath0:
2330 for d1
in self.stath1:
2331 rmsd, _ = self.
rmsd()
2333 def rmsd(self,metric=IMP.atom.get_rmsd):
2335 Computes the RMSD. Resolves ambiguous pairs assignments
2338 n0=self.stath0.current_index
2339 n1=self.stath1.current_index
2340 if ((n0,n1)
in self.pairwise_rmsd)
and ((n0,n1)
in self.pairwise_molecular_assignment):
2341 return self.pairwise_rmsd[(n0,n1)], self.pairwise_molecular_assignment[(n0,n1)]
2349 seldict_best_order={}
2350 molecular_assignment={}
2351 for molname, sels0
in self.seldict0.items():
2352 sels_best_order, best_rmsd2 = self.
rmsd_helper(sels0, self.seldict1[molname], metric)
2354 Ncoords = len(sels_best_order[0].get_selected_particles())
2355 Ncopies = len(self.seldict1[molname])
2356 total_rmsd += Ncoords*best_rmsd2
2357 total_N += Ncoords*Ncopies
2359 for sel0, sel1
in zip(sels_best_order, self.seldict1[molname]):
2360 p0 = sel0.get_selected_particles()[0]
2361 p1 = sel1.get_selected_particles()[0]
2367 molecular_assignment[(molname,c0)]=(molname,c1)
2369 total_rmsd = math.sqrt(total_rmsd/total_N)
2371 self.pairwise_rmsd[(n0,n1)]=total_rmsd
2372 self.pairwise_molecular_assignment[(n0,n1)]=molecular_assignment
2373 self.pairwise_rmsd[(n1,n0)]=total_rmsd
2374 self.pairwise_molecular_assignment[(n1,n0)]=molecular_assignment
2376 return total_rmsd, molecular_assignment
2380 Fix the reference structure for structural alignment, rmsd and chain assignemnt
2381 @param reference can be either "Absolute" (cluster center of the first cluster)
2382 or Relative (cluster center of the current cluster)
2384 if reference==
"Absolute":
2386 elif reference==
"Relative":
2387 if cluster.center_index:
2388 n0=cluster.center_index
2390 n0=cluster.members[0]
2395 compute the molecular assignemnts between multiple copies
2396 of the same sequence. It changes the Copy index of Molecules
2399 _, molecular_assignment = self.
rmsd()
2400 for (m0, c0), (m1,c1)
in molecular_assignment.items():
2401 mol0 = self.molcopydict0[m0][c0]
2402 mol1 = self.molcopydict1[m1][c1]
2405 p1.set_value(cik0,c0)
2409 Undo the Copy index assignment
2412 _, molecular_assignment = self.
rmsd()
2414 for (m0, c0), (m1,c1)
in molecular_assignment.items():
2415 mol0 = self.molcopydict0[m0][c0]
2416 mol1 = self.molcopydict1[m1][c1]
2419 p1.set_value(cik0,c1)
2426 s=
"AnalysisReplicaExchange\n"
2427 s+=
"---- number of clusters %s \n"%str(len(self.clusters))
2428 s+=
"---- number of models %s \n"%str(len(self.stath0))
2431 def __getitem__(self,int_slice_adaptor):
2432 if isinstance(int_slice_adaptor, int):
2433 return self.clusters[int_slice_adaptor]
2434 elif isinstance(int_slice_adaptor, slice):
2435 return self.__iter__(int_slice_adaptor)
2437 raise TypeError(
"Unknown Type")
2440 return len(self.clusters)
2442 def __iter__(self,slice_key=None):
2443 if slice_key
is None:
2444 for i
in range(len(self)):
2447 for i
in range(len(self))[slice_key]:
Simplify creation of constraints and movers for an IMP Hierarchy.
def rmsd
Computes the RMSD.
def set_reference
Fix the reference structure for structural alignment, rmsd and chain assignemnt.
def load_clusters
Load the clusters from a pickle file.
def precision
Compute the precision of a cluster.
Extends the functionality of IMP.atom.Molecule.
A macro for running all the basic operations of analysis.
A container for models organized into clusters.
Sample using molecular dynamics.
def aggregate
initial filling of the clusters.
A class for reading stat files (either rmf or ascii v1 and v2)
A member of a rigid body, it has internal (local) coordinates.
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Set of Python classes to create a multi-state, multi-resolution IMP hierarchy.
def prune_redundant_structures
remove structures that are similar append it to a new cluster
def rmsf
Compute the Root mean square fluctuations of a molecule in a cluster Returns an IMP.pmi.tools.OrderedDict() where the keys are the residue indexes and the value is the rmsf.
static XYZR setup_particle(Model *m, ParticleIndex pi)
Utility classes and functions for reading and storing PMI files.
def get_best_models
Given a list of stat files, read them all and find the best models.
A helper output for model evaluation.
def set_rmsd_selection
Setup the selection onto which the rmsd is computed.
def get_cluster_data
Return the model data from a cluster.
def __init__
Construction of the Class.
def get_molecules
Return list of all molecules grouped by state.
def set_data
Set the data from an external IMP.pmi.output.Data.
def undo_apply_molecular_assignments
Undo the Copy index assignment.
def set_alignment_selection
Setup the selection onto which the alignment is computed.
def rmsd_helper
a function that returns the permutation best_sel of sels0 that minimizes metric
def save_coordinates
Save the coordinates of the current cluster a single rmf file.
def clustering
Get the best scoring models, compute a distance matrix, cluster them, and create density maps...
def apply_molecular_assignments
compute the molecular assignemnts between multiple copies of the same sequence.
This class contains analysis utilities to investigate ReplicaExchange results.
Add uncertainty to a particle.
A macro to build a IMP::pmi::topology::System based on a TopologyReader object.
def merge_aggregates
merge the clusters that have close members
This class initializes the root node of the global IMP.atom.Hierarchy.
double get_distance(XYZR a, XYZR b)
Compute the sphere distance between a and b.
A class to cluster structures.
def add_protocol_output
Capture details of the modeling protocol.
static Uncertainty setup_particle(Model *m, ParticleIndex pi, Float uncertainty)
def compute_cluster_center
Compute the cluster center for a given cluster.
static bool get_is_setup(const IMP::ParticleAdaptor &p)
def get_modeling_trajectory
Get a trajectory of the modeling run, for generating demonstrative movies.
Warning related to handling of structures.
A decorator for keeping track of copies of a molecule.
static Hierarchy setup_particle(Model *m, ParticleIndex pi, ParticleIndexesAdaptor children=ParticleIndexesAdaptor())
Create a Hierarchy of level t by adding the needed attributes.
def get_trajectory_models
Given a list of stat files, read them all and find a trajectory of models.
The standard decorator for manipulating molecular structures.
Performs alignment and RMSD calculation for two sets of coordinates.
def update_seldicts
Update the seldicts.
def update_clusters
Update the cluster id numbers.
void transform(XYZ a, const algebra::Transformation3D &tr)
Apply a transformation to the particle.
def refine
Refine the clusters by merging the ones whose centers are close.
A decorator for a particle with x,y,z coordinates.
Class for easy writing of PDBs, RMFs, and stat files.
def set_symmetric
Store names of symmetric molecules.
Warning for an expected, but missing, file.
Tools for clustering and cluster analysis.
bool get_is_canonical(atom::Hierarchy h)
Walk up a PMI2 hierarchy/representations and check if the root is named System.
Transformation3D get_identity_transformation_3d()
Return a transformation that does not do anything.
Classes for writing output files and processing them.
def deprecated_object
Python decorator to mark a class as deprecated.
Sample using Monte Carlo.
Create movers and set up constraints for PMI objects.
def merge
merge two clusters
def add_state
Add a state using the topology info in a IMP::pmi::topology::TopologyReader object.
The general base class for IMP exceptions.
static SampleProvenance setup_particle(Model *m, ParticleIndex pi, std::string method, int frames, int iterations, int replicas)
class to link stat files to several rmf files
def save_data
Save the data for the whole models into a pickle file.
Class to handle individual particles of a Model object.
def execute_macro
Builds representations and sets up degrees of freedom.
def bipartite_precision
Compute the bipartite precision (ie the cross-precision) between two clusters.
def read_coordinates_of_rmfs
Read in coordinates of a set of RMF tuples.
int get_copy_index(Hierarchy h)
Walk up the hierarchy to find the current copy index.
def cluster
Cluster the models based on RMSD.
static bool get_is_setup(Model *m, ParticleIndex pi)
def save_clusters
Save the clusters into a pickle file.
def have_close_members
returns true if c0 and c1 have members that are closer than rmsd_cutoff
void add_geometries(RMF::FileHandle file, const display::GeometriesTemp &r)
Add geometries to the file.
A macro to help setup and run replica exchange.
algebra::Transformation3D get_transformation_aligning_first_to_second(const Selection &s1, const Selection &s2)
Get the transformation to align two selections.
A dictionary-like wrapper for reading and storing sequence data.
void add_provenance(Model *m, ParticleIndex pi, Provenance p)
Add provenance to part of the model.
Hierarchies get_leaves(const Selection &h)
Select hierarchy particles identified by the biological name.
Compute mean density maps from structures.
def load_data
Load the data from an external pickled file.
Support for the RMF file format for storing hierarchical molecular data and markup.
Sample using replica exchange.
Warning for probably incorrect input parameters.
def add_provenance
Add provenance information in prov (a list of _TempProvenance objects) to each of the IMP hierarchies...
Inferential scoring building on methods developed as part of the Inferential Structure Determination ...
A decorator for a particle with x,y,z coordinates and a radius.