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

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 21585f was 21585f, checked in by Frederik Heber <heber@…>, 14 years ago

Added getter/setter for PdbParser::atomIdMap().

  • Property mode set to 100644
File size: 12.3 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/Verbose.hpp"
25#include "PdbParser.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
34#include <map>
35#include <vector>
36
37#include <iostream>
38#include <iomanip>
39
40using namespace std;
41
42/**
43 * Constructor.
44 */
45PdbParser::PdbParser() {
46 knownKeys[" "] = PdbKey::noKey; // with this we can detect invalid keys
47 knownKeys["x"] = PdbKey::x;
48 knownKeys["Id"] = PdbKey::Id;
49 knownKeys["Type"] = PdbKey::Type;
50 knownKeys["extType"] = PdbKey::extType;
51 knownKeys["name"] = PdbKey::name;
52 knownKeys["resName"] = PdbKey::resName;
53 knownKeys["chainID"] = PdbKey::chainID;
54 knownKeys["resSeq"] = PdbKey::resSeq;
55 knownKeys["occupancy"] = PdbKey::occupancy;
56 knownKeys["tempFactor"] = PdbKey::tempFactor;
57 knownKeys["segID"] = PdbKey::segID;
58 knownKeys["charge"] = PdbKey::charge;
59}
60
61/**
62 * Destructor.
63 */
64PdbParser::~PdbParser() {
65 additionalAtomData.clear();
66 atomIdMap.clear();
67 knownKeys.clear();
68}
69
70/**
71 * Loads atoms from a tremolo-formatted file.
72 *
73 * \param tremolo file
74 */
75void PdbParser::load(istream* file) {
76// string line;
77// string::size_type location;
78//
79// usedFields.clear();
80// while (file->good()) {
81// std::getline(*file, line, '\n');
82// if (usedFields.empty()) {
83// location = line.find("ATOMDATA", 0);
84// if (location != string::npos) {
85// parseAtomDataKeysLine(line, location + 8);
86// }
87// }
88// if (line.length() > 0 && line.at(0) != '#') {
89// readAtomDataLine(line);
90// }
91// }
92//
93// processNeighborInformation();
94// adaptImprData();
95// adaptTorsion();
96}
97
98/**
99 * Saves the World's current state into as a tremolo file.
100 *
101 * \param file where to save the state
102 */
103void PdbParser::save(ostream* file) {
104 DoLog(0) && (Log() << Verbose(0) << "Saving changes to pdb." << std::endl);
105
106 {
107 // add initial remark
108 *file << "REMARK created by molecuilder on ";
109 time_t now = time((time_t *)NULL); // Get the system time and put it into 'now' as 'calender time'
110 // ctime ends in \n\0, we have to cut away the newline
111 std::string time(ctime(&now));
112 size_t pos = time.find('\n');
113 if (pos != 0)
114 *file << time.substr(0,pos);
115 else
116 *file << time;
117 *file << endl;
118 }
119
120 {
121 vector<atom *> AtomList = World::getInstance().getAllAtoms();
122
123 std::vector<int> elementNo(MAX_ELEMENTS,1);
124 char name[MAXSTRINGSIZE];
125
126 // write ATOMs
127 int AtomNo = 1; // serial number starts at 1 in pdb
128 int MolNo = 1; // residue number starts at 1 in pdb
129 for (vector<atom *>::iterator atomIt = AtomList.begin(); atomIt != AtomList.end(); atomIt++) {
130 const size_t Z = (*atomIt)->getType()->getAtomicNumber();
131 sprintf(name, "%2s%02d",(*atomIt)->getType()->getSymbol().c_str(), elementNo[Z]);
132 elementNo[Z] = (elementNo[Z]+1) % 100; // confine to two digits
133 const molecule *mol = (*atomIt)->getMolecule();
134 if (mol == NULL) { // for homeless atoms, MolNo = 0 is reserved
135 MolNo = 0;
136 } else {
137 MolNo = mol->getId();
138 }
139 saveLine(file, *atomIt, name, AtomNo, MolNo);
140 setAtomId((*atomIt)->getId(), AtomNo);
141 AtomNo++;
142 }
143
144 // write CONECTs
145 for (vector<atom *>::iterator atomIt = AtomList.begin(); atomIt != AtomList.end(); atomIt++) {
146 writeNeighbors(file, 4, *atomIt);
147 }
148 }
149
150 // END
151 *file << "END" << endl;
152}
153
154/**
155 * Writes one line of tremolo-formatted data to the provided stream.
156 *
157 * \param stream where to write the line to
158 * \param *currentAtom the atom of which information should be written
159 * \param *name name of atom, i.e. H01
160 * \param AtomNo serial number of atom
161 * \param ResidueNo number of residue
162 */
163void PdbParser::saveLine(ostream* file, const atom* currentAtom, const char *name, const int AtomNo, const int ResidueNo) {
164 *file << "ATOM ";
165 *file << setw(6) << AtomNo; /* atom serial number */
166 *file << setw(1) << " ";
167 *file << setfill(' ') << left << setw(4) << name << right; /* atom name */
168 *file << setw(1) << " ";
169 *file << setfill(' ') << setw(3) << ((currentAtom->getMolecule() != NULL) ? currentAtom->getMolecule()->getName().substr(0,3) : "-"); /* residue name */
170 *file << setw(1) << " ";
171 *file << setfill(' ') << setw(1) << (char)('a'+(unsigned char)(AtomNo % 26)); /* letter for chain */
172 *file << setw(4) << ResidueNo; /* residue sequence number */
173 *file << setw(4) << " ";
174 for (int i=0;i<NDIM;i++) {
175 *file << setw(8) << setprecision(3) << showpoint << currentAtom->at(i); /* positional coordinate in Angstroem */
176 }
177 *file << setw(6) << setprecision(2) << showpoint << (double)currentAtom->getType()->getValence(); /* occupancy */
178 *file << setw(6) << setprecision(2) << showpoint << (double)currentAtom->getType()->getNoValenceOrbitals(); /* temperature factor */
179 *file << noshowpoint;
180 *file << setw(6) << " ";
181 *file << setw(4) << "0";
182 *file << setfill(' ') << setw(2) << currentAtom->getType()->getSymbol();
183 *file << setw(2) << "0";
184
185 *file << endl;
186}
187
188/**
189 * Writes the neighbor information of one atom to the provided stream.
190 *
191 * \param *file where to write neighbor information to
192 * \param MaxnumberOfNeighbors of neighbors
193 * \param *currentAtom to the atom of which to take the neighbor information
194 */
195void PdbParser::writeNeighbors(ostream* file, int MaxnumberOfNeighbors, atom* currentAtom) {
196 if (!currentAtom->ListOfBonds.empty()) {
197 *file << "CONECT";
198 *file << setw(5) << getAtomId(currentAtom->getId());
199 int MaxNo = 0;
200 for(BondList::iterator currentBond = currentAtom->ListOfBonds.begin(); currentBond != currentAtom->ListOfBonds.end(); ++currentBond) {
201 if (MaxNo < MaxnumberOfNeighbors) {
202 *file << setw(5) << getAtomId((*currentBond)->GetOtherAtom(currentAtom)->getId());
203 }
204 MaxNo++;
205 }
206 *file << endl;
207 }
208}
209
210
211/** Retrieves a value from PdbParser::atomIdMap.
212 * \param atomid key
213 * \return value
214 */
215int PdbParser::getAtomId(int atomid) const
216{
217 ASSERT(atomIdMap.find(atomid) != atomIdMap.end(), "PdbParser::getAtomId: atomid not present in Map.");
218 return (atomIdMap.find(atomid)->second);
219}
220
221/** Sets an entry in PdbParser::atomIdMap.
222 * \param localatomid key
223 * \param atomid value
224 * \return true - key not present, false - value present
225 */
226void PdbParser::setAtomId(int localatomid, int atomid)
227{
228 pair<std::map<int,int>::iterator, bool > inserter;
229 inserter = atomIdMap.insert( pair<int, int>(localatomid, atomid) );
230 ASSERT(inserter.second, "PdbParser::setAtomId: atomId already present in Map.");
231}
232
233/**
234 * Reads one data line of a tremolo file and interprets it according to the keys
235 * obtained from the ATOMDATA line.
236 *
237 * \param line to parse as an atom
238 */
239void PdbParser::readAtomDataLine(string line) {
240// vector<string>::iterator it;
241// stringstream lineStream;
242// atom* newAtom = World::getInstance().createAtom();
243// PdbAtomInfoContainer *atomInfo = NULL;
244// additionalAtomData[newAtom->getId()] = *(new PdbAtomInfoContainer);
245// atomInfo = &additionalAtomData[newAtom->getId()];
246// PdbKey::atomDataKey currentField;
247// string word;
248// int oldId;
249// double tmp;
250//
251// lineStream << line;
252// for (it = usedFields.begin(); it < usedFields.end(); it++) {
253// currentField = knownKeys[it->substr(0, it->find("="))];
254// switch (currentField) {
255// case PdbKey::x :
256// // for the moment, assume there are always three dimensions
257// for (int i=0;i<NDIM;i++) {
258// lineStream >> tmp;
259// newAtom->set(i, tmp);
260// }
261// break;
262// case PdbKey::u :
263// // for the moment, assume there are always three dimensions
264// lineStream >> newAtom->AtomicVelocity[0];
265// lineStream >> newAtom->AtomicVelocity[1];
266// lineStream >> newAtom->AtomicVelocity[2];
267// break;
268// case PdbKey::Type :
269// char type[3];
270// lineStream >> type;
271// newAtom->setType(World::getInstance().getPeriode()->FindElement(type));
272// ASSERT(newAtom->getType(), "Type was not set for this atom");
273// break;
274// case PdbKey::Id :
275// lineStream >> oldId;
276// atomIdMap[oldId] = newAtom->getId();
277// break;
278// case PdbKey::neighbors :
279// readNeighbors(&lineStream,
280// atoi(it->substr(it->find("=") + 1, 1).c_str()), newAtom->getId());
281// break;
282// default :
283// lineStream >> word;
284// atomInfo->set(currentField, word);
285// break;
286// }
287// }
288}
289
290/**
291 * Reads neighbor information for one atom from the input.
292 *
293 * \param stream where to read the information from
294 * \param number of neighbors to read
295 * \param world id of the atom the information belongs to
296 */
297void PdbParser::readNeighbors(stringstream* line, int numberOfNeighbors, int atomId) {
298// int neighborId = 0;
299// for (int i = 0; i < numberOfNeighbors; i++) {
300// *line >> neighborId;
301// // 0 is used to fill empty neighbor positions in the tremolo file.
302// if (neighborId > 0) {
303// additionalAtomData[atomId].neighbors.push_back(neighborId);
304// }
305// }
306}
307
308/**
309 * Adds the collected neighbor information to the atoms in the world. The atoms
310 * are found by their current ID and mapped to the corresponding atoms with the
311 * Id found in the parsed file.
312 */
313void PdbParser::processNeighborInformation() {
314// if (!isUsedField("neighbors")) {
315// return;
316// }
317//
318// for(map<int, PdbAtomInfoContainer>::iterator currentInfo = additionalAtomData.begin();
319// currentInfo != additionalAtomData.end(); currentInfo++
320// ) {
321// for(vector<int>::iterator neighbor = currentInfo->second.neighbors.begin();
322// neighbor != currentInfo->second.neighbors.end(); neighbor++
323// ) {
324// World::getInstance().getAtom(AtomById(currentInfo->first))
325// ->addBond(World::getInstance().getAtom(AtomById(atomIdMap[*neighbor])));
326// }
327// }
328}
329
330/**
331 * Replaces atom IDs read from the file by the corresponding world IDs. All IDs
332 * IDs of the input string will be replaced; expected separating characters are
333 * "-" and ",".
334 *
335 * \param string in which atom IDs should be adapted
336 *
337 * \return input string with modified atom IDs
338 */
339string PdbParser::adaptIdDependentDataString(string data) {
340// // there might be no IDs
341// if (data == "-") {
342// return "-";
343// }
344//
345// char separator;
346// int id;
347// stringstream line, result;
348// line << data;
349//
350// line >> id;
351// result << atomIdMap[id];
352// while (line.good()) {
353// line >> separator >> id;
354// result << separator << atomIdMap[id];
355// }
356//
357// return result.str();
358 return "";
359}
360
361
362PdbAtomInfoContainer::PdbAtomInfoContainer() :
363 name("-"),
364 resName("-"),
365 chainID("0"),
366 resSeq("0"),
367 occupancy("0"),
368 tempFactor("0"),
369 segID("0"),
370 charge("0")
371{}
372
373void PdbAtomInfoContainer::set(PdbKey::PdbDataKey key, string value) {
374 switch (key) {
375 case PdbKey::extType :
376 extType = value;
377 break;
378 case PdbKey::name :
379 name = value;
380 break;
381 case PdbKey::resName :
382 resName = value;
383 break;
384 case PdbKey::chainID :
385 chainID = value;
386 break;
387 case PdbKey::resSeq :
388 resSeq = value;
389 break;
390 case PdbKey::occupancy :
391 occupancy = value;
392 break;
393 case PdbKey::tempFactor :
394 tempFactor = value;
395 break;
396 case PdbKey::segID :
397 segID = value;
398 break;
399 case PdbKey::charge :
400 charge = value;
401 break;
402 default :
403 cout << "Unknown key: " << key << ", value: " << value << endl;
404 break;
405 }
406}
407
408string PdbAtomInfoContainer::get(PdbKey::PdbDataKey key) {
409 switch (key) {
410 case PdbKey::extType :
411 return extType;
412 case PdbKey::name :
413 return name;
414 case PdbKey::resName :
415 return resName;
416 case PdbKey::chainID :
417 return chainID;
418 case PdbKey::resSeq :
419 return resSeq;
420 case PdbKey::occupancy :
421 return occupancy;
422 case PdbKey::tempFactor :
423 return tempFactor;
424 case PdbKey::segID :
425 return segID;
426 case PdbKey::charge :
427 return charge;
428 default :
429 cout << "Unknown key: " << key << endl;
430 return "";
431 }
432}
433
Note: See TracBrowser for help on using the repository browser.