source: src/Parser/TremoloParser.cpp@ d74077

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

Member variable Vector and element of class atom are now private.

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