348 lines
12 KiB
C++
348 lines
12 KiB
C++
/* Copyright 2004
|
|
Stanford University
|
|
|
|
This file is part of the DSR PDB Library.
|
|
|
|
The DSR PDB Library is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation; either version 2.1 of the License, or (at your
|
|
option) any later version.
|
|
|
|
The DSR PDB Library is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with the DSR PDB Library; see the file LICENSE.LGPL. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
MA 02110-1301, USA. */
|
|
|
|
#include <CGAL/PDB/Protein.h>
|
|
#include <CGAL/PDB/Residue.h>
|
|
#include <CGAL/PDB/internal/Error_logger.h>
|
|
#include <sstream>
|
|
CGAL_PDB_BEGIN_NAMESPACE
|
|
|
|
static Residue dummy_residue_;
|
|
static Atom dummy_atom_;
|
|
|
|
Protein::Protein(): chain_(' '){}
|
|
|
|
char Protein::chain() const {return chain_;}
|
|
|
|
void Protein::set_chain(char c) {chain_=c;}
|
|
|
|
/*bProtein::Protein(const dsr::vector<Residue_label> &seq) {
|
|
for (unsigned int i=0; i< seq.size(); ++i){
|
|
residues_.push_back(Residue::new_residue(seq[i]));
|
|
}
|
|
model_=1;
|
|
};*/
|
|
|
|
|
|
std::vector<Residue::Type> Protein::sequence() const{
|
|
std::vector<Residue::Type> ret(residues_.size());
|
|
for (unsigned int i=0; i< residues_.size(); ++i){
|
|
ret[i]= residues_[i].type();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
unsigned int Protein::number_of_atoms() const {
|
|
unsigned int ret=0;
|
|
for (unsigned int i=0; i< residues_.size(); ++i){
|
|
ret += residues_[i].number_of_atoms();
|
|
}
|
|
return ret;
|
|
}
|
|
unsigned int Protein::number_of_bonds() const {
|
|
unsigned int ret=0;
|
|
for (unsigned int i=0; i< residues_.size(); ++i){
|
|
ret += residues_[i].number_of_bonds();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
void Protein::dump(std::ostream &out) const {
|
|
for (unsigned int i=0; i< residues_.size(); ++i){
|
|
out << "Residue " << residues_[i].index() << std::endl;
|
|
residues_[i].dump(out);
|
|
}
|
|
}
|
|
|
|
void Protein::new_residue(const Residue &res){
|
|
if (!residues_.empty() && res.index() <= residues_.back().index()){
|
|
std::ostringstream eout;
|
|
eout << "Warning, newly added residue has index "<< res.index()
|
|
<< " while previous residue has index " << residues_.back().index();
|
|
CGAL_PDB_INTERNAL_NS::error_logger.new_warning(eout.str().c_str());
|
|
}
|
|
if (!residues_.empty() && !residues_.back().has_atom(Residue::AL_C)) {
|
|
std::ostringstream eout;
|
|
eout << "Warning, newly added residue " << residues_.back().index()
|
|
<< " either missing atom C or atoms out of order in pdb.";
|
|
CGAL_PDB_INTERNAL_NS::error_logger.new_warning(eout.str().c_str());
|
|
}
|
|
if (!residues_.empty() && !residues_.back().has_atom(Residue::AL_N)) {
|
|
std::ostringstream eout;
|
|
eout << "Warning, newly added residue " << residues_.back().index()
|
|
<< " either missing atom N or atoms out of order in pdb.";
|
|
CGAL_PDB_INTERNAL_NS::error_logger.new_warning(eout.str().c_str());
|
|
}
|
|
if (!residues_.empty() && !residues_.back().has_atom(Residue::AL_CA)) {
|
|
std::ostringstream eout;
|
|
eout << "Warning, newly added residue " << residues_.back().index()
|
|
<< " either missing atom CA or atoms out of order in pdb. ";
|
|
CGAL_PDB_INTERNAL_NS::error_logger.new_warning(eout.str().c_str());
|
|
}
|
|
residues_.push_back(res);
|
|
//residues_.back().write('t', std::cout);
|
|
}
|
|
|
|
#if 0
|
|
Protein::Graph Protein::graph() const {
|
|
std::vector<Point> points;
|
|
std::vector<std::pair<int,int> > edges;
|
|
//std::map<int,int> index_index_map;
|
|
int max_index=-1;
|
|
for (unsigned int i=0; i< residues_.size(); ++i){
|
|
const Residue &r= residues_[i];
|
|
//dsr::vector<Residue::Atom_label> als= r->atoms();
|
|
//dsr::vector<Residue::Bond> bls= r->bonds();
|
|
|
|
/*for (Residue::Atoms_iterator it= r->atoms_begin(); it != r->atoms_end(); ++it){
|
|
index_index_map[it->index()]= index_index_map.size();
|
|
}*/
|
|
for (Residue::Bonds_iterator bit= r.bonds_begin(); bit != r.bonds_end(); ++bit){
|
|
edges.push_back(std::pair<int,int>(bit->first,
|
|
bit->second));
|
|
max_index= (std::max)(max_index, bit->first);
|
|
max_index= (std::max)(max_index, bit->second);
|
|
}
|
|
if (i!= 0){
|
|
edges.push_back(std::pair<int,int>(r.atom(Residue::AL_N).index(),
|
|
residues_[i-1].atom(Residue::AL_C).index()));
|
|
}
|
|
}
|
|
|
|
points.resize(max_index);
|
|
for (unsigned int i=0; i< residues_.size(); ++i){
|
|
const Residue &r= residues_[i];
|
|
for (Residue::Atoms_iterator it= r.atoms_begin(); it != r.atoms_end(); ++it){
|
|
points[it->second.index()]= it->second.cartesian_coords();
|
|
}
|
|
}
|
|
return Graph(points,edges);
|
|
}
|
|
|
|
std::vector<Point> Protein::backbone() const {
|
|
// skip ACE, probably should do something more clever
|
|
std::vector<Point> pts;
|
|
for (Const_residues_iterator it= residues_begin(); it != residues_.end(); ++it) {
|
|
const Residue &aa= *it;
|
|
|
|
for (Residue::Atoms_iterator it= aa.atoms_begin(); it != aa.atoms_end(); ++it){
|
|
if (it->first == Residue::AL_C || it->first== Residue::AL_CA || it->first== Residue::AL_N) {
|
|
Point pt=it->second.cartesian_coords();
|
|
pts.push_back(pt);
|
|
}
|
|
}
|
|
}
|
|
return pts;
|
|
}
|
|
#endif
|
|
|
|
Protein::Atoms_iterator Protein::atoms_begin() {
|
|
return Atoms_iterator(residues_.begin(), residues_.end());
|
|
}
|
|
Protein::Atoms_iterator Protein::atoms_end() {
|
|
return Atoms_iterator(residues_.end(), residues_.end());
|
|
}
|
|
|
|
Protein::Const_atoms_iterator Protein::atoms_begin() const{
|
|
return Const_atoms_iterator(residues_.begin(), residues_.end());
|
|
}
|
|
Protein::Const_atoms_iterator Protein::atoms_end() const{
|
|
return Const_atoms_iterator(residues_.end(), residues_.end());
|
|
}
|
|
Protein::Bonds_iterator Protein::bonds_begin() const{
|
|
CGAL_PDB_INTERNAL_NS::error_logger.new_warning("bonds_begin() called without has_bonds() being true.\n");
|
|
return Bonds_iterator(residues_.begin(), residues_.end());
|
|
}
|
|
Protein::Bonds_iterator Protein::bonds_end() const{
|
|
return Bonds_iterator(residues_.end(), residues_.end());
|
|
}
|
|
|
|
const Residue& Protein::residue(Residue::Index i) const{
|
|
unsigned int cur= residue_offset(i);
|
|
if (cur == residues_.size()){
|
|
std::ostringstream oss;
|
|
oss << "residue(int) called with index that does not correspond to a valid residue: " << i;
|
|
CGAL_PDB_INTERNAL_NS::error_logger.new_warning(oss.str().c_str());
|
|
return dummy_residue_;
|
|
} else {
|
|
return residues_[cur];
|
|
}
|
|
}
|
|
|
|
bool Protein::has_residue(Residue::Index i) const {
|
|
return residue_offset(i) != residues_.size();
|
|
}
|
|
|
|
unsigned int Protein::residue_offset(Residue::Index i) const {
|
|
unsigned int cur= residues_.size();
|
|
if (!residues_.empty()){
|
|
cur = std::min BOOST_PREVENT_MACRO_SUBSTITUTION(i.to_index(), cur-1);
|
|
if (residues_[cur].index() > i) {
|
|
do {
|
|
--cur;
|
|
} while (cur > 0 && residues_[cur].index() > i);
|
|
} else if (residues_[cur].index() < i) {
|
|
do {
|
|
--cur;
|
|
} while (cur < residues_.size() && residues_[cur].index() < i);
|
|
}
|
|
if (residues_[cur].index() != i) cur= residues_.size();
|
|
}
|
|
return cur;
|
|
}
|
|
|
|
unsigned int Protein::residue_offset_of_atom_index(Atom::Index index) const {
|
|
for (int i= residues_.size()-1; i >=0; --i) {
|
|
if (residues_[i].min_atom_index() <= index) return i;
|
|
}
|
|
return residues_.size();
|
|
}
|
|
|
|
void Protein::set_atom(Atom::Index index, const Atom &a) {
|
|
unsigned int ind= residue_offset_of_atom_index(index);
|
|
if (ind == residues_.size()) {
|
|
std::ostringstream oss;
|
|
oss << "set_atom called with index " << index << " which does not corresponding to an existing atom.";
|
|
CGAL_PDB_INTERNAL_NS::error_logger.new_warning(oss.str().c_str());
|
|
} else {
|
|
residues_[ind].atoms_iterator_from_index(index)->second=a;
|
|
}
|
|
//if (!min_atom_index_ || a.index() < min_atom_index_) min_atom_index_=a.index();
|
|
}
|
|
|
|
const Atom& Protein::atom(Atom::Index index) const {
|
|
unsigned int ind= residue_offset_of_atom_index(index);
|
|
if (ind == residues_.size()) {
|
|
std::ostringstream oss;
|
|
oss << "set_atom called with index " << index << " which does not corresponding to an existing atom.";
|
|
CGAL_PDB_INTERNAL_NS::error_logger.new_warning(oss.str().c_str());
|
|
return dummy_atom_;
|
|
} else {
|
|
return residues_[ind].atoms_iterator_from_index(index)->second;
|
|
}
|
|
}
|
|
|
|
void Protein::erase_atom(Atom::Index index) {
|
|
unsigned int ind= residue_offset_of_atom_index(index);
|
|
if (ind == residues_.size()) {
|
|
} else {
|
|
residues_[ind].erase_atom(residues_[ind].atom_label(index));
|
|
}
|
|
}
|
|
|
|
Atom::Index Protein::parent_atom(Atom::Index index) const {
|
|
unsigned int ind= residue_offset_of_atom_index(index);
|
|
if (ind == residues_.size()) {
|
|
std::ostringstream oss;
|
|
oss << "parent_atom called with index " << index << " which does not corresponding to an existing atom.";
|
|
CGAL_PDB_INTERNAL_NS::error_logger.new_warning(oss.str().c_str());
|
|
return Atom::Index();
|
|
} else {
|
|
Residue::Atom_label al= residues_[ind].atoms_iterator_from_index(index)->first;
|
|
if (al != Residue::AL_CA && al != Residue::AL_C && al != Residue::AL_N) {
|
|
std::ostringstream oss;
|
|
oss << "parent_atom called with an atom which was not an N, CA or C.";
|
|
CGAL_PDB_INTERNAL_NS::error_logger.new_warning(oss.str().c_str());
|
|
return Atom::Index();
|
|
}
|
|
if (al == Residue::AL_C) {
|
|
return residues_[ind].atom(Residue::AL_CA).index();
|
|
} else if (al == Residue::AL_CA) {
|
|
return residues_[ind].atom(Residue::AL_N).index();
|
|
} else {
|
|
if (ind==0) return Atom::Index();
|
|
else return residues_[ind-1].atom(Residue::AL_C).index();
|
|
}
|
|
}
|
|
}
|
|
|
|
Spherical_point Protein::spherical_coordinates(Atom::Index index) const {
|
|
Atom::Index p= parent_atom(index);
|
|
Point pc(100000, 100000, 100000);
|
|
Point popc(100000, -100000, 100000);
|
|
Point popopc(100000, -100000, -100000);
|
|
if (p != Atom::Index()) {
|
|
pc= atom(p).cartesian_coords();
|
|
Atom::Index pop= parent_atom(p);
|
|
if (pop != Atom::Index()) {
|
|
popc= atom(pop).cartesian_coords();
|
|
Atom::Index popop= parent_atom(pop);
|
|
if (popop != Atom::Index()){
|
|
popopc= atom(popop).cartesian_coords();
|
|
}
|
|
}
|
|
}
|
|
Construct_spherical_point csp(pc, popc, popopc);
|
|
return csp(atom(index).cartesian_coords());
|
|
}
|
|
|
|
|
|
const Residue& Protein::residue_containing_atom(Atom::Index atom_index) const{
|
|
unsigned int rindex= residue_offset_of_atom_index(atom_index);
|
|
if (rindex == residues_.size() || residues_[rindex].atom_label(atom_index) == Residue::AL_INVALID) {
|
|
std::ostringstream oss;
|
|
oss << "Protein::atom_label_of_atom() called with uninitialized atom " << atom_index;
|
|
CGAL_PDB_INTERNAL_NS::error_logger.new_warning(oss.str().c_str());
|
|
return dummy_residue_;
|
|
}
|
|
return residues_[rindex];
|
|
}
|
|
|
|
Residue& Protein::residue_containing_atom(Atom::Index atom_index) {
|
|
unsigned int rindex= residue_offset_of_atom_index(atom_index);
|
|
if (rindex == residues_.size() || residues_[rindex].atom_label(atom_index) == Residue::AL_INVALID) {
|
|
std::ostringstream oss;
|
|
oss << "Protein::atom_label_of_atom() called with uninitialized atom " << atom_index;
|
|
CGAL_PDB_INTERNAL_NS::error_logger.new_warning(oss.str().c_str());
|
|
return dummy_residue_;
|
|
}
|
|
return residues_[rindex];
|
|
}
|
|
|
|
/*Residue::Atom_label Protein::atom_label_of_atom(int atom_index) const {
|
|
int rindex= residue_index_of_atom_index(atom_index);
|
|
Residue::Const_atoms_iterator it= residues_[rindex].atoms_iterator_from_index(atom_index);
|
|
if (it == residues_[rindex].atoms_end()) {
|
|
std::ostringstream oss;
|
|
oss << "Protein::atom_label_of_atom() called with uninitialized atom " << atom_index;
|
|
CGAL_PDB_INTERNAL_NS::error_logger.new_warning(oss.str().c_str());
|
|
return Residue::AL_INVALID;
|
|
} else {
|
|
return it->first;
|
|
}
|
|
}*/
|
|
|
|
#if 0
|
|
Protein::Backbone_coordinates_iterator Protein::backbone_coordinates_begin() const{
|
|
if (residues_.empty()){
|
|
Backbone_coordinates_iterator b(residues_.begin(), residues_.end());
|
|
Backbone_coordinates_iterator e(residues_.begin(), residues_.end());
|
|
assert(b==e);
|
|
}
|
|
return Backbone_coordinates_iterator(residues_.begin(), residues_.end());
|
|
}
|
|
Protein::Backbone_coordinates_iterator Protein::backbone_coordinates_end() const{
|
|
return Backbone_coordinates_iterator(residues_.end(), residues_.end());
|
|
}
|
|
#endif
|
|
CGAL_PDB_END_NAMESPACE
|