def test_001(pdb_str): ''' Check keyword n_terminal_charge: NH3 on resseq 1, first residue in chain, or no NH3 at all ''' pdb_inp = iotbx.pdb.input(lines=pdb_str.split("\n"), source_info=None) # initial model model_initial = mmtbx.model.manager(model_input=pdb_inp, log=null_out()) # # place H atoms: NH3 at resseq 1 only reduce_add_h_obj = reduce_hydrogen.place_hydrogens(model=model_initial) reduce_add_h_obj.run() model_h_added = reduce_add_h_obj.get_model() # hd_sel_h_added = model_h_added.get_hd_selection() ph_h_added = model_h_added.get_hierarchy() h_atoms_added = ph_h_added.select(hd_sel_h_added).atoms() h_names_added = list(h_atoms_added.extract_name()) assert (h_names_added.count(' H1 ') == 1) assert (h_names_added.count(' H2 ') == 1) assert (h_names_added.count(' H3 ') == 1) # # place H atoms: NH3 at first residue in chain reduce_add_h_obj = reduce_hydrogen.place_hydrogens( model=model_initial, n_terminal_charge='first_in_chain') reduce_add_h_obj.run() model_h_added = reduce_add_h_obj.get_model() # hd_sel_h_added = model_h_added.get_hd_selection() ph_h_added = model_h_added.get_hierarchy() h_atoms_added = ph_h_added.select(hd_sel_h_added).atoms() h_names_added = list(h_atoms_added.extract_name()) assert (h_names_added.count(' H1 ') == 3) assert (h_names_added.count(' H2 ') == 3) assert (h_names_added.count(' H3 ') == 3) # # place H atoms: no NH3 reduce_add_h_obj = reduce_hydrogen.place_hydrogens( model=model_initial, n_terminal_charge='no_charge') reduce_add_h_obj.run() model_h_added = reduce_add_h_obj.get_model() # hd_sel_h_added = model_h_added.get_hd_selection() ph_h_added = model_h_added.get_hierarchy() h_atoms_added = ph_h_added.select(hd_sel_h_added).atoms() h_names_added = list(h_atoms_added.extract_name()) assert (h_names_added.count(' H1 ') == 0) assert (h_names_added.count(' H2 ') == 0) assert (h_names_added.count(' H3 ') == 0)
def run(self): self.model = self.data_manager.get_model() # make_sub_header('Add H atoms', out=self.logger) reduce_add_h_obj = reduce_hydrogen.place_hydrogens( model=self.model, use_neutron_distances=self.params.use_neutron_distances, n_terminal_charge=self.params.n_terminal_charge) #import line_profiler #lp = line_profiler.LineProfiler(reduce_add_h_obj.run) #lp.enable() reduce_add_h_obj.run() #lp.disable() #lp.print_stats() self.model = reduce_add_h_obj.get_model() reduce_add_h_obj.show(log=self.logger) # make_sub_header('Optimize H atoms', out=self.logger) self.model = reduce_hydrogen.optimize(model=self.model) # if (self.params.output.file_name_prefix is not None): base = self.params.output.file_name_prefix else: fp = self.data_manager.get_default_model_name() base = os.path.splitext(os.path.basename(fp))[0] of = open("%s_hydrogenate.pdb" % base, "w") of.write(self.model.model_as_pdb()) of.close()
def compare_models(pdb_str, contains=None, not_contains=None): ''' Function to compare model with new H to the known answer (pdb_str) ''' # pdb_inp = iotbx.pdb.input(lines=pdb_str.split("\n"), source_info=None) model_initial = mmtbx.model.manager(model_input=pdb_inp, log=null_out()) ph_initial = model_initial.get_hierarchy() hd_sel_initial = model_initial.get_hd_selection() h_atoms_initial = ph_initial.select(hd_sel_initial).atoms() h_names_initial = list(h_atoms_initial.extract_name()) # number of H in pdb string (right answer) number_h_expected = hd_sel_initial.count(True) # get model obj without H atoms model_without_h = model_initial.select(~hd_sel_initial) # make sure model without H indeed has no H atoms hd_sel_without_h = model_without_h.get_hd_selection() assert (hd_sel_without_h is not None) assert (hd_sel_without_h.count(True) == 0) #model_h_added = reduce.add(model = model_without_h) # place H atoms reduce_add_h_obj = reduce_hydrogen.place_hydrogens(model=model_without_h) reduce_add_h_obj.run() model_h_added = reduce_add_h_obj.get_model() hd_sel_h_added = model_h_added.get_hd_selection() ph_h_added = model_h_added.get_hierarchy() assert ph_initial.is_similar_hierarchy(other=ph_h_added) number_h_added = hd_sel_h_added.count(True) assert (number_h_expected == number_h_added) h_atoms_added = ph_h_added.select(hd_sel_h_added).atoms() h_names_added = list(h_atoms_added.extract_name()) if not_contains: assert (not_contains not in h_names_added) if contains: assert (contains in h_names_added) sc_h_initial = model_initial.select(hd_sel_initial).get_sites_cart() sc_h_added = model_h_added.select(hd_sel_h_added).get_sites_cart() d1 = { h_names_initial[i]: sc_h_initial[i] for i in range(len(h_names_initial)) } d2 = {h_names_added[i]: sc_h_added[i] for i in range(len(h_names_added))} # check that coordinates are correct for name, sc in d2.items(): assert (name in d1) assert approx_equal(sc, d1[name], 0.01)
def compare_models(pdb_str, contains=None, not_contains=None): # pdb_inp = iotbx.pdb.input(lines=pdb_str.split("\n"), source_info=None) # initial model model_initial = mmtbx.model.manager(model_input=pdb_inp, log=null_out()) hd_sel_initial = model_initial.get_hd_selection() number_h_expected = hd_sel_initial.count(True) ph_initial = model_initial.get_hierarchy() h_atoms_initial = ph_initial.select(hd_sel_initial).atoms() h_names_initial = list(h_atoms_initial.extract_name()) # remove H atoms model_without_h = model_initial.select(~hd_sel_initial) hd_sel_without_h = model_without_h.get_hd_selection() assert (hd_sel_without_h is not None) assert (hd_sel_without_h.count(True) == 0) # place H atoms again reduce_add_h_obj = reduce_hydrogen.place_hydrogens(model=model_without_h) reduce_add_h_obj.run() # model_h_added = reduce_add_h_obj.get_model() hd_sel_h_added = model_h_added.get_hd_selection() ph_h_added = model_h_added.get_hierarchy() h_atoms_added = ph_h_added.select(hd_sel_h_added).atoms() h_names_added = list(h_atoms_added.extract_name()) number_h_added = hd_sel_h_added.count(True) #f = open("bla_intermediate.pdb","w") #f.write(model_h_added.model_as_pdb()) #f.close() assert ph_initial.is_similar_hierarchy(other=ph_h_added) assert (number_h_expected == number_h_added) if not_contains: assert (not_contains not in h_names_added) if contains: assert (contains in h_names_added) sc_h_initial = model_initial.select(hd_sel_initial).get_sites_cart() sc_h_added = model_h_added.select(hd_sel_h_added).get_sites_cart() d1 = { h_names_initial[i]: sc_h_initial[i] for i in range(len(h_names_initial)) } d2 = {h_names_added[i]: sc_h_added[i] for i in range(len(h_names_added))} for name, sc in d2.items(): assert (name in d1) assert approx_equal(sc, d1[name], 0.01), name
def test_000(pdb_str): ''' Make sure reduce does not crash for single_atom_residue models ''' pdb_inp = iotbx.pdb.input(lines=pdb_str.split("\n"), source_info=None) # initial model (has no H atoms) model_initial = mmtbx.model.manager(model_input=pdb_inp, log=null_out()) number_h_expected = model_initial.get_hd_selection().count(True) assert (number_h_expected == 0) # place H atoms reduce_add_h_obj = reduce_hydrogen.place_hydrogens(model=model_initial) reduce_add_h_obj.run() # We don't expect H atoms to be placed # (not enough restraints for single atom residues) model_h_added = reduce_add_h_obj.get_model() number_h_placed = model_h_added.get_hd_selection().count(True) assert (number_h_placed == 0)
def run(self): # String describing the run that will be output to the specified file. outString = 'reduce2 v.{}, run {}\n'.format(version, datetime.now().strftime("%Y-%m-%d %H:%M:%S")) for a in sys.argv: outString += ' {}'.format(a) outString += '\n' make_sub_header('Loading Model', out=self.logger) # Get our model. self.model = self.data_manager.get_model() # Fix up bogus unit cell when it occurs by checking crystal symmetry. cs = self.model.crystal_symmetry() if (cs is None) or (cs.unit_cell() is None): self.model = shift_and_box_model(model = self.model) if self.params.approach == 'add': # Add Hydrogens to the model make_sub_header('Adding Hydrogens', out=self.logger) startAdd = work_clock() reduce_add_h_obj = reduce_hydrogen.place_hydrogens( model = self.model, n_terminal_charge=self.params.n_terminal_charge, stop_for_unknowns=True ) reduce_add_h_obj.run() self.model = reduce_add_h_obj.get_model() doneAdd = work_clock() # Interpret the model after shifting and adding Hydrogens to it so that # all of the needed fields are filled in when we use them below. # @todo Remove this once place_hydrogens() does all the interpretation we need. make_sub_header('Interpreting Hydrogenated Model', out=self.logger) startInt = work_clock() self.model.get_hierarchy().sort_atoms_in_place() self.model.get_hierarchy().atoms().reset_serial() p = mmtbx.model.manager.get_default_pdb_interpretation_params() p.pdb_interpretation.allow_polymer_cross_special_position=True p.pdb_interpretation.clash_guard.nonbonded_distance_threshold=None p.pdb_interpretation.use_neutron_distances = self.params.use_neutron_distances p.pdb_interpretation.proceed_with_excessive_length_bonds=True #p.pdb_interpretation.sort_atoms=True self.model.process(make_restraints=True, pdb_interpretation_params=p) # make restraints doneInt = work_clock() make_sub_header('Optimizing', out=self.logger) startOpt = work_clock() Optimizers.probePhil = self.params.probe opt = Optimizers.FastOptimizer(self.params.add_flip_movers, self.model, probeRadius=0.25, altID=self.params.alt_id, preferenceMagnitude=self.params.preference_magnitude) doneOpt = work_clock() outString += opt.getInfo() outString += 'Time to Add Hydrogen = '+str(doneAdd-startAdd)+'\n' outString += 'Time to Interpret = '+str(doneInt-startInt)+'\n' outString += 'Time to Optimize = '+str(doneOpt-startOpt)+'\n' else: # Removing Hydrogens from the model rather than adding them. make_sub_header('Removing Hydrogens', out=self.logger) sel = self.model.selection("element H") for a in self.model.get_atoms(): if sel[a.i_seq]: a.parent().remove_atom(a) # Re-process the model because we have removed some atoms that were previously # bonded. Don't make restraints during the reprocessing. # We had to do this to keep from crashing on a call to pair_proxies when generating # mmCIF files, so we always do it for safety. self.model.process(make_restraints=False, pdb_interpretation_params=p) make_sub_header('Writing output', out=self.logger) # Write the description output to the specified file. of = open(self.params.output.description_file_name,"w") of.write(outString) of.close() # Determine whether to write a PDB or CIF file and write the appropriate text output. # Then determine the output file name and write it there. if str(self.params.output.suffix).lower() == "pdb": txt = self.model.model_as_pdb() suffix = ".pdb" else: txt = self.model.model_as_mmcif() suffix = ".cif" if self.params.output.model_file_base_name is not None: base = self.params.output.model_file_base_name else: file_name = self.data_manager.get_model_names()[0] base = os.path.splitext(os.path.basename(file_name))[0] + "_reduced" fullname = base+suffix with open(fullname, 'w') as f: f.write(txt) print('Wrote',fullname,'and',self.params.output.description_file_name, file = self.logger) # Report profiling info if we've been asked to in the Phil parameters if self.params.profile: print('Profile results:') import pstats profile_params = {'sort_by': 'time', 'num_entries': 20} self._pr.disable() ps = pstats.Stats(self._pr).sort_stats(profile_params['sort_by']) ps.print_stats(profile_params['num_entries'])