source: src/Parser/PdbParser.cpp@ 16462f

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 16462f was 16462f, checked in by Frederik Heber <heber@…>, 14 years ago

PdbParser is now complete with respect to additionalAtomData.

  • serial, name, resName, resSeq, element, and charge are updated if changed, otherwise we use values from PdbAtomInfoContainer.
  • PdbParser::saveLine() completely uses information from PdbAtomInfoContainer.

Testchanges:

  • Simple_configuration/2/post/test.pdb updated as we are now closer to real PDB format also concerning alignment and the resName changed again.
  • Property mode set to 100644
File size: 21.7 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * PdbParser.cpp
10 *
11 * Created on: Aug 17, 2010
12 * Author: heber
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20#include "Helpers/MemDebug.hpp"
21
22#include "Helpers/Assert.hpp"
23#include "Helpers/Log.hpp"
24#include "Helpers/toString.hpp"
25#include "Helpers/Verbose.hpp"
26#include "World.hpp"
27#include "atom.hpp"
28#include "bond.hpp"
29#include "element.hpp"
30#include "molecule.hpp"
31#include "periodentafel.hpp"
32#include "Descriptors/AtomIdDescriptor.hpp"
33#include "Parser/PdbParser.hpp"
34
35#include <map>
36#include <vector>
37
38#include <iostream>
39#include <iomanip>
40
41using namespace std;
42
43/**
44 * Constructor.
45 */
46PdbParser::PdbParser() {
47 knownTokens["ATOM"] = PdbKey::Atom;
48 knownTokens["HETATM"] = PdbKey::Atom;
49 knownTokens["TER"] = PdbKey::Filler;
50 knownTokens["END"] = PdbKey::EndOfFile;
51 knownTokens["CONECT"] = PdbKey::Connect;
52 knownTokens["REMARK"] = PdbKey::Remark;
53 knownTokens[""] = PdbKey::EndOfFile;
54
55 // argh, why can't just PdbKey::X+(size_t)i
56 PositionEnumMap[0] = PdbKey::X;
57 PositionEnumMap[1] = PdbKey::Y;
58 PositionEnumMap[2] = PdbKey::Z;
59}
60
61/**
62 * Destructor.
63 */
64PdbParser::~PdbParser() {
65 additionalAtomData.clear();
66 atomIdMap.clear();
67}
68
69
70/** Parses the initial word of the given \a line and returns the token type.
71 *
72 * @param line line to scan
73 * @return token type
74 */
75enum PdbKey::KnownTokens PdbParser::getToken(string &line)
76{
77 // look for first space
78 const size_t space_location = line.find(' ');
79 const size_t tab_location = line.find('\t');
80 size_t location = space_location < tab_location ? space_location : tab_location;
81 string token;
82 if (location != string::npos) {
83 //DoLog(1) && (Log() << Verbose(1) << "Found space at position " << space_location << std::endl);
84 token = line.substr(0,space_location);
85 } else {
86 token = line;
87 }
88
89 //DoLog(1) && (Log() << Verbose(1) << "Token is " << token << std::endl);
90 if (knownTokens.count(token) == 0)
91 return PdbKey::NoToken;
92 else
93 return knownTokens[token];
94
95 return PdbKey::NoToken;
96}
97
98/**
99 * Loads atoms from a PDB-formatted file.
100 *
101 * \param PDB file
102 */
103void PdbParser::load(istream* file) {
104 string line;
105 size_t linecount = 0;
106 enum PdbKey::KnownTokens token;
107
108 // reset atomIdMap for this file (to correctly parse CONECT entries)
109 atomIdMap.clear();
110
111 molecule *newmol = World::getInstance().createMolecule();
112 newmol->ActiveFlag = true;
113 bool NotEndOfFile = true;
114 // TODO: Remove the insertion into molecule when saving does not depend on them anymore. Also, remove molecule.hpp include
115 World::getInstance().getMolecules()->insert(newmol);
116 while (NotEndOfFile) {
117 std::getline(*file, line, '\n');
118 // extract first token
119 token = getToken(line);
120 //DoLog(1) && (Log() << Verbose(1) << " Recognized token of type : " << token << std::endl);
121 switch (token) {
122 case PdbKey::Atom:
123 readAtomDataLine(line, newmol);
124 break;
125 case PdbKey::Remark:
126 break;
127 case PdbKey::Connect:
128 readNeighbors(line);
129 break;
130 case PdbKey::Filler:
131 break;
132 case PdbKey::EndOfFile:
133 NotEndOfFile = false;
134 break;
135 default:
136 // TODO: put a throw here
137 DoeLog(2) && (eLog() << Verbose(2) << "Unknown token: '" << line << "'" << std::endl);
138 //ASSERT(0, "PdbParser::load() - Unknown token in line "+toString(linecount)+": "+line+".");
139 break;
140 }
141 NotEndOfFile = NotEndOfFile && (file->good());
142 linecount++;
143 }
144}
145
146/**
147 * Saves the World's current state into as a PDB file.
148 *
149 * \param file where to save the state
150 */
151void PdbParser::save(ostream* file) {
152 DoLog(0) && (Log() << Verbose(0) << "Saving changes to pdb." << std::endl);
153
154 {
155 // add initial remark
156 *file << "REMARK created by molecuilder on ";
157 time_t now = time((time_t *)NULL); // Get the system time and put it into 'now' as 'calender time'
158 // ctime ends in \n\0, we have to cut away the newline
159 std::string time(ctime(&now));
160 size_t pos = time.find('\n');
161 if (pos != 0)
162 *file << time.substr(0,pos);
163 else
164 *file << time;
165 *file << endl;
166 }
167
168 // we distribute serials, hence clear map beforehand
169 atomIdMap.clear();
170 {
171 std::vector<atom *> AtomList = World::getInstance().getAllAtoms();
172 std::vector<molecule *> MolList = World::getInstance().getAllMolecules();
173 std::map<size_t,size_t> MolIdMap;
174 size_t MolNo = 1; // residue number starts at 1 in pdb
175 for (std::vector<molecule *>::const_iterator iter = MolList.begin();
176 iter != MolList.end();
177 ++iter) {
178 MolIdMap[(*iter)->getId()] = MolNo++;
179 }
180 const size_t MaxMol = MolNo;
181
182 // have a count per element and per molecule (0 is for all homeless atoms)
183 std::vector<int> **elementNo = new std::vector<int>*[MaxMol];
184 for (size_t i = 0; i < MaxMol; ++i)
185 elementNo[i] = new std::vector<int>(MAX_ELEMENTS,1);
186 char name[MAXSTRINGSIZE];
187 std::string ResidueName;
188
189 // write ATOMs
190 int AtomNo = 1; // serial number starts at 1 in pdb
191 for (vector<atom *>::iterator atomIt = AtomList.begin(); atomIt != AtomList.end(); atomIt++) {
192 PdbAtomInfoContainer &atomInfo = additionalAtomData[(*atomIt)->getId()];
193 // gather info about residue
194 const molecule *mol = (*atomIt)->getMolecule();
195 if (mol == NULL) {
196 MolNo = 0;
197 atomInfo.set(PdbKey::resSeq, "0");
198 } else {
199 ASSERT(MolIdMap.find(mol->getId()) != MolIdMap.end(),
200 "PdbParser::save() - Mol id "+toString(mol->getId())+" not present despite we set it?!");
201 MolNo = MolIdMap[mol->getId()];
202 atomInfo.set(PdbKey::resSeq, toString(MolIdMap[mol->getId()]));
203 if (atomInfo.get<std::string>(PdbKey::resName) == "-")
204 atomInfo.set(PdbKey::resName, mol->getName().substr(0,3));
205 }
206 // get info about atom
207 const size_t Z = (*atomIt)->getType()->getAtomicNumber();
208 if (atomInfo.get<std::string>(PdbKey::name) == "-") { // if no name set, give it a new name
209 sprintf(name, "%2s%02d",(*atomIt)->getType()->getSymbol().c_str(), (*elementNo[MolNo])[Z]);
210 (*elementNo[MolNo])[Z] = ((*elementNo[MolNo])[Z]+1) % 100; // confine to two digits
211 atomInfo.set(PdbKey::name, name);
212 }
213 // set position
214 for (size_t i=0; i<NDIM;++i) {
215 stringstream position;
216 position << setw(8) << fixed << setprecision(3) << (*atomIt)->getPosition().at(i);
217 atomInfo.set(PositionEnumMap[i], position.str());
218 }
219 // change element and charge if changed
220 if (atomInfo.get<std::string>(PdbKey::element) != (*atomIt)->getType()->getSymbol())
221 atomInfo.set(PdbKey::element, (*atomIt)->getType()->getSymbol());
222 setSerial((*atomIt)->getId(), AtomNo);
223 atomInfo.set(PdbKey::serial, toString(AtomNo));
224
225 // finally save the line
226 saveLine(file, atomInfo);
227 AtomNo++;
228 }
229 for (size_t i = 0; i < MaxMol; ++i)
230 delete elementNo[i];
231 delete elementNo;
232
233 // write CONECTs
234 for (vector<atom *>::iterator atomIt = AtomList.begin(); atomIt != AtomList.end(); atomIt++) {
235 writeNeighbors(file, 4, *atomIt);
236 }
237 }
238
239 // END
240 *file << "END" << endl;
241}
242
243/**
244 * Writes one line of PDB-formatted data to the provided stream.
245 *
246 * \param stream where to write the line to
247 * \param *currentAtom the atom of which information should be written
248 * \param AtomNo serial number of atom
249 * \param *name name of atom, i.e. H01
250 * \param ResidueName Name of molecule
251 * \param ResidueNo number of residue
252 */
253void PdbParser::saveLine(
254 ostream* file,
255 const PdbAtomInfoContainer &atomInfo)
256{
257 *file << setfill(' ') << left << setw(6)
258 << atomInfo.get<std::string>(PdbKey::token);
259 *file << setfill(' ') << right << setw(5)
260 << atomInfo.get<int>(PdbKey::serial); /* atom serial number */
261 *file << " "; /* char 12 is empty */
262 *file << setfill(' ') << left << setw(4)
263 << atomInfo.get<std::string>(PdbKey::name); /* atom name */
264 *file << setfill(' ') << left << setw(1)
265 << atomInfo.get<std::string>(PdbKey::altLoc); /* alternate location/conformation */
266 *file << setfill(' ') << left << setw(3)
267 << atomInfo.get<std::string>(PdbKey::resName); /* residue name */
268 *file << " "; /* char 21 is empty */
269 *file << setfill(' ') << left << setw(1)
270 << atomInfo.get<std::string>(PdbKey::chainID); /* chain identifier */
271 *file << setfill(' ') << left << setw(4)
272 << atomInfo.get<int>(PdbKey::resSeq); /* residue sequence number */
273 *file << setfill(' ') << left << setw(1)
274 << atomInfo.get<std::string>(PdbKey::iCode); /* iCode */
275 *file << " "; /* char 28-30 are empty */
276 // have the following operate on stringstreams such that format specifiers
277 // only act on these
278 for (size_t i=0;i<NDIM;++i) {
279 stringstream position;
280 position << fixed << setprecision(3) << showpoint
281 << atomInfo.get<double>(PositionEnumMap[i]);
282 *file << setfill(' ') << right << setw(8) << position.str();
283 }
284 {
285 stringstream occupancy;
286 occupancy << fixed << setprecision(2) << showpoint
287 << atomInfo.get<double>(PdbKey::occupancy); /* occupancy */
288 *file << setfill(' ') << right << setw(6) << occupancy.str();
289 }
290 {
291 stringstream tempFactor;
292 tempFactor << fixed << setprecision(2) << showpoint
293 << atomInfo.get<double>(PdbKey::tempFactor); /* temperature factor */
294 *file << setfill(' ') << right << setw(6) << tempFactor.str();
295 }
296 *file << " "; /* char 68-76 are empty */
297 *file << setfill(' ') << right << setw(2) << atomInfo.get<std::string>(PdbKey::element); /* element */
298 *file << setfill(' ') << right << setw(2) << atomInfo.get<int>(PdbKey::charge); /* charge */
299
300 *file << endl;
301}
302
303/**
304 * Writes the neighbor information of one atom to the provided stream.
305 *
306 * \param *file where to write neighbor information to
307 * \param MaxnumberOfNeighbors of neighbors
308 * \param *currentAtom to the atom of which to take the neighbor information
309 */
310void PdbParser::writeNeighbors(ostream* file, int MaxnumberOfNeighbors, atom* currentAtom) {
311 int MaxNo = MaxnumberOfNeighbors;
312 if (!currentAtom->ListOfBonds.empty()) {
313 for(BondList::iterator currentBond = currentAtom->ListOfBonds.begin(); currentBond != currentAtom->ListOfBonds.end(); ++currentBond) {
314 if (MaxNo >= MaxnumberOfNeighbors) {
315 *file << "CONECT";
316 *file << setw(5) << getSerial(currentAtom->getId());
317 MaxNo = 0;
318 }
319 *file << setw(5) << getSerial((*currentBond)->GetOtherAtom(currentAtom)->getId());
320 MaxNo++;
321 if (MaxNo == MaxnumberOfNeighbors)
322 *file << "\n";
323 }
324 if (MaxNo != MaxnumberOfNeighbors)
325 *file << "\n";
326 }
327}
328
329/** Retrieves a value from PdbParser::atomIdMap.
330 * \param atomid key
331 * \return value
332 */
333size_t PdbParser::getSerial(const size_t atomid) const
334{
335 ASSERT(atomIdMap.find(atomid) != atomIdMap.end(), "PdbParser::getAtomId: atomid not present in Map.");
336 return (atomIdMap.find(atomid)->second);
337}
338
339/** Sets an entry in PdbParser::atomIdMap.
340 * \param localatomid key
341 * \param atomid value
342 * \return true - key not present, false - value present
343 */
344void PdbParser::setSerial(const size_t localatomid, const size_t atomid)
345{
346 pair<std::map<size_t,size_t>::iterator, bool > inserter;
347// DoLog(1) && (Log() << Verbose(1) << "PdbParser::setAtomId() - Inserting ("
348// << localatomid << " -> " << atomid << ")." << std::endl);
349 inserter = atomIdMap.insert( make_pair(localatomid, atomid) );
350 ASSERT(inserter.second, "PdbParser::setAtomId: atomId already present in Map.");
351}
352
353/** Parse an ATOM line from a PDB file.
354 *
355 * Reads one data line of a pdstatus file and interprets it according to the
356 * specifications of the PDB 3.2 format: http://www.wwpdb.org/docs.html
357 *
358 * A new atom is created and filled with available information, non-
359 * standard information is placed in additionalAtomData at the atom's id.
360 *
361 * \param line to parse as an atom
362 * \param newmol molecule to add parsed atoms to
363 */
364void PdbParser::readAtomDataLine(std::string &line, molecule *newmol = NULL) {
365 vector<string>::iterator it;
366 stringstream lineStream;
367 atom* newAtom = World::getInstance().createAtom();
368 additionalAtomData[newAtom->getId()] = *(new PdbAtomInfoContainer);
369 PdbAtomInfoContainer &atomInfo = additionalAtomData[newAtom->getId()];
370 string word;
371 ConvertTo<size_t> toSize_t;
372 double tmp;
373
374 lineStream << line;
375 atomInfo.set(PdbKey::token, line.substr(0,6));
376 atomInfo.set(PdbKey::serial, line.substr(6,5));
377 std::pair< std::set<size_t>::const_iterator, bool> Inserter =
378 SerialSet.insert(toSize_t(atomInfo.get<std::string>(PdbKey::serial)));
379 ASSERT(Inserter.second,
380 "PdbParser::readAtomDataLine() - ATOM contains entry with serial "
381 +atomInfo.get<std::string>(PdbKey::serial)+" already present!");
382 // assign hightest+1 instead, but then beware of CONECT entries! Another map needed!
383// if (!Inserter.second) {
384// const size_t id = (*SerialSet.rbegin())+1;
385// SerialSet.insert(id);
386// atomInfo.set(PdbKey::serial, toString(id));
387// DoeLog(2) && (eLog() << Verbose(2)
388// << "Serial " << atomInfo.get<std::string>(PdbKey::serial) << " already present, "
389// << "assigning " << toString(id) << " instead." << std::endl);
390// }
391
392 // check whether serial exists, if so, assign next available
393
394// DoLog(2) && (Log() << Verbose(2) << "Split line:"
395// << line.substr(6,5) << "|"
396// << line.substr(12,4) << "|"
397// << line.substr(16,1) << "|"
398// << line.substr(17,3) << "|"
399// << line.substr(21,1) << "|"
400// << line.substr(22,4) << "|"
401// << line.substr(26,1) << "|"
402// << line.substr(30,8) << "|"
403// << line.substr(38,8) << "|"
404// << line.substr(46,8) << "|"
405// << line.substr(54,6) << "|"
406// << line.substr(60,6) << "|"
407// << line.substr(76,2) << "|"
408// << line.substr(78,2) << std::endl);
409
410 setSerial(toSize_t(atomInfo.get<std::string>(PdbKey::serial)), newAtom->getId());
411 atomInfo.set(PdbKey::name, line.substr(12,4));
412 atomInfo.set(PdbKey::altLoc, line.substr(16,1));
413 atomInfo.set(PdbKey::resName, line.substr(17,3));
414 atomInfo.set(PdbKey::chainID, line.substr(21,1));
415 atomInfo.set(PdbKey::resSeq, line.substr(22,4));
416 atomInfo.set(PdbKey::iCode, line.substr(26,1));
417 PdbAtomInfoContainer::ScanKey(tmp, line.substr(30,8));
418 newAtom->set(0, tmp);
419 PdbAtomInfoContainer::ScanKey(tmp, line.substr(38,8));
420 newAtom->set(1, tmp);
421 PdbAtomInfoContainer::ScanKey(tmp, line.substr(46,8));
422 newAtom->set(2, tmp);
423 atomInfo.set(PdbKey::occupancy, line.substr(54,6));
424 atomInfo.set(PdbKey::tempFactor, line.substr(60,6));
425 atomInfo.set(PdbKey::charge, line.substr(78,2));
426 atomInfo.set(PdbKey::element, line.substr(76,2));
427 const element *elem = World::getInstance().getPeriode()
428 ->FindElement(atomInfo.get<std::string>(PdbKey::element));
429 ASSERT(elem != NULL,
430 "PdbParser::readAtomDataLine() - element "+atomInfo.get<std::string>(PdbKey::element)+" is unknown!");
431 newAtom->setType(elem);
432
433 if (newmol != NULL)
434 newmol->AddAtom(newAtom);
435
436// printAtomInfo(newAtom);
437}
438
439/** Prints all PDB-specific information known about an atom.
440 *
441 */
442void PdbParser::printAtomInfo(const atom * const newAtom) const
443{
444 const PdbAtomInfoContainer &atomInfo = additionalAtomData.at(newAtom->getId()); // operator[] const does not exist
445
446 DoLog(1) && (Log() << Verbose(1) << "We know about atom " << newAtom->getId() << ":" << std::endl);
447 DoLog(1) && (Log() << Verbose(1) << "\ttoken is " << atomInfo.get<std::string>(PdbKey::token) << std::endl);
448 DoLog(1) && (Log() << Verbose(1) << "\tserial is " << atomInfo.get<int>(PdbKey::serial) << std::endl);
449 DoLog(1) && (Log() << Verbose(1) << "\tname is " << atomInfo.get<std::string>(PdbKey::name) << std::endl);
450 DoLog(1) && (Log() << Verbose(1) << "\taltLoc is " << atomInfo.get<std::string>(PdbKey::altLoc) << std::endl);
451 DoLog(1) && (Log() << Verbose(1) << "\tresName is " << atomInfo.get<std::string>(PdbKey::resName) << std::endl);
452 DoLog(1) && (Log() << Verbose(1) << "\tchainID is " << atomInfo.get<std::string>(PdbKey::chainID) << std::endl);
453 DoLog(1) && (Log() << Verbose(1) << "\tresSeq is " << atomInfo.get<int>(PdbKey::resSeq) << std::endl);
454 DoLog(1) && (Log() << Verbose(1) << "\tiCode is " << atomInfo.get<std::string>(PdbKey::iCode) << std::endl);
455 DoLog(1) && (Log() << Verbose(1) << "\tX is " << atomInfo.get<double>(PdbKey::X) << std::endl);
456 DoLog(1) && (Log() << Verbose(1) << "\tY is " << atomInfo.get<double>(PdbKey::Y) << std::endl);
457 DoLog(1) && (Log() << Verbose(1) << "\tZ is " << atomInfo.get<double>(PdbKey::Z) << std::endl);
458 DoLog(1) && (Log() << Verbose(1) << "\toccupancy is " << atomInfo.get<double>(PdbKey::occupancy) << std::endl);
459 DoLog(1) && (Log() << Verbose(1) << "\ttempFactor is " << atomInfo.get<double>(PdbKey::tempFactor) << std::endl);
460 DoLog(1) && (Log() << Verbose(1) << "\telement is '" << *(newAtom->getType()) << "'" << std::endl);
461 DoLog(1) && (Log() << Verbose(1) << "\tcharge is " << atomInfo.get<int>(PdbKey::charge) << std::endl);
462}
463
464/**
465 * Reads neighbor information for one atom from the input.
466 *
467 * \param line to parse as an atom
468 */
469void PdbParser::readNeighbors(std::string &line)
470{
471 const size_t length = line.length();
472 std::list<size_t> ListOfNeighbors;
473 ConvertTo<size_t> toSize_t;
474
475 // obtain neighbours
476 // show split line for debugging
477 string output;
478 ASSERT(length >=16,
479 "PdbParser::readNeighbors() - CONECT entry has not enough entries: "+line+"!");
480// output = "Split line:|";
481// output += line.substr(6,5) + "|";
482 const size_t id = toSize_t(line.substr(6,5));
483 for (size_t index = 11; index <= 26; index+=5) {
484 if (index+5 <= length) {
485// output += line.substr(index,5) + "|";
486 const size_t otherid = toSize_t(line.substr(index,5));
487 ListOfNeighbors.push_back(otherid);
488 } else {
489 break;
490 }
491 }
492// DoLog(2) && (Log() << Verbose(2) << output << std::endl);
493
494 // add neighbours
495 atom *_atom = World::getInstance().getAtom(AtomById(getSerial(id)));
496 for (std::list<size_t>::const_iterator iter = ListOfNeighbors.begin();
497 iter != ListOfNeighbors.end();
498 ++iter) {
499// DoLog(1) && (Log() << Verbose(1) << "Adding Bond (" << getAtomId(id) << "," << getAtomId(*iter) << ")" << std::endl);
500 atom * const _Otheratom = World::getInstance().getAtom(AtomById(getSerial(*iter)));
501 _atom->addBond(_Otheratom);
502 }
503}
504
505/**
506 * Replaces atom IDs read from the file by the corresponding world IDs. All IDs
507 * IDs of the input string will be replaced; expected separating characters are
508 * "-" and ",".
509 *
510 * \param string in which atom IDs should be adapted
511 *
512 * \return input string with modified atom IDs
513 */
514//string PdbParser::adaptIdDependentDataString(string data) {
515// // there might be no IDs
516// if (data == "-") {
517// return "-";
518// }
519//
520// char separator;
521// int id;
522// stringstream line, result;
523// line << data;
524//
525// line >> id;
526// result << atomIdMap[id];
527// while (line.good()) {
528// line >> separator >> id;
529// result << separator << atomIdMap[id];
530// }
531//
532// return result.str();
533// return "";
534//}
535
536
537bool PdbParser::operator==(const PdbParser& b) const
538{
539 bool status = true;
540 World::AtomComposite atoms = World::getInstance().getAllAtoms();
541 for (World::AtomComposite::const_iterator iter = atoms.begin(); iter != atoms.end(); ++iter) {
542 if ((additionalAtomData.find((*iter)->getId()) != additionalAtomData.end())
543 && (b.additionalAtomData.find((*iter)->getId()) != b.additionalAtomData.end())) {
544 const PdbAtomInfoContainer &atomInfo = additionalAtomData.at((*iter)->getId());
545 const PdbAtomInfoContainer &OtheratomInfo = b.additionalAtomData.at((*iter)->getId());
546
547 status = status && (atomInfo.get<std::string>(PdbKey::serial) == OtheratomInfo.get<std::string>(PdbKey::serial));
548 if (!status) DoeLog(1) && (eLog() << Verbose(1) << "Mismatch in serials!" << std::endl);
549 status = status && (atomInfo.get<std::string>(PdbKey::name) == OtheratomInfo.get<std::string>(PdbKey::name));
550 if (!status) DoeLog(1) && (eLog() << Verbose(1) << "Mismatch in names!" << std::endl);
551 status = status && (atomInfo.get<std::string>(PdbKey::altLoc) == OtheratomInfo.get<std::string>(PdbKey::altLoc));
552 if (!status) DoeLog(1) && (eLog() << Verbose(1) << "Mismatch in altLocs!" << std::endl);
553 status = status && (atomInfo.get<std::string>(PdbKey::resName) == OtheratomInfo.get<std::string>(PdbKey::resName));
554 if (!status) DoeLog(1) && (eLog() << Verbose(1) << "Mismatch in resNames!" << std::endl);
555 status = status && (atomInfo.get<std::string>(PdbKey::chainID) == OtheratomInfo.get<std::string>(PdbKey::chainID));
556 if (!status) DoeLog(1) && (eLog() << Verbose(1) << "Mismatch in chainIDs!" << std::endl);
557 status = status && (atomInfo.get<std::string>(PdbKey::resSeq) == OtheratomInfo.get<std::string>(PdbKey::resSeq));
558 if (!status) DoeLog(1) && (eLog() << Verbose(1) << "Mismatch in resSeqs!" << std::endl);
559 status = status && (atomInfo.get<std::string>(PdbKey::iCode) == OtheratomInfo.get<std::string>(PdbKey::iCode));
560 if (!status) DoeLog(1) && (eLog() << Verbose(1) << "Mismatch in iCodes!" << std::endl);
561 status = status && (atomInfo.get<std::string>(PdbKey::occupancy) == OtheratomInfo.get<std::string>(PdbKey::occupancy));
562 if (!status) DoeLog(1) && (eLog() << Verbose(1) << "Mismatch in occupancies!" << std::endl);
563 status = status && (atomInfo.get<std::string>(PdbKey::tempFactor) == OtheratomInfo.get<std::string>(PdbKey::tempFactor));
564 if (!status) DoeLog(1) && (eLog() << Verbose(1) << "Mismatch in tempFactors!" << std::endl);
565 status = status && (atomInfo.get<std::string>(PdbKey::charge) == OtheratomInfo.get<std::string>(PdbKey::charge));
566 if (!status) DoeLog(1) && (eLog() << Verbose(1) << "Mismatch in charges!" << std::endl);
567 }
568 }
569
570 return status;
571}
572
Note: See TracBrowser for help on using the repository browser.