Main Page | Namespace List | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | Examples

Protein.h

00001 /* Copyright 2004
00002 Stanford University
00003 
00004 This file is part of the DSR PDB Library.
00005 
00006 The DSR PDB Library is free software; you can redistribute it and/or modify
00007 it under the terms of the GNU Lesser General Public License as published by
00008 the Free Software Foundation; either version 2.1 of the License, or (at your
00009 option) any later version.
00010 
00011 The DSR PDB Library is distributed in the hope that it will be useful, but
00012 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00013 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00014 License for more details.
00015 
00016 You should have received a copy of the GNU Lesser General Public License
00017 along with the DSR PDB Library; see the file COPYING.LIB.  If not, write to
00018 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00019 MA 02111-1307, USA. */
00020 
00021 #ifndef DSR_PDB_PROTEIN_H
00022 #define DSR_PDB_PROTEIN_H
00023 
00024 #include <dsrpdb/Point.h>
00025 #include <dsrpdb/Atom.h>
00026 #include <dsrpdb/Residue.h>
00027 #include <iostream>
00028 #include <vector>
00029 #include <iterator>
00030 #include <cassert>
00031 
00032 
00033 namespace dsrpdb {
00034 
00035   class Model;
00036   
00038 
00041   class Protein {
00042     friend class Model;
00043   public:
00044 
00049 
00050     typedef std::pair<Atom::Index,Atom::Index> Bond;
00051 
00059     Protein(std::istream &in, bool print_errors=false);
00060 
00062     Protein();
00063 
00065     char chain() const;
00066 
00068     void set_chain(char c);
00069     
00071     typedef std::vector<Residue>::iterator Residues_iterator;
00073     Residues_iterator residues_begin() {
00074       return residues_.begin();
00075     }
00077     Residues_iterator residues_end() {
00078       return residues_.end();
00079     }
00081     typedef std::vector<Residue>::const_iterator Const_residues_iterator;
00083     Const_residues_iterator residues_begin() const {
00084       return residues_.begin();
00085     }
00087     Const_residues_iterator residues_end() const {
00088       return residues_.end();
00089     }
00090     unsigned int number_of_residues() const {
00091       return residues_.size();
00092     }
00093 
00094     void new_residue(const Residue &res);
00095     
00097     class Atoms_iterator;
00099     Atoms_iterator atoms_begin();
00101     Atoms_iterator atoms_end();
00102 
00104     class Const_atoms_iterator;
00106     Const_atoms_iterator atoms_begin() const;
00108     Const_atoms_iterator atoms_end() const;
00110     unsigned int number_of_atoms() const;
00111 
00113     class Bonds_iterator;
00122     Bonds_iterator bonds_begin() const;
00124     Bonds_iterator bonds_end() const;
00126     unsigned int number_of_bonds() const;
00127 
00129 
00133     const Residue& residue_containing_atom(Atom::Index atom_index) const;
00135     Residue& residue_containing_atom(Atom::Index atom_index);
00136 
00138     const Atom& atom(Atom::Index atom_index) const;
00139 
00141     void set_atom(Atom::Index atom_index, const Atom &a);
00142 
00143 
00145     std::vector<Residue::Type> sequence() const;
00146 
00148     void write(std::ostream &out) const;
00150 
00154     void write_pdb(std::ostream &out) const;
00156     void dump(std::ostream &out) const;
00157 
00158 
00160 
00163     const Residue& residue(Residue::Index i) const;
00164 
00166     bool has_residue(Residue::Index i) const;
00167 
00168     /*const Atom &atom(unsigned int i) const {
00169       for (Const_residues_iterator it = residues_begin(); it != residues_.end(); ++it){
00170         
00171       }
00172       }*/
00173 
00174 
00176     bool has_bonds() const {
00177       return residues_[0].has_bonds();
00178     }
00179 
00181     void set_has_bonds(bool tf) {
00182       for (unsigned int i=0; i< residues_.size(); ++i){
00183         residues_[i].set_has_bonds(tf);
00184       }
00185     }
00186 
00187 
00188 #if 0
00189 
00190 
00193     class Backbone_coordinates_iterator;
00195     Backbone_coordinates_iterator backbone_coordinates_begin() const;
00197     Backbone_coordinates_iterator backbone_coordinates_end() const;
00198 #endif
00199     
00200   protected:
00201     void process_line(const char *line);
00202     
00203     unsigned int residue_offset_of_atom_index(Atom::Index i) const;
00204 
00205     unsigned int residue_offset(Residue::Index i) const;
00206     
00207     std::vector<Residue> residues_;
00208     std::vector<std::string> header_;
00209     //static Residue dummy_residue_;
00210     char chain_;
00211   };
00212 
00213 
00214 
00215 
00216 
00217 
00218 
00220   class Protein::Atoms_iterator {
00221     friend class Protein;
00222     friend class Protein::Const_atoms_iterator;
00223   public:
00225     typedef Atom value_type;
00226     typedef std::forward_iterator_tag iterator_category;
00227     typedef std::size_t difference_type;
00228     typedef Residue::Atoms_iterator::reference reference;
00229     typedef Residue::Atoms_iterator::pointer pointer;
00230 
00231     reference operator*() {
00232       return *ait_;
00233     }
00234     pointer operator->() {
00235       return ait_.operator->();
00236     }
00237     Atoms_iterator operator++() {
00238       ++ait_;
00239       if (ait_== aend_) {
00240         ++rit_;
00241         if (rit_!= rend_){
00242           ait_=rit_->atoms_begin();
00243           aend_= rit_->atoms_end();
00244         }
00245       }
00246       return *this;
00247     }
00248     
00249     bool operator==(const Atoms_iterator& o) const {
00250       if (rit_ == rend_) return rit_==o.rit_;
00251       else return rit_== o.rit_ && ait_ == o.ait_;
00252     }
00253     bool operator!=(const Atoms_iterator& o) const {
00254       if (rit_== rend_) return rit_!= o.rit_;
00255       else return rit_!= o.rit_ || ait_ != o.ait_;
00256     }
00257 
00258   protected:
00259     Atoms_iterator(std::vector<Residue>::iterator b, 
00260                    std::vector<Residue>::iterator e): rit_(b), rend_(e){
00261       if (b != e) {
00262         ait_= rit_->atoms_begin();
00263         aend_= rit_->atoms_end();
00264       }
00265     }
00266     std::vector<Residue>::iterator rit_, rend_;
00267     Residue::Atoms_iterator ait_, aend_;
00268   };
00269 
00270 
00272   class Protein::Const_atoms_iterator {
00273     friend class Protein;
00274   public:
00276     typedef Atom value_type;
00277     typedef std::forward_iterator_tag iterator_category;
00278     typedef std::size_t difference_type;
00279     typedef Residue::Const_atoms_iterator::reference reference;
00280     typedef Residue::Const_atoms_iterator::pointer pointer;
00281 
00282     reference operator*() const {
00283       return *ait_;
00284     }
00285     pointer operator->() const {
00286       return ait_.operator->();
00287     }
00288     Const_atoms_iterator operator++() {
00289       ++ait_;
00290       if (ait_== aend_) {
00291         ++rit_;
00292         if (rit_!= rend_){
00293           ait_=rit_->atoms_begin();
00294           aend_= rit_->atoms_end();
00295         }
00296       }
00297       return *this;
00298     }
00299     
00300     bool operator==(const Const_atoms_iterator& o) const {
00301       if (rit_ == rend_) return rit_==o.rit_;
00302       else return rit_== o.rit_ && ait_ == o.ait_;
00303     }
00304     bool operator!=(const Const_atoms_iterator& o) const {
00305       if (rit_== rend_) return rit_!= o.rit_;
00306       else return rit_!= o.rit_ || ait_ != o.ait_;
00307     }
00308 
00309     Const_atoms_iterator(Protein::Atoms_iterator it){
00310       rit_= it.rit_;
00311       rend_= it.rend_;
00312       ait_= it.ait_;
00313       aend_= it.aend_;
00314     }
00315 
00316   protected:
00317     Const_atoms_iterator(std::vector<Residue>::const_iterator b, 
00318                          std::vector<Residue>::const_iterator e): rit_(b), rend_(e){
00319       if (b != e) {
00320         ait_= rit_->atoms_begin();
00321         aend_= rit_->atoms_end();
00322       }
00323     }
00324     std::vector<Residue>::const_iterator rit_, rend_;
00325     Residue::Const_atoms_iterator ait_, aend_;
00326   };
00327 
00328 
00330   class Protein::Bonds_iterator {
00331     friend class Protein;
00332   public:
00334     typedef Bond value_type;
00335     typedef std::forward_iterator_tag iterator_category;
00336     typedef std::size_t difference_type;
00337     typedef const Bond& reference;
00338     typedef const Bond* pointer;
00339     
00340     reference operator*() const {
00341       return cur_bond();
00342     }
00343     pointer operator->() const {
00344       return &cur_bond();
00345     }
00346     Bonds_iterator operator++() {
00347       if (nc_) {
00348         nc_=false;
00349       } else {
00350         ++ait_;
00351         if (ait_== aend_) {
00352           std::vector<Residue>::const_iterator orit= rit_;
00353           ++rit_;
00354           if (rit_!= rend_){
00355             if (static_cast<unsigned int>(orit->index()) +1 == static_cast<unsigned int>(rit_->index())
00356                 && orit->has_atom(Residue::AL_C) && rit_->has_atom(Residue::AL_N)){
00357               nc_=true;
00358             } /*else {
00359               std::cout << "Skipping bond between residues " << orit->index() << " and " << rit_->index() << "\n";
00360               std::cout << static_cast<unsigned int>(orit->index()) << " " << static_cast<unsigned int>(rit_->index()) << std::endl;
00361               rit_->dump(std::cout);
00362               orit->dump(std::cout);
00363               }*/
00364             ait_=rit_->bonds_begin();
00365             aend_= rit_->bonds_end();
00366           }
00367         }
00368       }
00369       return *this;
00370     }
00371      bool operator==(const Bonds_iterator& o) const {
00372        if (rit_ == rend_) return rit_==o.rit_;
00373        else return rit_== o.rit_ && ait_ == o.ait_ && nc_== o.nc_;
00374     }
00375     bool operator!=(const Bonds_iterator& o) const {
00376       if (rit_== rend_) return rit_!= o.rit_;
00377       else return rit_!= o.rit_ || ait_ != o.ait_ || nc_ != o.nc_;
00378     }
00379     
00380     Bonds_iterator(){}
00381   protected:
00382     Bonds_iterator(std::vector<Residue>::const_iterator b, 
00383                    std::vector<Residue>::const_iterator e): rit_(b), rend_(e), nc_(false){
00384       if (b != e) {
00385         ait_= rit_->bonds_begin();
00386         aend_= rit_->bonds_end();
00387       }
00388     }
00389 
00390     const Bond &cur_bond() const {
00391       if (nc_) {
00392         assert(rit_ != rend_);
00393         static Bond b;
00394         b= Bond((rit_-1)->atom(Residue::AL_C).index(),
00395                 rit_->atom(Residue::AL_N).index());
00396         return b;
00397       } else return *ait_;
00398     }
00399 
00400     std::vector<Residue>::const_iterator rit_, rend_;
00401     Residue::Bonds_iterator ait_, aend_;
00402     bool nc_;
00403   };
00404 };
00405 
00406 
00407 #endif