cgal/PDB/include/CGAL/PDB/Monomer.h

314 lines
8.6 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. */
#ifndef CGAL_DSR_PDB_RESIDUE_H
#define CGAL_DSR_PDB_RESIDUE_H
#include <CGAL/PDB/basic.h>
#include <CGAL/PDB/Point.h>
#include <CGAL/PDB/Atom.h>
#include <CGAL/PDB/small_map.h>
#include <CGAL/Tools/Label.h>
#include <vector>
#include <map>
CGAL_PDB_BEGIN_NAMESPACE
//! The class representing a residue or nucleotide.
/*! All the information concerning atoms and bonds for each monomer
is stored here. To add atoms to monomers, new monomers, or bonds
to monomers, look in Monomer_data.cpp. There is documentation there
of what you need to do.
*/
class Monomer {
struct Monomer_type_tag{};
struct Atom_type_tag{};
public:
//! The labels for the types of residues.
/*!
\note These values must be packed, start from 0 and end with INV.
*/
enum Type { GLY=0, ALA, VAL, LEU, ILE,
SER, THR, CYS, MET, PRO,
ASP, ASN, GLU, GLN, LYS,
ARG, HIS, PHE, TYR, TRP,
ACE, NH2, ADE, URA, CYT, GUA, THY, INV };
//! The labels of atoms within residues
/*! These are the labels for each atom in each residue. The
identifiers are attempting to following the PDB specs. Feel free to add more if needed.
AL_N must be before AL_CA which must be before AL_C to get the backbone order correct.
*/
enum Atom_key {AL_OTHER, AL_INVALID,
AL_N, AL_CA, AL_C, AL_O,
AL_H, AL_1H, AL_2H, AL_3H,
AL_HA, AL_1HA, AL_2HA,
AL_CB, AL_HB, AL_1HB, AL_2HB, AL_3HB,
AL_OXT, AL_CH3,
AL_CG, AL_CG1, AL_CG2, AL_HG, AL_1HG, AL_2HG, //AL_HG1,
AL_1HG1, AL_2HG1, AL_3HG1, AL_1HG2,
AL_2HG2, AL_3HG2, AL_OG, AL_OG1, AL_SG,
// AL_HD1, AL_HD2,
AL_CD, AL_CD1, AL_CD2, AL_HD, AL_1HD, AL_2HD, AL_3HD, AL_1HD1,
AL_2HD1, AL_3HD1, AL_1HD2, AL_2HD2, AL_3HD2, AL_SD,
AL_OD1, AL_OD2, AL_ND1, AL_ND2,
AL_CE, AL_CE1, AL_CE2, AL_CE3, AL_HE, AL_1HE, AL_2HE,
AL_3HE, //AL_HE1, AL_HE2, AL_HE3,
AL_1HE2, AL_2HE2,
AL_OE1, AL_OE2, AL_NE, AL_NE1, AL_NE2,
AL_CZ, AL_CZ2, AL_CZ3, AL_NZ, AL_HZ, AL_1HZ, AL_2HZ,
AL_3HZ, // AL_HZ2, AL_HZ3,
AL_CH2, AL_NH1, AL_NH2, AL_OH, AL_HH, AL_1HH1,
AL_2HH1, AL_HH2, AL_1HH2, AL_2HH2,
AL_1HH3, AL_2HH3, AL_3HH3,
AL_P, AL_OP1, AL_OP2,
AL_O5p, AL_C5p, AL_H5p, AL_H5pp,
AL_C4p, AL_H4p, AL_O4p, AL_C1p, AL_H1p,
AL_C3p, AL_H3p, AL_O3p, AL_C2p, AL_H2p,
AL_H2pp, AL_O2p, AL_HO2p,
AL_N9, AL_C8, AL_H8,
AL_N7, AL_C5, AL_C4, AL_N3,
AL_C2, AL_H2, AL_N1, AL_C6, AL_N6,
AL_H61, AL_H62,
AL_O6, AL_H1, AL_N2, AL_H21, AL_H22,
AL_H6, AL_H5, AL_O2, AL_N4, AL_H41, AL_H42,
AL_H3, AL_O4, AL_C7, AL_H71, AL_H72, AL_H73,
AL_LAST_LABEL
};
//! This class defines the value_type of the Atom_iterator
class Atom_iterator_value_type: public small_map_value_type<Atom_key, Atom> {
typedef small_map_value_type<Atom_key, Atom> P;
public:
Atom_iterator_value_type(Atom_key k, const Atom &a=Atom()): P(k,a){}
Atom_iterator_value_type(){}
const Atom &atom() const {return P::data();}
Atom &atom() {return P::data();}
};
typedef small_map<Atom_iterator_value_type> Atoms;
//! Default constructor. Makes and invalid monomer.
Monomer(){}
//! Make a monomer of a given type
Monomer(Type al);
CGAL_COPY_CONSTRUCTOR(Monomer);
void copy_from(const Monomer &o);
void swap_with(Monomer &o);
//! The label for the monomer
Type type() const{
return label_;
}
CGAL_CONST_ITERATOR(Atom, atom, Atoms::const_iterator,
return atoms_.begin(),
return atoms_.end());
CGAL_ITERATOR(Atom, atom, Atoms::iterator,
return atoms_.begin(),
return atoms_.end());
CGAL_SIZE(atoms, return atoms_.size());
CGAL_FIND(Atom, Atom_key al= fix_atom_key(k);
return atoms_.find(al));
CGAL_INSERT(Atom, return insert_internal(k,m));
Atom_iterator insert_internal(Atom_key k, const Atom &a);
//! Return true if monomer of this type can have atoms of that type
bool can_have_atom(Atom_key al) const;
//! Set an atom using a string as a key
void set_atom_from_string(const char *str, const Atom &a) {
insert(atom_key(str), a);
}
//! Remove an atom from the monomer
void erase_atom(Atom_key al);
//! Write it for debugging
void dump(std::ostream &out) const;
//! Write it for debugging
std::ostream& write(std::ostream &out) const {dump(out);return out;}
//! Write the lines for a pdb file
/*!
Indices start at the start_index and the new start_index is returned.
*/
int write(char chain, int monomer_index, char insert_code, int start_index, std::ostream &out) const;
//! The Bond_iterator value_type is a pair of these
class Bond_endpoint {
Atom_const_iterator aci_;
Bond_endpoint(Atom_const_iterator aci): aci_(aci){}
friend class Monomer;
public:
Bond_endpoint(){}
Atom_key key() const {return aci_->key();}
const Atom &atom() const {return aci_->atom();}
};
//! A bond between two atoms in a monomer.
/*!
The ints refer the the atom index.
*/
typedef std::pair<Bond_endpoint, Bond_endpoint> Bond;
//! Return a list of all the bonds in the monomer
CGAL_CONST_ITERATOR(Bond, bond,
std::vector<Bond>::const_iterator,
return bonds_.begin(),
return bonds_.end());
//! The number of atoms present in the monomer
CGAL_SIZE(bonds, return bonds_.size());
//! Return a point representing the sidechain
/*! If the sidechain is empty this returns the CA
location. Otherwise it returns the location of some atom or the
average of some atom locations.
*/
Point sidechain_point() const;
//! Set whether all the inter-atom bonds are present or not.
/*!
This must be true before Monomer::bonds_begin() is called.
*/
void set_has_bonds(bool tf);
//! Return whether this monomer has the inter-atom bonds computed.
bool has_bonds() const {
return !bonds_.empty();
}
//! Return the label of the first atom along the backbone in this monomer
Atom_const_iterator front_atom() const {
if (is_amino_acid()) return find(AL_N);
else return atoms_end();
}
//! Return the label of the last atom along the backbone in this monomer
Atom_const_iterator back_atom() const {
if (is_amino_acid()) return find(AL_C);
else return atoms_end();
}
//! Return the label of the first atom along the backbone in this monomer
Atom_iterator front_atom() {
if (is_amino_acid()) return find(AL_N);
else return atoms_end();
}
//! Return the label of the last atom along the backbone in this monomer
Atom_iterator back_atom() {
if (is_amino_acid()) return find(AL_C);
else return atoms_end();
}
//----- Static functions
//! Convert a string for an amino acid type into a tag
static Type type(const std::string &st);
//! A string so you can write an amino acid type
static std::string type_string(Type rl);
//! Return the element corresponding to an atom label
static Atom::Type element(Atom_key al);
//! return the string corresponding to an atom key
static std::string atom_key_string(Atom_key al);
//! Return an atom type from a string
/*! Note, this type may be adjusted when the atoms is added to a
monomer to address naming inconsistencies.
*/
static Atom_key atom_key(const char *c);
bool is_amino_acid() const {
return label_ < ADE;
}
private:
Atom_key fix_atom_key(Atom_key atom_label) const;
/*--------------- Data members-----------------------------------*/
Atoms atoms_;
std::vector<Bond> bonds_;
Type label_;
};
//! Assign unique indices to all atoms in the monomer, starting at optional start value
/*!
This returns the next unused index.
*/
inline int index_atoms(const Monomer &m, int start=0) {
for (Monomer::Atom_const_iterator it= m.atoms_begin(); it != m.atoms_end(); ++it) {
it->atom().set_index(Atom::Index(start++));
}
return start;
}
CGAL_SWAP(Monomer);
CGAL_OUTPUT(Monomer);
CGAL_PDB_END_NAMESPACE
#endif