def make_restraints(m, comp_id, mogul_dir, mogul_file_name_stub, pdb_out_file_name, mmcif_dict_name, quartet_planes, quartet_hydrogen_planes, use_mmff, match_atom_names_to_dict_flag, comp_id_list_for_names_match, dict_files_for_names_match): # test here (or in calling functions) if m is sane (i.e. is an rdkit molecule) if not isinstance(m, Chem.rdchem.Mol): print 'ERROR:: not a molecule' return False n_attempts = 20 * m.GetNumAtoms() # default is 10 * number of atoms. # pH-dependent protonation or deprotonation # do_hydrogen_atoms_shift = True try: compound_name = m.GetProp('_Name'); except KeyError: # this happens all the time when we start from a SMILES, users don't need to see it. # print 'caught key error in trying to get _Name in make_restraints() for m' compound_name = '.' except AttributeError as e: # Do we need to see this? Perhaps make_restraints() needs to return a status. # print 'AttributeError: problem with molecule in make_restraints()', e, ' on object:', m return m_H = m if n_hydrogens(m) == 0: m_H = AllChem.AddHs(m) if do_hydrogen_atoms_shift: # simple sane pH H-exchanges sane_H_mol = pyrogen_boost.hydrogen_transformations(m_H) # print >>file('sane_H.mol','w+'),Chem.MolToMolBlock(sane_H_mol) else: sane_H_mol = m_H # This makes UFF types, which can fail sometimes. conf_id = AllChem.EmbedMolecule(sane_H_mol, maxAttempts=n_attempts) if use_mmff: AllChem.MMFFOptimizeMolecule(sane_H_mol, confId=conf_id) if False: # debugging output ba = pyrogen_boost.mmff_bonds_and_angles(sane_H_mol) # uses _forcefield_ of the molecule n_bonds = ba.bonds_size() if n_bonds > 0: for i_bond in range(n_bonds): bond = ba.get_bond(i_bond) print bond.get_idx_1(), bond.get_idx_2(), bond.get_type(), \ bond.get_resting_bond_length(), bond.get_sigma() n_angles = ba.angles_size() if n_angles > 0: for i_angle in range(n_angles): angle = ba.get_angle(i_angle) print angle.get_idx_1(), angle.get_idx_2(), angle.get_idx_3(), \ angle.get_resting_angle(), angle.get_sigma() else: AllChem.UFFOptimizeMolecule(sane_H_mol, confId=conf_id) # AllChem.UFFOptimizeMolecule(sane_H_mol) atom_names = add_atom_names(sane_H_mol) all_set = atom_types.set_atom_types(sane_H_mol) # has deloc bonds now, potentially # debug sane_H_mol if True: molblock = Chem.MolToMolBlock(sane_H_mol) print >> file("sane_H_mol.mol",'w'), molblock if (all_set != True): return False else: sane_H_mol.SetProp('comp_id', comp_id) sane_H_mol.SetProp('name', compound_name) sd_local = mogul_file_name_stub + ".sdf" sdf_file_name = os.path.join(mogul_dir, mogul_file_name_stub + '-mogul.sdf') mogul_ins_file_name = os.path.join(mogul_dir, mogul_file_name_stub + '-mogul.ins') mogul_out_file_name = os.path.join(mogul_dir, mogul_file_name_stub + '-mogul.out') Chem.AllChem.ComputeGasteigerCharges(sane_H_mol) moguled_mol = pyrogen_boost.mogulify(sane_H_mol) # Nitro bond orders (and other things?) if not os.path.isdir(mogul_dir): checked_mkdir(mogul_dir) if os.path.isdir(mogul_dir): mb = Chem.MolToMolBlock(moguled_mol) print >> file(sdf_file_name,'w'), mb else: mb = Chem.MolToMolBlock(moguled_mol) print >> file(sdf_file_name,'w'), mb bor = make_restraints_for_bond_orders(sane_H_mol) # print out the set types: print_atom_props = False if print_atom_props: print '--- Atom Props ---' for atom in sane_H_mol.GetAtoms(): charge = atom.GetProp('_GasteigerCharge') # string? name = atom.GetProp('name') try: atom_type = atom.GetProp('atom_type') is_aromatic = atom.GetIsAromatic() hybrid = atom.GetHybridization() f_charge = float(charge) if print_atom_props: print " atom: %s %s type: %s arom: %s hybrid: %s charge: %6.3f" % (name, atom.GetSymbol(), atom_type.ljust(4), str(is_aromatic).ljust(5), str(hybrid).rjust(3), f_charge) except KeyError: print "miss", name, atom.GetSymbol(), charge # replace_with_mmff_b_a_restraints = False if use_mmff: replace_with_mmff_b_a_restraints = True # execute_mogul() tests if mogul is executable # mogul_state = execute_mogul(sdf_file_name, mogul_ins_file_name, mogul_out_file_name) if mogul_state: # Here we need to think about matching to reference # dictionary of amino acids (for standard atom names). # That function takes a dictionary and a mmdb::Residue. # How does that fit in here? # restraints = pysw.mogul_out_to_mmcif_dict_by_mol(mogul_out_file_name, comp_id, compound_name, sane_H_mol, bor, mmcif_dict_name, # not used quartet_planes, quartet_hydrogen_planes, replace_with_mmff_b_a_restraints) # match_atom_names_to_dict_flag, comp_id_list_for_names_match, dict_file_for_names_match if match_atom_names_to_dict_flag: restraints = atom_match_dictionary(restraints, sane_H_mol, comp_id_list_for_names_match, dict_files_for_names_match) pysw.write_restraints(restraints, mmcif_dict_name) pysw.regularize_and_write_pdb(sane_H_mol, restraints, comp_id, pdb_out_file_name) else: # mogul failed or was not in the path: if run_mogul == False: # ... but that's OK if we told pyrogen to run without mogul # sane_H_mol: # print >>file('debug_sane_H.mol','w+'),Chem.MolToMolBlock(sane_H_mol) restraints = pysw.mmcif_dict_from_mol(comp_id, compound_name, sane_H_mol, mmcif_dict_name, quartet_planes, quartet_hydrogen_planes, replace_with_mmff_b_a_restraints) if restraints == None: print "No restraints" return True # hacked in value if match_atom_names_to_dict_flag: restraints = atom_match_dictionary(restraints, sane_H_mol, comp_id_list_for_names_match, dict_files_for_names_match) pysw.write_restraints(restraints, mmcif_dict_name) pysw.write_pdb_from_mol(sane_H_mol, comp_id, pdb_out_file_name) else: # ... but not if we wanted to use mogul. # (We get here if there is a licence error for mogul) exit(1) return sane_H_mol