source: src/ConfigFileBuffer.cpp@ d3abb1

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 d3abb1 was 4fdc65, checked in by Frederik Heber <heber@…>, 14 years ago

FIX: XyzParser and PcpParser fail on empty but present config files.

  • Property mode set to 100644
File size: 7.1 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * ConfigFileBuffer.cpp
10 *
11 * Created on: 12.06.2010
12 * Author: heber
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20#include "CodePatterns/MemDebug.hpp"
21
22#include <iostream>
23#include <boost/tokenizer.hpp>
24#include <string>
25
26#include "ConfigFileBuffer.hpp"
27#include "CodePatterns/Verbose.hpp"
28#include "CodePatterns/Log.hpp"
29#include "Helpers/defs.hpp"
30#include "Helpers/helpers.hpp"
31#include "World.hpp"
32
33/******************************** Functions for class ConfigFileBuffer **********************/
34
35/** Structure containing compare function for Ion_Type sorting.
36 */
37struct IonTypeCompare {
38 bool operator()(std::string s1, std::string s2) const {
39 ConvertTo<int> toInt;
40 boost::char_separator<char> sep("_");
41 tokenizer tokens1(s1,sep);
42 tokenizer tokens2(s2,sep);
43 tokenizer::iterator tok_iter1 = tokens1.begin();
44 tokenizer::iterator tok_iter2 = tokens2.begin();
45 ++tok_iter1;
46 ++tok_iter2;
47
48 std::string element1(*tok_iter1++);
49 std::string element2(*tok_iter2++);
50 int elementno1 = toInt(element1.substr(4,string::npos));
51 int elementno2 = toInt(element2.substr(4,string::npos));
52 if (elementno1 != elementno2)
53 return elementno1 < elementno2;
54 else {
55 std::string atom1(*tok_iter1);
56 std::string atom2(*tok_iter2);
57 int atomno1 = toInt(atom1);
58 int atomno2 = toInt(atom2);
59 return atomno1 < atomno2;
60 }
61
62// char number1[8];
63// char number2[8];
64// const char *dummy1 = s1.c_str();
65// const char *dummy2 = s2.c_str();
66// //Log() << Verbose(0) << s1 << " " << s2 << endl;
67// dummy1 = strchr(s1, '_')+sizeof(char)*5; // go just after "Ion_Type"
68// dummy2 = strchr(dummy1, '_');
69// strncpy(number1, dummy1, dummy2-dummy1); // copy the number
70// number1[dummy2-dummy1]='\0';
71// dummy1 = strchr(s2, '_')+sizeof(char)*5; // go just after "Ion_Type"
72// dummy2 = strchr(dummy1, '_');
73// strncpy(number2, dummy1, dummy2-dummy1); // copy the number
74// number2[dummy2-dummy1]='\0';
75// if (atoi(number1) != atoi(number2))
76// return (atoi(number1) < atoi(number2));
77// else {
78// dummy1 = strchr(s1, '_')+sizeof(char);
79// dummy1 = strchr(dummy1, '_')+sizeof(char);
80// dummy2 = strchr(dummy1, ' ') < strchr(dummy1, '\t') ? strchr(dummy1, ' ') : strchr(dummy1, '\t');
81// strncpy(number1, dummy1, dummy2-dummy1); // copy the number
82// number1[dummy2-dummy1]='\0';
83// dummy1 = strchr(s2, '_')+sizeof(char);
84// dummy1 = strchr(dummy1, '_')+sizeof(char);
85// dummy2 = strchr(dummy1, ' ') < strchr(dummy1, '\t') ? strchr(dummy1, ' ') : strchr(dummy1, '\t');
86// strncpy(number2, dummy1, dummy2-dummy1); // copy the number
87// number2[dummy2-dummy1]='\0';
88// return (atoi(number1) < atoi(number2));
89// }
90 }
91
92 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
93};
94
95
96/** Constructor for ConfigFileBuffer class.
97 */
98ConfigFileBuffer::ConfigFileBuffer() :
99 buffer(NULL),
100 LineMapping(NULL),
101 CurrentLine(0),
102 NoLines(0)
103{
104};
105
106/** Constructor for ConfigFileBuffer class with filename to be parsed.
107 * \param *filename file name
108 */
109ConfigFileBuffer::ConfigFileBuffer(const char * const filename) :
110 buffer(NULL),
111 LineMapping(NULL),
112 CurrentLine(0),
113 NoLines(0)
114{
115 InitFileBuffer(filename);
116}
117
118void ConfigFileBuffer::InitFileBuffer(const char * const filename)
119{
120 ifstream *file= new ifstream(filename);
121 InitFileBuffer(file);
122}
123
124void ConfigFileBuffer::InitFileBuffer(istream *file)
125{
126 char line[MAXSTRINGSIZE];
127
128 RemoveMapping();
129
130 // prescan number of lines
131 if (file->fail()) {
132 DoeLog(1) && (eLog()<< Verbose(1) << "config file missing!" << endl);
133 return;
134 }
135 NoLines = 0; // we're overcounting by one
136 long file_position = file->tellg(); // mark current position
137 while (file->good()) {
138 file->getline(line, MAXSTRINGSIZE-1);
139 NoLines++;
140 }
141 file->clear();
142 file->seekg(file_position, ios::beg);
143 DoLog(1) && (Log() << Verbose(1) << NoLines-1 << " lines were recognized." << endl);
144
145 // allocate buffer's 1st dimension
146 if (buffer != NULL) {
147 DoeLog(1) && (eLog()<< Verbose(1) << "FileBuffer->buffer is not NULL!" << endl);
148 return;
149 } else
150 buffer = new char *[NoLines];
151
152 // scan each line and put into buffer
153 int lines=0;
154 int i;
155 do {
156 buffer[lines] = new char[MAXSTRINGSIZE];
157 file->getline(buffer[lines], MAXSTRINGSIZE-1);
158 i = strlen(buffer[lines]);
159 buffer[lines][i] = '\n';
160 buffer[lines][i+1] = '\0';
161 lines++;
162 } while((!file->eof()) && (lines < NoLines));
163 DoLog(1) && (Log() << Verbose(1) << lines-1 << " lines were read into the buffer." << endl);
164 file->clear();
165 file->seekg(file_position, ios::beg);
166
167 InitMapping();
168}
169
170/** Destructor for ConfigFileBuffer class.
171 */
172ConfigFileBuffer::~ConfigFileBuffer()
173{
174 RemoveBuffer();
175 RemoveMapping();
176}
177
178
179/** Create trivial mapping.
180 */
181void ConfigFileBuffer::InitMapping()
182{
183 LineMapping = new int[NoLines];
184 for (int i=0;i<NoLines;i++)
185 LineMapping[i] = i;
186 MappingAllocated = true;
187}
188
189/** Remove allocated mapping.
190 */
191void ConfigFileBuffer::RemoveMapping()
192{
193 delete[](LineMapping);
194 MappingAllocated = false;
195}
196
197/** Remove allocated mapping.
198 */
199void ConfigFileBuffer::RemoveBuffer()
200{
201 for(int i=0;i<NoLines;++i)
202 delete[](buffer[i]);
203 delete[](buffer);
204}
205
206
207/** Creates a mapping for the \a *FileBuffer's lines containing the Ion_Type keyword such that they are sorted.
208 * \a *map on return contains a list of NoAtom entries such that going through the list, yields indices to the
209 * lines in \a *FileBuffer in a sorted manner of the Ion_Type?_? keywords. We assume that ConfigFileBuffer::CurrentLine
210 * points to first Ion_Type entry.
211 * \param *FileBuffer pointer to buffer structure
212 * \param NoAtoms of subsequent lines to look at
213 */
214void ConfigFileBuffer::MapIonTypesInBuffer(const int NoAtoms)
215{
216 std::multimap<std::string, int, IonTypeCompare> IonTypeLineMap;
217 if (!MappingAllocated) {
218 InitMapping();
219 }
220
221 typedef boost::tokenizer<boost::char_separator<char> >
222 tokenizer;
223 boost::char_separator<char> sep("\t ");
224
225 // put all into hashed map
226 for (int i=CurrentLine; i<NoLines; ++i) {
227 std::string line(buffer[i]);
228 tokenizer tokens(line, sep);
229 if (tokens.begin() != tokens.end()) {
230 const std::string token = *tokens.begin();
231 if (token.find("Ion_Type") != string::npos) {
232 IonTypeLineMap.insert(pair<std::string, int> (token, i));
233 }
234 }
235 }
236
237 // fill map (aka IonType1_1, IonType1_1, IonType1_1, IonType1_2, IonType1_2, IonType1_2, ...
238 // ..., IonType2_1, IonType2_1, IonType2_1, ...)
239 int nr=0;
240 for (map<std::string, int, IonTypeCompare>::iterator runner = IonTypeLineMap.begin(); runner != IonTypeLineMap.end(); ++runner) {
241 if (CurrentLine+nr < NoLines)
242 LineMapping[CurrentLine+(nr++)] = runner->second;
243 else {
244 DoeLog(0) && (eLog()<< Verbose(0) << "config::MapIonTypesInBuffer - NoLines is wrong: We are past the end of the file!" << endl);
245 performCriticalExit();
246 }
247 }
248}
Note: See TracBrowser for help on using the repository browser.