source: src/Parser/TremoloParser.cpp@ 0ba410

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 0ba410 was 839e85, checked in by Tillmann Crueger <crueger@…>, 15 years ago

Removed some unecessary opened namespaces

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