source: src/Parser/TremoloParser.cpp@ 97b825

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

Shortened constructors [Meyers, "Effective C++" item 12]

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