source: src/Parser/TremoloParser.cpp@ 15b670

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

shortened NAME of ParserLoadXyz and ParserSaveXyz actions, as it is the key in the ActionRegistry.

Signed-off-by: Frederik Heber <heber@…>

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