All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
PDB.cpp
Go to the documentation of this file.
1 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2  Copyright (c) 2013 The plumed team
3  (see the PEOPLE file at the root of the distribution for a list of names)
4 
5  See http://www.plumed-code.org for more information.
6 
7  This file is part of plumed, version 2.0.
8 
9  plumed is free software: you can redistribute it and/or modify
10  it under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  plumed is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with plumed. If not, see <http://www.gnu.org/licenses/>.
21 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
22 #include "PDB.h"
23 #include "Tools.h"
24 #include <cstdio>
25 #include <iostream>
26 
27 using namespace std;
28 
29 namespace PLMD{
30 
31 const std::vector<Vector> & PDB::getPositions()const{
32  return positions;
33 }
34 
35 const std::vector<double> & PDB::getOccupancy()const{
36  return occupancy;
37 }
38 
39 const std::vector<double> & PDB::getBeta()const{
40  return beta;
41 }
42 
43 const std::vector<std::string> & PDB::getRemark()const{
44  return remark;
45 }
46 
47 const std::vector<AtomNumber> & PDB::getAtomNumbers()const{
48  return numbers;
49 }
50 
51 std::string PDB::getAtomName(AtomNumber a)const{
52  std::map<AtomNumber,unsigned>::const_iterator p;
53  p=number2index.find(a);
54  if(p==number2index.end()) return "";
55  else return atomsymb[p->second];
56 }
57 
58 unsigned PDB::getResidueNumber(AtomNumber a)const{
59  std::map<AtomNumber,unsigned>::const_iterator p;
60  p=number2index.find(a);
61  if(p==number2index.end()) return 0;
62  else return residue[p->second];
63 }
64 
65 std::string PDB::getResidueName(AtomNumber a) const{
66  std::map<AtomNumber,unsigned>::const_iterator p;
67  p=number2index.find(a);
68  if(p==number2index.end()) return "";
69  else return residuenames[p->second];
70 }
71 
72 unsigned PDB::size()const{
73  return positions.size();
74 }
75 
76 bool PDB::readFromFilepointer(FILE *fp,bool naturalUnits,double scale){
77  //cerr<<file<<endl;
78  bool file_is_alive=false;
79  if(naturalUnits) scale=1.0;
80  string line;
81  fpos_t pos;
82  while(Tools::getline(fp,line)){
83  //cerr<<line<<"\n";
84  fgetpos (fp,&pos);
85  while(line.length()<80) line.push_back(' ');
86  string record=line.substr(0,6);
87  string serial=line.substr(6,5);
88  string atomname=line.substr(12,4);
89  string residuename=line.substr(17,3);
90  string chainID=line.substr(21,1);
91  string resnum=line.substr(22,4);
92  string x=line.substr(30,8);
93  string y=line.substr(38,8);
94  string z=line.substr(46,8);
95  string occ=line.substr(54,6);
96  string bet=line.substr(60,6);
97  Tools::trim(record);
98  if(record=="TER"){file_is_alive=true; break;}
99  if(record=="END"){file_is_alive=true; break;}
100  if(record=="ENDMDL"){file_is_alive=true; break;}
101  if(record=="REMARK"){
102  vector<string> v1; v1=Tools::getWords(line.substr(6));
103  remark.insert(remark.begin(),v1.begin(),v1.end());
104  }
105  if(record=="ATOM" || record=="HETATM"){
106  AtomNumber a; unsigned resno;
107  double o,b;
108  Vector p;
109  Tools::convert(serial,a);
110  Tools::convert(resnum,resno);
111  Tools::convert(occ,o);
112  Tools::convert(bet,b);
113  Tools::convert(x,p[0]);
114  Tools::convert(y,p[1]);
115  Tools::convert(z,p[2]);
116  // scale into nm
117  p*=scale;
118  numbers.push_back(a);
119  number2index[a]=positions.size();
120  std::size_t startpos=atomname.find_first_not_of(" \t");
121  std::size_t endpos=atomname.find_last_not_of(" \t");
122  atomsymb.push_back( atomname.substr(startpos, endpos-startpos+1) );
123  residue.push_back(resno);
124  chain.push_back(chainID);
125  occupancy.push_back(o);
126  beta.push_back(b);
127  positions.push_back(p);
128  residuenames.push_back(residuename);
129  }
130  }
131  return file_is_alive;
132 }
133 
134 void PDB::setArgKeyword( const std::string& new_args ){
135  bool replaced=false;
136  for(unsigned i=0;i<remark.size();++i){
137  if( remark[i].find("ARG=")!=std::string::npos){
138  remark[i]=new_args; replaced=true;
139  }
140  }
141  plumed_assert( replaced );
142 }
143 
144 bool PDB::read(const std::string&file,bool naturalUnits,double scale){
145  FILE* fp=fopen(file.c_str(),"r");
146  if(!fp) return false;
147  readFromFilepointer(fp,naturalUnits,scale);
148  fclose(fp);
149  return true;
150 }
151 
152 void PDB::getChainNames( std::vector<std::string>& chains ) const {
153  chains.resize(0);
154  chains.push_back( chain[0] );
155  for(unsigned i=1;i<size();++i){
156  if( chains[chains.size()-1]!=chain[i] ) chains.push_back( chain[i] );
157  }
158 }
159 
160 void PDB::getResidueRange( const std::string& chainname, unsigned& res_start, unsigned& res_end, std::string& errmsg ) const {
161  bool inres=false, foundchain=false;
162  for(unsigned i=0;i<size();++i){
163  if( chain[i]==chainname ){
164  if(!inres){
165  if(foundchain) errmsg="found second start of chain named " + chainname;
166  res_start=residue[i];
167  }
168  inres=true; foundchain=true;
169  } else if( inres && chain[i]!=chainname ){
170  inres=false;
171  res_end=residue[i-1];
172  }
173  }
174  if(inres) res_end=residue[size()-1];
175 }
176 
177 void PDB::getAtomRange( const std::string& chainname, AtomNumber& a_start, AtomNumber& a_end, std::string& errmsg ) const {
178  bool inres=false, foundchain=false;
179  for(unsigned i=0;i<size();++i){
180  if( chain[i]==chainname ){
181  if(!inres){
182  if(foundchain) errmsg="found second start of chain named " + chainname;
183  a_start=numbers[i];
184  }
185  inres=true; foundchain=true;
186  } else if( inres && chain[i]!=chainname ){
187  inres=false;
188  a_end=numbers[i-1];
189  }
190  }
191  if(inres) a_end=numbers[size()-1];
192 }
193 
194 bool PDB::getBackbone( const unsigned& resnumber, const std::vector<std::string>& backnames, std::vector<AtomNumber>& backnumbers ) const {
195  if( backnames.size()!=backnumbers.size() ) plumed_merror("mismatch between number of backbone names and number of backbone numbers");
196  bool foundresidue=false; std::vector<bool> found( backnames.size(), false );
197  for(unsigned i=0;i<size();++i){
198  if( residue[i]==resnumber ){
199  foundresidue=true;
200  for(unsigned bno=0;bno<backnames.size();++bno){
201  if( backnames[bno]==atomsymb[i] ){ backnumbers[bno]=numbers[i]; found[bno]=true; }
202  }
203  }
204  }
205  if(!foundresidue){ return false; }
206  for(unsigned i=0;i<found.size();++i){
207  if( !found[i] ) return false;
208  }
209  return true;
210 }
211 
212 std::string PDB::getChainID(const unsigned& resnumber) const {
213  for(unsigned i=0;i<size();++i){
214  if(resnumber==residue[i]) return chain[i];
215  }
216  plumed_merror("Not enough residues in pdb input file");
217 }
218 
219 void PDB::renameAtoms( const std::string& old_name, const std::string& new_name ){
220  for(unsigned i=0;i<size();++i){
221  if( atomsymb[i]==old_name ) atomsymb[i]=new_name;
222  }
223 }
224 
225 Log& operator<<(Log& ostr, const PDB& pdb){
226  char buffer[1000];
227  for(unsigned i=0;i<pdb.positions.size();i++){
228  sprintf(buffer,"ATOM %3d %8.3f %8.3f %8.3f\n",pdb.numbers[i].serial(),pdb.positions[i][0],pdb.positions[i][1],pdb.positions[i][2]);
229  ostr<<buffer;
230  }
231  return ostr;
232 }
233 
234 }
235 
Simple class to store the index of an atom.
Definition: AtomNumber.h:39
Class implementing fixed size vectors of doubles.
Definition: Vector.h:74
STL namespace.
Class containing the log stream.
Definition: Log.h:35
std::vector< Vector > positions
Definition: PDB.h:41
Minimalistic pdb parser.
Definition: PDB.h:38
Log & operator<<(Log &ostr, const PDB &pdb)
Definition: PDB.cpp:225
void const char const char int double * a
Definition: Matrix.h:42
std::vector< AtomNumber > numbers
Definition: PDB.h:45