source: src/Parser/TremoloParser.cpp@ 4ac1aa

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 4ac1aa was 112b09, checked in by Tillmann Crueger <crueger@…>, 15 years ago

Added #include "Helpers/MemDebug.hpp" to all .cpp files

  • Property mode set to 100644
File size: 13.6 KB
Line 
1/*
2 * TremoloParser.cpp
3 *
4 * Created on: Mar 2, 2010
5 * Author: metzler
6 */
7
8#include "Helpers/MemDebug.hpp"
9
10#include "Helpers/Assert.hpp"
11#include "TremoloParser.hpp"
12#include "World.hpp"
13#include "atom.hpp"
14#include "element.hpp"
15#include "bond.hpp"
16#include "periodentafel.hpp"
17#include "Descriptors/AtomIdDescriptor.hpp"
18#include <map>
19#include <vector>
20
21
22using namespace std;
23using namespace boost;
24
25/**
26 * Constructor.
27 */
28TremoloParser::TremoloParser() {
29 knownKeys[" "] = TremoloKey::noKey; // with this we can detect invalid keys
30 knownKeys["x"] = TremoloKey::x;
31 knownKeys["u"] = TremoloKey::u;
32 knownKeys["F"] = TremoloKey::F;
33 knownKeys["stress"] = TremoloKey::stress;
34 knownKeys["Id"] = TremoloKey::Id;
35 knownKeys["neighbors"] = TremoloKey::neighbors;
36 knownKeys["imprData"] = TremoloKey::imprData;
37 knownKeys["GroupMeasureTypeNo"] = TremoloKey::GroupMeasureTypeNo;
38 knownKeys["Type"] = TremoloKey::Type;
39 knownKeys["extType"] = TremoloKey::extType;
40 knownKeys["name"] = TremoloKey::name;
41 knownKeys["resName"] = TremoloKey::resName;
42 knownKeys["chainID"] = TremoloKey::chainID;
43 knownKeys["resSeq"] = TremoloKey::resSeq;
44 knownKeys["occupancy"] = TremoloKey::occupancy;
45 knownKeys["tempFactor"] = TremoloKey::tempFactor;
46 knownKeys["segID"] = TremoloKey::segID;
47 knownKeys["Charge"] = TremoloKey::Charge;
48 knownKeys["charge"] = TremoloKey::charge;
49 knownKeys["GrpTypeNo"] = TremoloKey::GrpTypeNo;
50 knownKeys["torsion"] = TremoloKey::torsion;
51}
52
53/**
54 * Destructor.
55 */
56TremoloParser::~TremoloParser() {
57 usedFields.clear();
58 additionalAtomData.clear();
59 atomIdMap.clear();
60 knownKeys.clear();
61}
62
63/**
64 * Loads atoms from a tremolo-formatted file.
65 *
66 * \param tremolo file
67 */
68void TremoloParser::load(istream* file) {
69 string line;
70 string::size_type location;
71
72 usedFields.clear();
73 while (file->good()) {
74 std::getline(*file, line, '\n');
75 if (usedFields.empty()) {
76 location = line.find("ATOMDATA", 0);
77 if (location != string::npos) {
78 parseAtomDataKeysLine(line, location + 8);
79 }
80 }
81 if (line.length() > 0 && line.at(0) != '#') {
82 readAtomDataLine(line);
83 }
84 }
85
86 processNeighborInformation();
87 adaptImprData();
88 adaptTorsion();
89}
90
91/**
92 * Saves the World's current state into as a tremolo file.
93 *
94 * \param file where to save the state
95 */
96void TremoloParser::save(ostream* file) {
97 vector<atom*>::iterator atomIt;
98 vector<string>::iterator it;
99
100 *file << "# ATOMDATA";
101 for (it=usedFields.begin(); it < usedFields.end(); it++) {
102 *file << "\t" << *it;
103 }
104 *file << endl;
105 vector<atom *> AtomList = World::getInstance().getAllAtoms();
106 for (atomIt = AtomList.begin(); atomIt != AtomList.end(); atomIt++) {
107 saveLine(file, *atomIt);
108 }
109}
110
111/**
112 * Sets the keys for which data should be written to the stream when save is
113 * called.
114 *
115 * \param string of field names with the same syntax as for an ATOMDATA line
116 * but without the prexix "ATOMDATA"
117 */
118void TremoloParser::setFieldsForSave(std::string atomDataLine) {
119 parseAtomDataKeysLine(atomDataLine, 0);
120}
121
122
123/**
124 * Writes one line of tremolo-formatted data to the provided stream.
125 *
126 * \param stream where to write the line to
127 * \param reference to the atom of which information should be written
128 */
129void TremoloParser::saveLine(ostream* file, atom* currentAtom) {
130 vector<string>::iterator it;
131 TremoloKey::atomDataKey currentField;
132
133 for (it = usedFields.begin(); it != usedFields.end(); it++) {
134 currentField = knownKeys[it->substr(0, it->find("="))];
135 switch (currentField) {
136 case TremoloKey::x :
137 // for the moment, assume there are always three dimensions
138 *file << currentAtom->x[0] << "\t";
139 *file << currentAtom->x[1] << "\t";
140 *file << currentAtom->x[2] << "\t";
141 break;
142 case TremoloKey::u :
143 // for the moment, assume there are always three dimensions
144 *file << currentAtom->v[0] << "\t";
145 *file << currentAtom->v[1] << "\t";
146 *file << currentAtom->v[2] << "\t";
147 break;
148 case TremoloKey::Type :
149 *file << currentAtom->getType()->getSymbol() << "\t";
150 break;
151 case TremoloKey::Id :
152 *file << currentAtom->getId() << "\t";
153 break;
154 case TremoloKey::neighbors :
155 writeNeighbors(file, atoi(it->substr(it->find("=") + 1, 1).c_str()), currentAtom);
156 break;
157 default :
158 *file << (additionalAtomData.find(currentAtom->getId()) != additionalAtomData.end()
159 ? additionalAtomData[currentAtom->getId()].get(currentField)
160 : defaultAdditionalData.get(currentField));
161 *file << "\t";
162 break;
163 }
164 }
165
166 *file << endl;
167}
168
169/**
170 * Writes the neighbor information of one atom to the provided stream.
171 *
172 * \param stream where to write neighbor information to
173 * \param number of neighbors
174 * \param reference to the atom of which to take the neighbor information
175 */
176void TremoloParser::writeNeighbors(ostream* file, int numberOfNeighbors, atom* currentAtom) {
177 BondList::iterator currentBond = currentAtom->ListOfBonds.begin();
178 for (int i = 0; i < numberOfNeighbors; i++) {
179 *file << (currentBond != currentAtom->ListOfBonds.end()
180 ? (*currentBond)->GetOtherAtom(currentAtom)->getId() : 0) << "\t";
181 }
182}
183
184/**
185 * Stores keys from the ATOMDATA line.
186 *
187 * \param line to parse the keys from
188 * \param with which offset the keys begin within the line
189 */
190void TremoloParser::parseAtomDataKeysLine(string line, int offset) {
191 string keyword;
192 stringstream lineStream;
193
194 lineStream << line.substr(offset);
195 while (lineStream.good()) {
196 lineStream >> keyword;
197 if (knownKeys[keyword.substr(0, keyword.find("="))] == TremoloKey::noKey) {
198 // TODO: throw exception about unknown key
199 cout << "Unknown key: " << keyword << " is not part of the tremolo format specification." << endl;
200 break;
201 }
202 usedFields.push_back(keyword);
203 }
204}
205
206/**
207 * Reads one data line of a tremolo file and interprets it according to the keys
208 * obtained from the ATOMDATA line.
209 *
210 * \param line to parse as an atom
211 */
212void TremoloParser::readAtomDataLine(string line) {
213 vector<string>::iterator it;
214 stringstream lineStream;
215 atom* newAtom = World::getInstance().createAtom();
216 TremoloAtomInfoContainer *atomInfo = NULL;
217 additionalAtomData[newAtom->getId()] = *(new TremoloAtomInfoContainer);
218 atomInfo = &additionalAtomData[newAtom->getId()];
219 TremoloKey::atomDataKey currentField;
220 string word;
221 int oldId;
222
223 lineStream << line;
224 for (it = usedFields.begin(); it < usedFields.end(); it++) {
225 currentField = knownKeys[it->substr(0, it->find("="))];
226 switch (currentField) {
227 case TremoloKey::x :
228 // for the moment, assume there are always three dimensions
229 lineStream >> newAtom->x[0];
230 lineStream >> newAtom->x[1];
231 lineStream >> newAtom->x[2];
232 break;
233 case TremoloKey::u :
234 // for the moment, assume there are always three dimensions
235 lineStream >> newAtom->v[0];
236 lineStream >> newAtom->v[1];
237 lineStream >> newAtom->v[2];
238 break;
239 case TremoloKey::Type :
240 char type[3];
241 lineStream >> type;
242 newAtom->setType(World::getInstance().getPeriode()->FindElement(type));
243 ASSERT(newAtom->getType(), "Type was not set for this atom");
244 break;
245 case TremoloKey::Id :
246 lineStream >> oldId;
247 atomIdMap[oldId] = newAtom->getId();
248 break;
249 case TremoloKey::neighbors :
250 readNeighbors(&lineStream,
251 atoi(it->substr(it->find("=") + 1, 1).c_str()), newAtom->getId());
252 break;
253 default :
254 lineStream >> word;
255 atomInfo->set(currentField, word);
256 break;
257 }
258 }
259}
260
261/**
262 * Reads neighbor information for one atom from the input.
263 *
264 * \param stream where to read the information from
265 * \param number of neighbors to read
266 * \param world id of the atom the information belongs to
267 */
268void TremoloParser::readNeighbors(stringstream* line, int numberOfNeighbors, int atomId) {
269 int neighborId = 0;
270 for (int i = 0; i < numberOfNeighbors; i++) {
271 *line >> neighborId;
272 // 0 is used to fill empty neighbor positions in the tremolo file.
273 if (neighborId > 0) {
274 additionalAtomData[atomId].neighbors.push_back(neighborId);
275 }
276 }
277}
278
279/**
280 * Checks whether the provided name is within the list of used fields.
281 *
282 * \param field name to check
283 *
284 * \return true if the field name is used
285 */
286bool TremoloParser::isUsedField(string fieldName) {
287 bool fieldNameExists = false;
288 for (vector<string>::iterator usedField = usedFields.begin(); usedField != usedFields.end(); usedField++) {
289 if (usedField->substr(0, usedField->find("=")) == fieldName)
290 fieldNameExists = true;
291 }
292
293 return fieldNameExists;
294}
295
296
297/**
298 * Adds the collected neighbor information to the atoms in the world. The atoms
299 * are found by their current ID and mapped to the corresponding atoms with the
300 * Id found in the parsed file.
301 */
302void TremoloParser::processNeighborInformation() {
303 if (!isUsedField("neighbors")) {
304 return;
305 }
306
307 for(map<int, TremoloAtomInfoContainer>::iterator currentInfo = additionalAtomData.begin();
308 currentInfo != additionalAtomData.end(); currentInfo++
309 ) {
310 for(vector<int>::iterator neighbor = currentInfo->second.neighbors.begin();
311 neighbor != currentInfo->second.neighbors.end(); neighbor++
312 ) {
313 World::getInstance().getAtom(AtomById(currentInfo->first))
314 ->addBond(World::getInstance().getAtom(AtomById(atomIdMap[*neighbor])));
315 }
316 }
317}
318
319/**
320 * Replaces atom IDs read from the file by the corresponding world IDs. All IDs
321 * IDs of the input string will be replaced; expected separating characters are
322 * "-" and ",".
323 *
324 * \param string in which atom IDs should be adapted
325 *
326 * \return input string with modified atom IDs
327 */
328string TremoloParser::adaptIdDependentDataString(string data) {
329 // there might be no IDs
330 if (data == "-") {
331 return "-";
332 }
333
334 char separator;
335 int id;
336 stringstream line, result;
337 line << data;
338
339 line >> id;
340 result << atomIdMap[id];
341 while (line.good()) {
342 line >> separator >> id;
343 result << separator << atomIdMap[id];
344 }
345
346 return result.str();
347}
348
349/**
350 * Corrects the atom IDs in each imprData entry to the corresponding world IDs
351 * as they might differ from the originally read IDs.
352 */
353void TremoloParser::adaptImprData() {
354 if (!isUsedField("imprData")) {
355 return;
356 }
357
358 for(map<int, TremoloAtomInfoContainer>::iterator currentInfo = additionalAtomData.begin();
359 currentInfo != additionalAtomData.end(); currentInfo++
360 ) {
361 currentInfo->second.imprData = adaptIdDependentDataString(currentInfo->second.imprData);
362 }
363}
364
365/**
366 * Corrects the atom IDs in each torsion entry to the corresponding world IDs
367 * as they might differ from the originally read IDs.
368 */
369void TremoloParser::adaptTorsion() {
370 if (!isUsedField("torsion")) {
371 return;
372 }
373
374 for(map<int, TremoloAtomInfoContainer>::iterator currentInfo = additionalAtomData.begin();
375 currentInfo != additionalAtomData.end(); currentInfo++
376 ) {
377 currentInfo->second.torsion = adaptIdDependentDataString(currentInfo->second.torsion);
378 }
379}
380
381
382TremoloAtomInfoContainer::TremoloAtomInfoContainer() {
383 F = "0";
384 stress = "0";
385 imprData = "-";
386 GroupMeasureTypeNo = "0";
387 extType = "-";
388 name = "-";
389 resName = "-";
390 chainID = "0";
391 resSeq = "0";
392 occupancy = "0";
393 tempFactor = "0";
394 segID = "0";
395 Charge = "0";
396 charge = "0";
397 GrpTypeNo = "0";
398 torsion = "-";
399 neighbors = vector<int>(0, 5);
400}
401
402void TremoloAtomInfoContainer::set(TremoloKey::atomDataKey key, string value) {
403 switch (key) {
404 case TremoloKey::F :
405 F = value;
406 break;
407 case TremoloKey::stress :
408 stress = value;
409 break;
410 case TremoloKey::imprData :
411 imprData = value;
412 break;
413 case TremoloKey::GroupMeasureTypeNo :
414 GroupMeasureTypeNo = value;
415 break;
416 case TremoloKey::extType :
417 extType = value;
418 break;
419 case TremoloKey::name :
420 name = value;
421 break;
422 case TremoloKey::resName :
423 resName = value;
424 break;
425 case TremoloKey::chainID :
426 chainID = value;
427 break;
428 case TremoloKey::resSeq :
429 resSeq = value;
430 break;
431 case TremoloKey::occupancy :
432 occupancy = value;
433 break;
434 case TremoloKey::tempFactor :
435 tempFactor = value;
436 break;
437 case TremoloKey::segID :
438 segID = value;
439 break;
440 case TremoloKey::Charge :
441 Charge = value;
442 break;
443 case TremoloKey::charge :
444 charge = value;
445 break;
446 case TremoloKey::GrpTypeNo :
447 GrpTypeNo = value;
448 break;
449 case TremoloKey::torsion :
450 torsion = value;
451 break;
452 default :
453 cout << "Unknown key: " << key << ", value: " << value << endl;
454 break;
455 }
456}
457
458string TremoloAtomInfoContainer::get(TremoloKey::atomDataKey key) {
459 switch (key) {
460 case TremoloKey::F :
461 return F;
462 case TremoloKey::stress :
463 return stress;
464 case TremoloKey::imprData :
465 return imprData;
466 case TremoloKey::GroupMeasureTypeNo :
467 return GroupMeasureTypeNo;
468 case TremoloKey::extType :
469 return extType;
470 case TremoloKey::name :
471 return name;
472 case TremoloKey::resName :
473 return resName;
474 case TremoloKey::chainID :
475 return chainID;
476 case TremoloKey::resSeq :
477 return resSeq;
478 case TremoloKey::occupancy :
479 return occupancy;
480 case TremoloKey::tempFactor :
481 return tempFactor;
482 case TremoloKey::segID :
483 return segID;
484 case TremoloKey::Charge :
485 return Charge;
486 case TremoloKey::charge :
487 return charge;
488 case TremoloKey::GrpTypeNo :
489 return GrpTypeNo;
490 case TremoloKey::torsion :
491 return torsion;
492 default :
493 cout << "Unknown key: " << key << endl;
494 return "";
495 }
496}
497
Note: See TracBrowser for help on using the repository browser.