source: src/Parser/TremoloParser.cpp@ 701ad6

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

Added ifdef HAVE_CONFIG and config.h include to each and every cpp file.

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