int main(int argc, char **argv) { try { desc.add_options() ("help,h", "Print messages about any errors encountered in parsing the pdb file.") ("input-file,i", po::value< std::string >(&input), "input pdb file"); po::positional_options_description p; p.add("input-file", 1); po::variables_map vm; po::store( po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm); po::notify(vm); if (vm.count("help") || input.empty()) { print_help(); return 1; } IMP_NEW(IMP::Model, m, ()); m->set_log_level(IMP::SILENT); IMP::set_log_level(IMP::VERBOSE); IMP::atom::Hierarchies inhs; IMP_CATCH_AND_TERMINATE(inhs= IMP::atom::read_multimodel_pdb(input, m)); for (unsigned int i=0; i< inhs.size(); ++i) { IMP::atom::add_bonds(inhs[i]); } return 0; } catch (const IMP::Exception &e) { std::cerr << "Error: " << e.what() << std::endl; return 1; } catch (const std::exception &e) { std::cerr << "Error: " << e.what() << std::endl; } }
int main(int argc, char **argv) { try { std::vector<std::string> argcs = IMP::setup_from_argv( argc, argv, "Print warnings about pdb file", "input.pdb", -1); IMP::set_log_level(IMP::WARNING); for (unsigned int i = 0; i < argcs.size(); ++i) { IMP_NEW(IMP::Model, m, ()); m->set_log_level(IMP::SILENT); IMP::atom::Hierarchies inhs; IMP_CATCH_AND_TERMINATE(inhs = IMP::atom::read_multimodel_pdb(argcs[i], m)); for (unsigned int i = 0; i < inhs.size(); ++i) { IMP::atom::add_bonds(inhs[i]); } } return 0; } catch (const IMP::Exception &e) { std::cerr << "Error: " << e.what() << std::endl; return 1; } catch (const std::exception &e) { std::cerr << "Error: " << e.what() << std::endl; } }
void ResidueRotamer::set_coordinates(unsigned index, IMP::atom::Residue &rd) const { IMP_USAGE_CHECK(index < size_, "no rotamer at given index"); IMP_USAGE_CHECK(rd.get_residue_type() == residue_type_, "wrong residue type"); IMP::atom::Hierarchies mhs = IMP::atom::get_by_type(rd, IMP::atom::ATOM_TYPE); for (size_t i = 0; i != mhs.size(); ++i) { IMP::atom::Atom at = mhs[i].get_as_atom(); IMP::atom::AtomType at_t = at.get_atom_type(); if (get_atom_exists(at_t)) { const IMP::algebra::Vector3D &coords = get_coordinates(index, at_t); IMP::core::XYZ(at).set_coordinates(coords); } } }
void read_pdb(Model *model, const std::string file, std::vector<std::string>& pdb_file_names, std::vector<IMP::Particles>& particles_vec, bool residue_level, bool heavy_atoms_only, int multi_model_pdb, bool explicit_water) { IMP::atom::Hierarchies mhds; IMP::atom::PDBSelector* selector; if (residue_level) // read CA only selector = new IMP::atom::CAlphaPDBSelector(); else if (heavy_atoms_only) { // read without hydrogens if (explicit_water) selector = new IMP::atom::NonHydrogenPDBSelector(); else selector = new IMP::atom::NonWaterNonHydrogenPDBSelector(); } else { // read with hydrogens if (explicit_water) selector = new IMP::atom::NonAlternativePDBSelector(); else selector = new IMP::atom::NonWaterPDBSelector(); } if (multi_model_pdb == 2) { mhds = read_multimodel_pdb(file, model, selector, true); } else { if (multi_model_pdb == 3) { IMP::atom::Hierarchy mhd = IMP::atom::read_pdb(file, model, selector, false, true); mhds.push_back(mhd); } else { IMP::atom::Hierarchy mhd = IMP::atom::read_pdb(file, model, selector, true, true); mhds.push_back(mhd); } } for (unsigned int h_index = 0; h_index < mhds.size(); h_index++) { IMP::ParticlesTemp ps = get_by_type(mhds[h_index], IMP::atom::ATOM_TYPE); if (ps.size() > 0) { // pdb file std::string pdb_id = file; if (mhds.size() > 1) { pdb_id = trim_extension(file) + "_m" + std::string(boost::lexical_cast<std::string>(h_index + 1)) + ".pdb"; } pdb_file_names.push_back(pdb_id); particles_vec.push_back(IMP::get_as<IMP::Particles>(ps)); if (mhds.size() > 1) { IMP_LOG_TERSE(ps.size() << " atoms were read from PDB file " << file << " MODEL " << h_index + 1 << std::endl); } else { IMP_LOG_TERSE(ps.size() << " atoms were read from PDB file " << file << std::endl); } } } }
int main(int argc, char *argv[]) { IMP::Strings args = IMP::setup_from_argv(argc, argv, "Score a protein-ligand complex", "file.mol2 file.pdb [libfile]", -1); IMP::set_log_level(IMP::SILENT); std::string mol2name, pdbname; for (size_t i = 0; i < args.size(); ++i) { std::string nm(args[i]); if (nm.rfind(".mol2") == nm.size() - 5) { mol2name = nm; } else if (nm.rfind(".pdb") == nm.size() - 4) { pdbname = nm; } else { break; } } if (mol2name.empty() || pdbname.empty()) { std::cerr << "Usage: " << argv[0] << " file.mol2 file.pdb [libfile]" << std::endl; return EXIT_FAILURE; } IMP::TextInput lib; if (args.size() == 3) { lib = IMP::TextInput(args[2]); } { int lib_requested = 0; if (lib) lib_requested++; if (pose_score) lib_requested++; if (rank_score) lib_requested++; if (lib_requested > 1) { std::cerr << "Can only specify one of --pose, --rank, " << "or a library name" << std::endl; return EXIT_FAILURE; } } IMP_NEW(IMP::Model, m, ()); IMP::atom::Hierarchy p, l; { IMP::SetLogState ss(IMP::SILENT); p = IMP::atom::read_pdb(pdbname, m, new IMP::atom::ATOMPDBSelector()); IMP::atom::add_protein_ligand_score_data(p); l = IMP::atom::read_mol2(mol2name, m); IMP::atom::add_protein_ligand_score_data(l); } IMP::atom::Hierarchies mols = IMP::atom::get_by_type(l, IMP::atom::RESIDUE_TYPE); IMP::Pointer<IMP::atom::ProteinLigandAtomPairScore> ps = get_pair_score(lib); double d = ps->get_maximum_distance(); IMP_NEW(IMP::core::GridClosePairsFinder, gcpf, ()); gcpf->set_distance(d); IMP::ParticlesTemp patoms = IMP::atom::get_leaves(p); IMP::ParticleIndexes ipatoms = IMP::get_indexes(patoms); for (unsigned int i = 0; i < mols.size(); ++i) { // IMP::SetLogState ss(i==0? TERSE: IMP::SILENT); IMP::ParticlesTemp latoms = IMP::atom::get_leaves(mols[i]); IMP::ParticleIndexes ilatoms = IMP::get_indexes(latoms); IMP::ParticleIndexPairs ppt = gcpf->get_close_pairs(m, ipatoms, ilatoms); double score = ps->evaluate_indexes(m, ppt, NULL, 0, ppt.size()); std::cout << "Score for " << mols[i]->get_name() << " is " << score << std::endl; } ps->set_was_used(true); return EXIT_SUCCESS; }
void RotamerCalculator::transform(const IMP::atom::Hierarchy &protein, const IMP::PairScore *score, double thr, double K, int num_iter) const { IMP_USAGE_CHECK(protein, "protein must me non-null"); IMP::atom::Hierarchies mhs = IMP::atom::get_by_type(protein, IMP::atom::RESIDUE_TYPE); const size_t num_res = mhs.size(); ResidueRotamers rotamers; rotamers.reserve(num_res); ResidueRotamer::Boxes3D bb_boxes(num_res); ResidueRotamer::Boxes3D sc_boxes(num_res); IMP_LOG_VERBOSE("Computing bounding boxes" << std::endl); std::vector<ResidueRotamer::Boxes3D> rot_boxes(num_res); for (size_t i = 0; i != num_res; ++i) { IMP::atom::Residue rd = mhs[i].get_as_residue(); ResidueRotamer rr = get_rotamer(rd, thr); rotamers.push_back(rr); rr.create_bounding_boxes(bb_boxes[i], sc_boxes[i], rot_boxes[i]); } IMP_LOG_VERBOSE("Equation (39)" << std::endl); // implementation of equation (39) E^{BB}_{ij} std::vector<std::vector<double> > E_bb(num_res); for (size_t i = 0; i != num_res; ++i) { IMP_LOG_VERBOSE("Processing residue " << i << " out of " << num_res << std::endl); IMP::atom::Residue rd_i = mhs[i].get_as_residue(); IMP::atom::Hierarchies at_i = IMP::atom::get_by_type(rd_i, IMP::atom::ATOM_TYPE); E_bb[i].resize(rotamers[i].get_size()); // for each rotamer j... for (unsigned j = 1; j < rotamers[i].get_size(); ++j) { rotamers[i].set_coordinates(j, rd_i); // for each l in Nbr_BB(i)... for (size_t l = 0; l != num_res; ++l) if (l != i) { if (!ResidueRotamer::intersect(bb_boxes[l], sc_boxes[i])) continue; IMP::atom::Residue rd_l = mhs[i].get_as_residue(); IMP::atom::Hierarchies at_l = IMP::atom::get_by_type(rd_l, IMP::atom::ATOM_TYPE); // for each k in side chain(i)... for (size_t k = 0; k != at_i.size(); ++k) { IMP::atom::Atom at_ik = at_i[k].get_as_atom(); if (is_backbone(at_ik.get_atom_type().get_index())) continue; // for each n in backbone(l)... for (size_t n = 0; n != at_l.size(); ++n) { IMP::atom::Atom at_ln = at_l[n].get_as_atom(); if (!is_backbone(at_ln.get_atom_type().get_index())) continue; E_bb[i][j] += score->evaluate_index( protein->get_model(), IMP::ParticleIndexPair( at_ik.get_particle()->get_index(), at_ln.get_particle()->get_index()), nullptr); } } } rotamers[i].set_coordinates(0, rd_i); } } // now we are ready to compute eq. (41) and (42) std::vector<std::vector<double> > E_P(num_res); std::vector<std::vector<double> > q(num_res); for (size_t i = 0; i != num_res; ++i) { E_P[i].resize(rotamers[i].get_size()); q[i].resize(rotamers[i].get_size()); } // we will need to iterate num_iter times for (int iter = 0; iter < num_iter; ++iter) { IMP_LOG_VERBOSE("Equation (41), iteration " << iter << std::endl); // equation (41)... for (size_t i = 0; i != num_res; ++i) { IMP::atom::Residue rd_i = mhs[i].get_as_residue(); IMP::atom::Hierarchies at_i = IMP::atom::get_by_type(rd_i, IMP::atom::ATOM_TYPE); for (unsigned j = 1; j < rotamers[i].get_size(); ++j) { E_P[i][j] = E_bb[i][j]; for (size_t l = 0; l != num_res; ++l) if (l != i) { IMP::atom::Residue rd_l = mhs[l].get_as_residue(); IMP::atom::Hierarchies at_l = IMP::atom::get_by_type(rd_l, IMP::atom::ATOM_TYPE); for (unsigned m = 1; m < rotamers[l].get_size(); ++m) { if (!ResidueRotamer::intersect(rot_boxes[i][j], rot_boxes[l][m])) continue; double q_lm = rotamers[l].get_probability(m); // now compute E^SC_{ijlm} from eq. (40) double E_SC = 0; rotamers[i].set_coordinates(j, rd_i); rotamers[l].set_coordinates(m, rd_l); // for k in side-chain(i)... for (size_t k = 0; k != at_i.size(); ++k) { IMP::atom::Atom at_ik = at_i[k].get_as_atom(); if (is_backbone(at_ik.get_atom_type().get_index())) continue; // for n in side-chain(l)... for (size_t n = 0; n != at_l.size(); ++n) { IMP::atom::Atom at_ln = at_l[n].get_as_atom(); if (is_backbone(at_ln.get_atom_type().get_index())) continue; E_SC += score->evaluate_index( protein->get_model(), IMP::ParticleIndexPair( at_ik.get_particle()->get_index(), at_ln.get_particle()->get_index()), nullptr); } } rotamers[i].set_coordinates(0, rd_i); rotamers[l].set_coordinates(0, rd_l); E_P[i][j] += q_lm * E_SC; } } } } IMP_LOG_VERBOSE("Equation (42), iteration " << iter << std::endl); // equation (42)... for (size_t i = 0; i != num_res; ++i) { double denom = 0; for (unsigned k = 1; k < rotamers[i].get_size(); ++k) { // IMP_LOG_VERBOSE( "E_P[" << i << "][" << k << "] = " << E_P[i][k] << // std::endl); // IMP_LOG_VERBOSE( "P[" << i << "][" << k << "] = " << // rotamers[i].get_probability(k) << std::endl); denom += std::exp(-K * E_P[i][k]) * rotamers[i].get_probability(k); } for (unsigned j = 1; j < rotamers[i].get_size(); ++j) { q[i][j] = std::exp(-K * E_P[i][j]) * rotamers[i].get_probability(j) / denom; // IMP_LOG_VERBOSE( "Computed q[" << i << "][" << j << "] = " << // q[i][j] << std::endl); } } // store new probabilities for (size_t i = 0; i != num_res; ++i) for (unsigned j = 1; j < rotamers[i].get_size(); ++j) rotamers[i].probabilities_[j] = q[i][j]; } // now we are ready to transform - choose max probability IMP_LOG_VERBOSE("Transforming all residues" << std::endl); for (size_t i = 0; i != num_res; ++i) { IMP::atom::Residue rd_i = mhs[i].get_as_residue(); // find max probability unsigned best = 0; double best_prob = 0; for (unsigned j = 1; j < rotamers[i].get_size(); ++j) if (rotamers[i].get_probability(j) > best_prob) { best_prob = rotamers[i].get_probability(j); best = j; } if (best > 0) { IMP_LOG_VERBOSE("Setting coordinates for residue " << rd_i << std::endl); rotamers[i].set_coordinates(best, rd_i); } } }
ResidueRotamer RotamerCalculator::get_rotamer(const IMP::atom::Residue &rd, double thr) const { IMP::atom::ResidueType rt = rd.get_residue_type(); ResidueRotamer r(rt); // the coordinates at index 0 are the original coordinates IMP::atom::Hierarchies mhs = IMP::atom::get_by_type(rd, IMP::atom::ATOM_TYPE); for (size_t i = 0; i != mhs.size(); ++i) { IMP::atom::Atom at = mhs[i].get_as_atom(); r.add_coordinates(at.get_atom_type(), IMP::core::XYZ(at).get_coordinates()); } r.size_ = 1; r.probabilities_.push_back(0); // unknown residue will not be rotated unsigned r_idx = rt.get_index(); if (r_idx >= residues_.size() || residues_[r_idx].empty()) { IMP_LOG_VERBOSE("Residue " << rt << " is unknown" << std::endl); return r; } // query the rotamer library for chi-angles (the library stores angles // in degrees) const double to_deg = 180 / IMP::PI, from_deg = IMP::PI / 180; double psi = get_psi_angle(rd) * to_deg, phi = get_phi_angle(rd) * to_deg; RotamerLibrary::RotamerRange rr = rl_->get_rotamers_fast(rt, phi, psi, thr); // we need to create fake particles representing rotated atoms // (for get_dihedral) IMP_NEW(IMP::Model, model, ()); IMP_NEW(IMP::Particle, p_a, (model)); IMP_NEW(IMP::Particle, p_b, (model)); IMP_NEW(IMP::Particle, p_c, (model)); IMP_NEW(IMP::Particle, p_d, (model)); IMP::core::XYZ xyz_a = IMP::core::XYZ::setup_particle(p_a); IMP::core::XYZ xyz_b = IMP::core::XYZ::setup_particle(p_b); IMP::core::XYZ xyz_c = IMP::core::XYZ::setup_particle(p_c); IMP::core::XYZ xyz_d = IMP::core::XYZ::setup_particle(p_d); const ResidueData &res_data = residues_[r_idx]; // iterate through all sets of chi angles for (RotamerLibrary::RotamerIterator p = rr.begin(); p != rr.end(); ++p) { r.push_coordinates(); const RotamerAngleTuple &ra = *p; r.probabilities_.push_back(ra.get_probability()); double desired_angles[4] = { ra.get_chi1() * from_deg, ra.get_chi2() * from_deg, ra.get_chi3() * from_deg, ra.get_chi4() * from_deg}; // iterate through chi-angles for (int i = 0; i < res_data.n_angles; ++i) { // find the axis atoms // sometimes the required atoms are missing - log and skip the rotation // in these cases bool complete = true; IMP::atom::Atom at_a = IMP::atom::get_atom(rd, res_data.at_axes[i]); if (!at_a) { IMP_LOG_VERBOSE("Residue " << rt << ": no atom of type " << res_data.at_axes[i] << std::endl); complete = false; } IMP::atom::Atom at_b = IMP::atom::get_atom(rd, res_data.at_axes[i + 1]); if (!at_b) { IMP_LOG_VERBOSE("Residue " << rt << ": no atom of type " << res_data.at_axes[i + 1] << std::endl); complete = false; } IMP::atom::Atom at_c = IMP::atom::get_atom(rd, res_data.at_axes[i + 2]); if (!at_c) { IMP_LOG_VERBOSE("Residue " << rt << ": no atom of type " << res_data.at_axes[i + 2] << std::endl); complete = false; } IMP::atom::Atom at_d = IMP::atom::get_atom(rd, res_data.at_axes[i + 3]); if (!at_d) { IMP_LOG_VERBOSE("Residue " << rt << ": no atom of type " << res_data.at_axes[i + 3] << std::endl); complete = false; } if (!complete) break; // get the current coordinates of the axis atoms IMP::algebra::Vector3D &c_a = r.get_coordinates(at_a.get_atom_type()); IMP::algebra::Vector3D &c_b = r.get_coordinates(at_b.get_atom_type()); IMP::algebra::Vector3D &c_c = r.get_coordinates(at_c.get_atom_type()); IMP::algebra::Vector3D &c_d = r.get_coordinates(at_d.get_atom_type()); xyz_a.set_coordinates(c_a); xyz_b.set_coordinates(c_b); xyz_c.set_coordinates(c_c); xyz_d.set_coordinates(c_d); // compute the original dihedral angle double actual_angle = IMP::core::get_dihedral(xyz_a, xyz_b, xyz_c, xyz_d); // now perform the rotations (about c_b->c_c axis) and store the // coordinates int mask = 1 << i; IMP::algebra::Vector3D rot_axis = c_c - c_b; IMP::algebra::Rotation3D rot = IMP::algebra::get_rotation_about_axis( rot_axis, desired_angles[i] - actual_angle); IMP::algebra::Transformation3D t = IMP::algebra::get_rotation_about_point(c_b, rot); for (size_t k = 0; k != mhs.size(); ++k) { IMP::atom::Atom at = mhs[k].get_as_atom(); IMP::atom::AtomType at_type = at.get_atom_type(); unsigned at_idx = at_type.get_index(); if (at_idx < res_data.rot_atoms.size() && (res_data.rot_atoms[at_idx] & mask)) { // Atom "at" participates in this rotation IMP::algebra::Vector3D ¤t = r.get_coordinates(at_type); current = t.get_transformed(current); } } } } return r; }