Molmodel
|
00001 #ifndef MOLMODEL_PDB_H_ 00002 #define MOLMODEL_PDB_H_ 00003 00004 #include "SimTKsimbody.h" 00005 #include <cctype> 00006 #include "molmodel/internal/Compound.h" 00007 #include <map> 00008 00009 namespace SimTK { 00010 00011 namespace Pdb { 00012 SimTK_DEFINE_UNIQUE_INDEX_TYPE(AtomIndex); 00013 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ResidueIndex); 00014 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ChainIndex); 00015 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ModelIndex); 00016 } 00017 00020 class SimTK_MOLMODEL_EXPORT PdbResidueId { 00021 public: 00022 explicit PdbResidueId(int num, char iCode = ' ') : residueNumber(num), insertionCode(iCode) {} 00023 00025 bool operator<(const PdbResidueId& other) const; 00026 00027 int residueNumber; 00028 char insertionCode; 00029 }; 00030 00031 namespace Exception 00032 { 00033 class UndefinedPdbChainId : public Exception::Base 00034 { 00035 public: 00036 UndefinedPdbChainId(const char* fn, int ln, char chainId) 00037 : Exception::Base(fn, ln) 00038 { 00039 String chainString = " "; 00040 chainString[0] = chainId; 00041 setMessage("Undefined PDB chain Id: '" + chainString + "'"); 00042 } 00043 00044 }; 00045 00046 class DuplicatePdbResidue : public Exception::Base 00047 { 00048 public: 00049 DuplicatePdbResidue(const char* fn, int ln, PdbResidueId pdbResidueId) 00050 : Exception::Base(fn, ln) 00051 { 00052 String message("Duplicate PDB Residue number "); 00053 message += String(pdbResidueId.residueNumber); 00054 00055 setMessage(message); 00056 } 00057 00058 }; 00059 00060 class UndefinedAminoAcidResidue : public Exception::Base 00061 { 00062 public: 00063 UndefinedAminoAcidResidue(const char* fn, int ln, String residueName) 00064 : Exception::Base(fn, ln) 00065 { 00066 String message("Unknown amino acid residue name '"); 00067 message += residueName; 00068 message += "'"; 00069 00070 setMessage(message); 00071 } 00072 00073 }; 00074 } 00075 00077 class SimTK_MOLMODEL_EXPORT PdbAtomLocation { 00078 public: 00079 explicit PdbAtomLocation(SimTK::Vec3 coords, char altLoc = ' ', SimTK::Real tFac = 0.00, SimTK::Real occ = 1.0) 00080 : coordinates(coords), alternateLocationIndicator(altLoc), temperatureFactor(tFac), occupancy(occ) 00081 {} 00082 00084 std::ostream& writePdb(std::ostream& os, const Transform& transform) const; 00085 00086 const Vec3& getCoordinates() const {return coordinates;} 00087 00088 char getAlternateLocationIndicator() const {return alternateLocationIndicator;} 00089 00090 SimTK::Real getTemperatureFactor() const {return temperatureFactor;} 00091 00092 SimTK::Real getOccupancy() const {return occupancy;} 00093 00094 private: 00095 00096 // avoid dll export warnings for these private types 00097 #if defined(_MSC_VER) 00098 #pragma warning(push) 00099 #pragma warning(disable:4251) 00100 #endif 00101 00102 SimTK::Vec3 coordinates; 00103 00104 #if defined(_MSC_VER) 00105 #pragma warning(pop) 00106 #endif 00107 00108 char alternateLocationIndicator; 00109 SimTK::Real temperatureFactor; 00110 SimTK::Real occupancy; 00111 }; 00112 00114 class SimTK_MOLMODEL_EXPORT PdbAtom { 00115 friend class PdbResidue; 00116 typedef std::vector<SimTK::String> AtomNameList; 00117 public: 00118 explicit PdbAtom(const SimTK::String& name, const Element& e); 00119 00120 explicit PdbAtom( 00121 const class Compound& compound, 00122 const String& atomName, 00123 const Transform& transform = Transform() ); 00124 00125 explicit PdbAtom( 00126 const State& state, 00127 const class Compound& compound, 00128 const String& atomName, 00129 const Transform& transform = Transform() ); 00130 00131 std::ostream& write( 00132 std::ostream& os, 00133 int& nextAtomSerialNumber, 00134 const char residueName[4], 00135 PdbResidueId residueId, 00136 char chainId, 00137 const Transform& transform) const; 00138 00139 bool hasLocation(char altLoc) const; 00140 00141 bool hasLocation() const; 00142 00143 Vec3 getLocation(char altLoc) const; 00144 00145 Vec3 getLocation() const; 00146 00147 PdbAtom& setLocation(const PdbAtomLocation& loc) { 00148 char alt_loc = loc.getAlternateLocationIndicator(); 00149 if (locationIndicesById.find(alt_loc) == locationIndicesById.end()) { 00150 locationIndicesById[alt_loc] = locations.size(); 00151 locations.push_back(loc); 00152 } 00153 else { 00154 locations[locationIndicesById.find(alt_loc)->second] = loc; 00155 } 00156 00157 return *this; 00158 } 00159 00160 const String& getName() const {return atomName;} 00161 00162 const PdbAtomLocation& getPdbAtomLocation() const { 00163 assert(hasLocation()); 00164 return locations[0]; 00165 } 00166 00167 const Vec3& getCoordinates() const { 00168 return getPdbAtomLocation().getCoordinates(); 00169 } 00170 00171 char getAlternateLocationIndicator() const { 00172 return getPdbAtomLocation().getAlternateLocationIndicator(); 00173 } 00174 00175 SimTK::Real getTemperatureFactor() const { 00176 return getPdbAtomLocation().getTemperatureFactor(); 00177 } 00178 00179 SimTK::Real getOccupancy() const { 00180 return getPdbAtomLocation().getOccupancy(); 00181 } 00182 00183 00184 protected: 00185 void parsePdbLine(const String& line); 00186 00189 static String canonicalizeAtomName(const String& casualName); 00190 00192 static std::vector<SimTK::String> generatePossibleAtomNames(SimTK::String name); 00193 00194 private: 00195 Element element; 00196 00197 // avoid dll export warnings for these private types 00198 #if defined(_MSC_VER) 00199 #pragma warning(push) 00200 #pragma warning(disable:4251) 00201 #endif 00202 00203 SimTK::String atomName; 00204 typedef std::vector<PdbAtomLocation> Locations; 00205 Locations locations; 00206 std::map<char, int> locationIndicesById; 00207 00208 #if defined(_MSC_VER) 00209 #pragma warning(pop) 00210 #endif 00211 00212 }; 00213 00215 class SimTK_MOLMODEL_EXPORT PdbResidue { 00216 friend class PdbChain; 00217 public: 00218 explicit PdbResidue(String name, PdbResidueId id); 00219 00220 explicit PdbResidue( 00221 const class Compound& compound, 00222 int residueNumber, 00223 const Transform& transform = Transform() ); 00224 00225 explicit PdbResidue( 00226 const State& state, 00227 const class Compound& compound, 00228 int residueNumber, 00229 const Transform& transform = Transform() ); 00230 00231 std::ostream& write(std::ostream& os, int& nextAtomSerialNumber, char chainId, const Transform& transform) const; 00232 00233 bool hasAtom(SimTK::String argName) const; 00234 00235 const PdbAtom& getAtom(String argName) const; 00236 00237 PdbAtom& updAtom(String argName); 00238 00239 const PdbResidueId& getResidueId() const {return residueId;} 00240 const char* getName() const {return residueName;} 00241 int getPdbResidueNumber() const {return residueId.residueNumber;} 00242 char getInsertionCode() const {return residueId.insertionCode;} 00243 00244 size_t getNumAtoms() const { return atoms.size(); } 00245 00246 const PdbAtom& getAtom(Pdb::AtomIndex atomIx) const { 00247 return atoms[atomIx]; 00248 } 00249 00250 void addAtom(const PdbAtom& atom); 00251 00252 protected: 00253 void parsePdbLine(const String& line); 00254 00255 private: 00256 char residueName[4]; 00257 PdbResidueId residueId; 00258 00259 // avoid dll export warnings for these private types 00260 #if defined(_MSC_VER) 00261 #pragma warning(push) 00262 #pragma warning(disable:4251) 00263 #endif 00264 00265 typedef std::vector<PdbAtom> Atoms; 00266 Atoms atoms; 00267 std::map<SimTK::String, int> atomIndicesByName; 00268 00269 #if defined(_MSC_VER) 00270 #pragma warning(pop) 00271 #endif 00272 00273 private: 00274 // OBSOLETE: use getNumAtoms() 00275 size_t getNAtoms() const {return getNumAtoms();} 00276 }; 00277 00278 class Compound; 00279 00282 class SimTK_MOLMODEL_EXPORT PdbChain { 00283 friend class PdbModel; 00284 public: 00285 explicit PdbChain(char id = ' ') : chainId(id) {} 00286 00287 explicit PdbChain( 00288 const Compound& compound, 00289 const Transform& transform = Transform()); 00290 00291 explicit PdbChain( 00292 const State& state, 00293 const Compound& compound, 00294 const Transform& transform = Transform()); 00295 00296 std::ostream& write(std::ostream& os, int& nextAtomSerialNumber, const Transform& transform = Transform()) const; 00297 00298 bool hasResidue(PdbResidueId pdbResidueId) const; 00299 00300 bool hasAtom(String atomName, PdbResidueId residueId) const; 00301 00302 const PdbAtom& getAtom(String atomName, PdbResidueId residueId) const; 00303 00304 PdbAtom& updAtom(String atomName, PdbResidueId residueId); 00305 00306 PdbResidue& appendResidue( const PdbResidue& residue ) 00307 { 00308 if ( residueIndicesById.find(residue.getResidueId()) != residueIndicesById.end() ) 00309 SimTK_THROW1( Exception::DuplicatePdbResidue, residue.getResidueId() ); 00310 00311 residues.push_back( residue ); 00312 residueIndicesById[residue.getResidueId()] = residues.size() - 1; 00313 00314 return residues.back(); 00315 } 00316 00317 size_t getNumResidues() const { return residues.size(); } 00318 const PdbResidue& getResidue(Pdb::ResidueIndex resIx) const { 00319 return residues[resIx]; 00320 } 00321 00322 size_t getNumAtoms() const { 00323 size_t atomCount = 0; 00324 for (Pdb::ResidueIndex r(0); r < getNumResidues(); ++r) { 00325 atomCount += getResidue(r).getNumAtoms(); 00326 } 00327 00328 return atomCount; 00329 } 00330 00331 char getChainId() const {return chainId;} 00332 00333 00334 protected: 00335 void parsePdbLine(const String& line); 00336 00337 private: 00338 char chainId; 00339 00340 // avoid dll export warnings for these private types 00341 #if defined(_MSC_VER) 00342 #pragma warning(push) 00343 #pragma warning(disable:4251) 00344 #endif 00345 00346 typedef std::vector<PdbResidue> Residues; 00347 Residues residues; 00348 std::map<PdbResidueId, size_t> residueIndicesById; 00349 00350 #if defined(_MSC_VER) 00351 #pragma warning(pop) 00352 #endif 00353 00354 private: 00355 // OBSOLETE: use getNumResidues() 00356 size_t getNResidues() const { return getNumResidues(); } 00357 // OBSOLETE: use getNumAtoms() 00358 size_t getNAtoms() const { return getNumAtoms(); } 00359 }; 00360 00363 class SimTK_MOLMODEL_EXPORT PdbModel { 00364 friend class PdbStructure; 00365 public: 00366 explicit PdbModel( 00367 const Compound& compound, 00368 int number = 1, 00369 const Transform& transform = Transform()); 00370 00371 explicit PdbModel( 00372 const State& state, 00373 const Compound& compound, int number = 1, 00374 const Transform& transform = Transform()); 00375 00376 explicit PdbModel(int number) : modelNumber(number) {} 00377 00378 std::ostream& write(std::ostream& os, const Transform& transform) const; 00379 00380 bool hasChain(char id) const; 00381 00382 bool hasAtom(String atomName, PdbResidueId residueId, char chainId) const; 00383 00384 const PdbAtom& getAtom(String atomName, PdbResidueId residueId, char chainId) const; 00385 00386 PdbAtom& updAtom(String atomName, PdbResidueId residueId, char chainId); 00387 00388 size_t getNumChains() const {return chains.size();} 00389 const PdbChain& getChain(Pdb::ChainIndex chainIx) const { 00390 return chains[chainIx]; 00391 } 00392 const PdbChain& getChain(char chainId) const; 00393 00394 // OBSOLETE; TODO: remove in SimTK 2.0 00395 size_t getNChains() const {return getNumChains();} 00396 00397 protected: 00398 void parsePdbLine(const String& line); 00399 00400 PdbChain& updOrCreateChain(char chainId); 00401 00402 private: 00403 int modelNumber; 00404 00405 // avoid dll export warnings for these private types 00406 #if defined(_MSC_VER) 00407 #pragma warning(push) 00408 #pragma warning(disable:4251) 00409 #endif 00410 00411 typedef std::vector<PdbChain> Chains; 00412 Chains chains; 00413 std::map<char, int> chainIndicesById; 00414 00415 #if defined(_MSC_VER) 00416 #pragma warning(pop) 00417 #endif 00418 00419 }; 00420 00423 class SimTK_MOLMODEL_EXPORT PdbStructure { 00424 public: 00425 00427 explicit PdbStructure( 00428 const Compound& compound, 00429 const Transform& transform = Transform()); 00430 00432 explicit PdbStructure( 00433 const State& state, 00434 const Compound& compound, 00435 const Transform& transform = Transform()); 00436 00437 explicit PdbStructure(std::istream& pdbFile); 00438 00439 bool hasAtom(String atomName, PdbResidueId residueId, char chainId) const; 00440 00441 const PdbAtom& getAtom(String atomName, PdbResidueId residueId, char chainId) const; 00442 00443 PdbAtom& updAtom(String atomName, PdbResidueId residueId, char chainId); 00444 00445 std::ostream& write(std::ostream& os, Transform transform = Transform()) const; 00446 00447 size_t getNumModels() const {return models.size();} 00448 const PdbModel& getModel(Pdb::ModelIndex modelIx) const { 00449 return models[modelIx]; 00450 } 00451 00452 private: 00453 00454 // avoid dll export warnings for these private types 00455 #if defined(_MSC_VER) 00456 #pragma warning(push) 00457 #pragma warning(disable:4251) 00458 #endif 00459 00460 typedef std::vector<PdbModel> Models; 00461 Models models; 00462 00463 #if defined(_MSC_VER) 00464 #pragma warning(pop) 00465 #endif 00466 00467 private: 00468 // OBSOLETE; use getNumModels() instead 00469 size_t getNModels() const {return getNumModels();} 00470 }; 00471 00472 } // namespace SimTK 00473 00474 SimTK_MOLMODEL_EXPORT std::ostream& operator<<(std::ostream& os, const SimTK::PdbModel& pdbModel); 00475 SimTK_MOLMODEL_EXPORT std::ostream& operator<<(std::ostream& os, const SimTK::PdbStructure& pdbStructure); 00476 00477 #endif // MOLMODEL_PDB_H_