45#include "io/ShapeAtomTypesSectionParser.hpp"
52#include "types/AtomType.hpp"
53#include "types/DirectionalAdapter.hpp"
55#include "utils/CaseConversion.hpp"
57#include "utils/simError.h"
61 ShapeAtomTypesSectionParser::ShapeAtomTypesSectionParser(ForceFieldOptions&) {
62 setSectionName(
"ShapeAtomTypes");
65 void ShapeAtomTypesSectionParser::parseLine(ForceField& ff,
66 const std::string& line,
68 StringTokenizer tokenizer(line);
70 if (tokenizer.countTokens() >= 2) {
71 std::string shapeTypeName = tokenizer.nextToken();
72 std::string shapeFile = tokenizer.nextToken();
74 AtomType* atomType = ff.getAtomType(shapeTypeName);
75 if (atomType == NULL) {
76 atomType =
new AtomType();
77 int ident = ff.getNAtomType() + 1;
78 atomType->setIdent(ident);
79 atomType->setName(shapeTypeName);
80 ff.addAtomType(shapeTypeName, atomType);
83 parseShapeFile(ff, shapeFile, atomType);
86 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
87 "ShapesAtomTypesSectionParser Error: "
88 "Not enough tokens at line %d\n",
90 painCave.severity = OPENMD_ERROR;
96 void ShapeAtomTypesSectionParser::parseShapeFile(ForceField&,
97 std::string& shapeFileName,
99 const int bufferSize = 65535;
100 char buffer[bufferSize];
104 RealSphericalHarmonic* rsh;
105 std::vector<RealSphericalHarmonic*> functionVector;
106 ifstrstream shapeStream;
107 std::string tempString;
111 tempPath = getenv(
"FORCE_PARAM_PATH");
113 if (tempPath == NULL) {
115 STR_DEFINE(ffPath, FRC_PATH);
120 shapeStream.open(shapeFileName.c_str());
122 if (!shapeStream.is_open()) {
125 tempString += shapeFileName;
126 shapeFileName = tempString;
128 shapeStream.open(shapeFileName.c_str());
130 if (!shapeStream.is_open()) {
131 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
132 "Error opening the shape file:\n"
134 "\tHave you tried setting the FORCE_PARAM_PATH environment "
136 shapeFileName.c_str());
137 painCave.severity = OPENMD_ERROR;
138 painCave.isFatal = 1;
143 ShapeAtomType* st =
new ShapeAtomType();
147 shapeStream.getline(buffer, bufferSize);
150 while (!shapeStream.eof()) {
152 if (buffer[0] !=
'!' && buffer[0] !=
'#') {
155 StringTokenizer tokenInfo(buffer);
157 if (tokenInfo.countTokens() != 0) {
158 if (tokenInfo.countTokens() < 5) {
159 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
160 "ShapesAtomTypesSectionParser Error: Not enough "
161 "information on a ShapeInfo line in file: %s\n",
162 shapeFileName.c_str());
163 painCave.severity = OPENMD_ERROR;
164 painCave.isFatal = 1;
167 tokenInfo.skipToken();
168 at->setMass(tokenInfo.nextTokenAsDouble());
169 DirectionalAdapter da = DirectionalAdapter(at);
171 I(0, 0) = tokenInfo.nextTokenAsDouble();
172 I(1, 1) = tokenInfo.nextTokenAsDouble();
173 I(2, 2) = tokenInfo.nextTokenAsDouble();
174 da.makeDirectional(I);
178 shapeStream.getline(buffer, bufferSize);
182 findBegin(shapeStream,
"ContactFunctions");
183 functionVector.clear();
185 shapeStream.getline(buffer, bufferSize);
186 while (!shapeStream.eof()) {
188 if (buffer[0] !=
'!' && buffer[0] !=
'#') {
191 StringTokenizer tokenInfo1(buffer);
193 if (tokenInfo1.countTokens() != 0) {
194 if (tokenInfo1.countTokens() < 4) {
195 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
196 "ShapesAtomTypesSectionParser Error: Not enough "
197 "information on a ContactFunctions line in file: %s\n",
198 shapeFileName.c_str());
199 painCave.severity = OPENMD_ERROR;
200 painCave.isFatal = 1;
204 rsh =
new RealSphericalHarmonic();
205 rsh->setL(tokenInfo1.nextTokenAsInt());
206 rsh->setM(tokenInfo1.nextTokenAsInt());
207 token = tokenInfo1.nextToken();
210 rsh->makeSinFunction();
212 rsh->makeCosFunction();
213 rsh->setCoefficient(tokenInfo1.nextTokenAsDouble());
215 functionVector.push_back(rsh);
219 shapeStream.getline(buffer, bufferSize);
223 st->setContactFuncs(functionVector);
226 findBegin(shapeStream,
"RangeFunctions");
227 functionVector.clear();
229 shapeStream.getline(buffer, bufferSize);
230 while (!shapeStream.eof()) {
232 if (buffer[0] !=
'!' && buffer[0] !=
'#') {
235 StringTokenizer tokenInfo2(buffer);
237 if (tokenInfo2.countTokens() != 0) {
238 if (tokenInfo2.countTokens() < 4) {
239 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
240 "ShapesAtomTypesSectionParser Error: Not enough "
241 "information on a RangeFunctions line in file: %s\n",
242 shapeFileName.c_str());
243 painCave.severity = OPENMD_ERROR;
244 painCave.isFatal = 1;
248 rsh =
new RealSphericalHarmonic();
249 rsh->setL(tokenInfo2.nextTokenAsInt());
250 rsh->setM(tokenInfo2.nextTokenAsInt());
251 token = tokenInfo2.nextToken();
254 rsh->makeSinFunction();
256 rsh->makeCosFunction();
257 rsh->setCoefficient(tokenInfo2.nextTokenAsDouble());
259 functionVector.push_back(rsh);
263 shapeStream.getline(buffer, bufferSize);
267 st->setRangeFuncs(functionVector);
270 findBegin(shapeStream,
"StrengthFunctions");
271 functionVector.clear();
273 shapeStream.getline(buffer, bufferSize);
274 while (!shapeStream.eof()) {
276 if (buffer[0] !=
'!' && buffer[0] !=
'#') {
279 StringTokenizer tokenInfo3(buffer);
281 if (tokenInfo3.countTokens() != 0) {
282 if (tokenInfo3.countTokens() < 4) {
283 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
284 "ShapesAtomTypesSectionParser Error: Not enough "
285 "information on a StrengthFunctions line in file: %s\n",
286 shapeFileName.c_str());
287 painCave.severity = OPENMD_ERROR;
288 painCave.isFatal = 1;
292 rsh =
new RealSphericalHarmonic();
293 rsh->setL(tokenInfo3.nextTokenAsInt());
294 rsh->setM(tokenInfo3.nextTokenAsInt());
295 token = tokenInfo3.nextToken();
298 rsh->makeSinFunction();
300 rsh->makeCosFunction();
301 rsh->setCoefficient(tokenInfo3.nextTokenAsDouble());
303 functionVector.push_back(rsh);
307 shapeStream.getline(buffer, bufferSize);
311 st->setStrengthFuncs(functionVector);
313 std::shared_ptr<GenericData>(
new ShapeAtypeData(
"Shape", st)));
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
int findBegin(std::istream &theStream, const char *startText)
Finds the location of the string "begin <startText>" in an input stream.
int isEndLine(char *line)
discovers whether or not the line contains the "end" token