#include <openbabel/babelconfig.h>
#include <openbabel/obmolecformat.h>
#include <openbabel/mol.h>
#include <openbabel/atom.h>
#include <openbabel/bond.h>
#include <openbabel/obiter.h>
#include <openbabel/elements.h>
#include <openbabel/generic.h>
#include <algorithm>
using namespace std;
namespace Gamess {
}
namespace OpenBabel {
#define BOHR_TO_ANGSTROM 0.529177249
#define ANGSTROM_TO_BOHR 1.889725989
class GAMESSOutputFormat: public OBMoleculeFormat {
public:
GAMESSOutputFormat() {
OBConversion::RegisterFormat("gam", this, "chemical/x-gamess-output");
OBConversion::RegisterFormat("gamout", this);
OBConversion::RegisterFormat("gamess", this);
}
virtual const char* Description() {
return
"GAMESS Output\n"
"Read Options e.g. -as\n"
" s Output single bonds only\n"
" b Disable bonding entirely\n"
" c Read multiple conformers\n\n";
}
virtual const char* SpecificationURL() {
return "http://www.msg.ameslab.gov/GAMESS/doc.menu.html";
}
virtual const char* GetMIMEType() {
return "chemical/x-gamess-output";
}
virtual unsigned int Flags() {
return READONEONLY | NOTWRITABLE;
}
virtual bool ReadMolecule(OBBase* pOb, OBConversion* pConv);
private:
};
GAMESSOutputFormat theGAMESSOutputFormat;
class GAMESSInputFormat: public OBMoleculeFormat {
public:
GAMESSInputFormat() {
OBConversion::RegisterFormat("inp", this, "chemical/x-gamess-input");
OBConversion::RegisterFormat("gamin", this);
OBConversion::RegisterOptionParam("k", nullptr, 1, OBConversion::OUTOPTIONS);
OBConversion::RegisterOptionParam("f", nullptr, 1, OBConversion::OUTOPTIONS);
}
virtual const char* Description() {
return
"GAMESS Input\n"
"Write Options e.g. -xk\n"
" k \"keywords\" Use the specified keywords for input\n"
" f <file> Read the file specified for input keywords\n\n";
}
virtual const char* SpecificationURL() {
return "http://www.msg.ameslab.gov/GAMESS/doc.menu.html";
}
virtual const char* GetMIMEType() {
return "chemical/x-gamess-input";
}
virtual unsigned int Flags() {
return WRITEONEONLY; }
virtual bool WriteMolecule(OBBase* pOb, OBConversion* pConv);
virtual bool ReadMolecule(OBBase* pOb, OBConversion* pConv);
};
GAMESSInputFormat theGAMESSInputFormat;
bool GAMESSOutputFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv) {
OBMol* pmol = pOb->CastAndClear<OBMol>();
if (pmol == nullptr)
return false;
istream& ifs = *pConv->GetInStream();
OBMol& mol = *pmol;
const char* title = pConv->GetTitle();
char buffer[BUFF_SIZE];
string str, str1;
double x, y, z;
OBAtom* atom;
vector<string> vs;
bool hasPartialCharges = false;
int aHOMO = 0;
int bHOMO = 0;
vector<double> orbitals;
vector<std::string> symmetries;
std::vector<double*> vconf; std::vector<double> coordinates; int natoms = 0;
int ndummyatoms = 0;
OBConformerData* confData = new OBConformerData();
confData->SetOrigin(fileformatInput);
std::vector<unsigned short> confDimensions = confData->GetDimension(); std::vector<double> confEnergies = confData->GetEnergies();
std::vector< std::vector< vector3 > > confForces = confData->GetForces();
vector<double> frequencies, intensities, raman_intensities;
vector< vector<vector3> > displacements;
int lowFreqModesBegin; int lowFreqModesEnd; int numFreq, numIntens, numDisp; numFreq = numIntens = numDisp = 0;
int charge = 0;
int mult = 1;
OBSetData* gmsset = new OBSetData();
gmsset->SetAttribute("gamess");
gmsset->SetOrigin(fileformatInput);
mol.Clear();
mol.BeginModify();
while (ifs.getline(buffer, BUFF_SIZE)) {
if (strstr(buffer, "ICHARG=")) {
tokenize(vs, (strstr(buffer, "ICHARG=")));
charge=atoi(vs[1].c_str());
}
if (strstr(buffer, "MULT ")) {
tokenize(vs, (strstr(buffer, "MULT ")));
mult=atoi(vs[2].c_str());
}
if (strstr(buffer, "ATOMIC COORDINATES (BOHR)") != nullptr) {
ifs.getline(buffer, BUFF_SIZE); ifs.getline(buffer, BUFF_SIZE);
tokenize(vs, buffer);
while (vs.size() == 5) {
int atomicNum = atoi(vs[1].c_str());
x = atof((char*) vs[2].c_str()) * BOHR_TO_ANGSTROM;
y = atof((char*) vs[3].c_str()) * BOHR_TO_ANGSTROM;
z = atof((char*) vs[4].c_str()) * BOHR_TO_ANGSTROM;
if (natoms == 0) {
atom = mol.NewAtom();
atom->SetAtomicNum(atomicNum);
}
coordinates.push_back(x);
coordinates.push_back(y);
coordinates.push_back(z);
if (!ifs.getline(buffer, BUFF_SIZE))
break;
tokenize(vs, buffer);
}
natoms = mol.NumAtoms();
double* tmpCoords = new double [(natoms)*3];
memcpy(tmpCoords, &coordinates[0], sizeof(double)*natoms*3);
vconf.push_back(tmpCoords);
coordinates.clear();
confDimensions.push_back(3);
} else if (strstr(buffer, "MULTIPOLE COORDINATES, ELECTRONIC AND NUCLEAR CHARGES") != nullptr) {
double* tmpCoords = vconf.at(0);
for (int i=0; i < natoms*3; i++)
coordinates.push_back(tmpCoords[i]);
ifs.getline(buffer, BUFF_SIZE); ifs.getline(buffer, BUFF_SIZE);
ifs.getline(buffer, BUFF_SIZE);
tokenize(vs, buffer);
while (vs.size() == 6) {
int atomicNum;
if (atof((char*) vs[5].c_str()) > 0.0) {
atomicNum = OBElements::GetAtomicNum(vs[0].substr(0, 1).c_str());
if (natoms == 0) {
atom = mol.NewAtom();
atom->SetAtomicNum(atomicNum);
}
x = atof((char*) vs[1].c_str())* BOHR_TO_ANGSTROM;
y = atof((char*) vs[2].c_str())* BOHR_TO_ANGSTROM;
z = atof((char*) vs[3].c_str())* BOHR_TO_ANGSTROM;
coordinates.push_back(x);
coordinates.push_back(y);
coordinates.push_back(z);
} else if (vs[0].substr(0, 1) == "Z") {
atomicNum = OBElements::GetAtomicNum(vs[0].substr(1, 1).c_str());
x = atof((char*) vs[1].c_str())* BOHR_TO_ANGSTROM;
y = atof((char*) vs[2].c_str())* BOHR_TO_ANGSTROM;
z = atof((char*) vs[3].c_str())* BOHR_TO_ANGSTROM;
coordinates.push_back(x);
coordinates.push_back(y);
coordinates.push_back(z);
}
if (!ifs.getline(buffer, BUFF_SIZE))
break;
tokenize(vs, buffer);
}
ndummyatoms = mol.NumAtoms();
memcpy(tmpCoords, &coordinates[0], sizeof(double)*natoms*3);
vconf[0] = tmpCoords;
coordinates.clear();
} else if (strstr(buffer, "COORDINATES OF ALL ATOMS ARE (ANGS)") != nullptr) {
ifs.getline(buffer, BUFF_SIZE); ifs.getline(buffer, BUFF_SIZE); ifs.getline(buffer, BUFF_SIZE);
tokenize(vs, buffer);
while (vs.size() == 5) {
int atomicNum = atoi(vs[1].c_str());
x = atof((char*) vs[2].c_str());
y = atof((char*) vs[3].c_str());
z = atof((char*) vs[4].c_str());
if (natoms == 0) {
atom = mol.NewAtom();
atom->SetAtomicNum(atomicNum);
}
coordinates.push_back(x);
coordinates.push_back(y);
coordinates.push_back(z);
if (!ifs.getline(buffer, BUFF_SIZE))
break;
tokenize(vs, buffer);
}
if (strstr(buffer, "COORDINATES OF FRAGMENT") != nullptr) {
ifs.getline(buffer, BUFF_SIZE); ifs.getline(buffer, BUFF_SIZE);
ifs.getline(buffer, BUFF_SIZE);
tokenize(vs, buffer);
while (vs.size() > 0) {
if (vs.size() == 1) {
vector<string> vs2;
char delim[] = "=";
tokenize(vs2, buffer, delim);
} else {
int atomicNum;
if (vs[0].substr(0, 1) == "Z")
atomicNum = OBElements::GetAtomicNum(vs[0].substr(1, 1).c_str());
else
atomicNum = OBElements::GetAtomicNum(vs[0].substr(0, 1).c_str());
if (natoms == 0) {
atom = mol.NewAtom();
atom->SetAtomicNum(atomicNum);
}
x = atof((char*) vs[1].c_str());
y = atof((char*) vs[2].c_str());
z = atof((char*) vs[3].c_str());
coordinates.push_back(x);
coordinates.push_back(y);
coordinates.push_back(z);
}
if (!ifs.getline(buffer, BUFF_SIZE))
break;
tokenize(vs, buffer);
}
}
natoms = mol.NumAtoms();
double* tmpCoords = new double [(natoms)*3];
memcpy(tmpCoords, &coordinates[0], sizeof(double)*natoms*3);
vconf.push_back(tmpCoords);
coordinates.clear();
confDimensions.push_back(3);
} else if (strstr(buffer, "NSERCH=") != nullptr && strstr(buffer, "ENERGY=") != nullptr) {
char* tok = strtok(buffer, " ="); int n = 0;
while (true) {
tok = strtok(nullptr, " =");
if (tok == nullptr)
break;
n++;
if (n == 3) {
confEnergies.push_back(atof(tok));
break;
}
}
} else if (strstr(buffer, "ELECTROSTATIC MOMENTS") != nullptr) {
ifs.getline(buffer, BUFF_SIZE); ifs.getline(buffer, BUFF_SIZE); ifs.getline(buffer, BUFF_SIZE); ifs.getline(buffer, BUFF_SIZE); ifs.getline(buffer, BUFF_SIZE); ifs.getline(buffer, BUFF_SIZE);
tokenize(vs, buffer);
if (vs.size() == 4) {
OBVectorData* dipoleMoment = new OBVectorData;
dipoleMoment->SetAttribute("Dipole Moment");
double x, y, z;
x = atof(vs[0].c_str());
y = atof(vs[1].c_str());
z = atof(vs[2].c_str());
dipoleMoment->SetData(x, y, z);
dipoleMoment->SetOrigin(fileformatInput);
mol.SetData(dipoleMoment);
}
} else if (strstr(buffer, "MOPAC CHARGES") != nullptr) {
hasPartialCharges = true;
ifs.getline(buffer, BUFF_SIZE); ifs.getline(buffer, BUFF_SIZE); ifs.getline(buffer, BUFF_SIZE);
tokenize(vs, buffer);
while (vs.size() == 4) {
atom = mol.GetAtom(atoi(vs[0].c_str()));
atom->SetPartialCharge(atof(vs[2].c_str()));
if (!ifs.getline(buffer, BUFF_SIZE))
break;
tokenize(vs, buffer);
}
} else if (strstr(buffer, "TOTAL MULLIKEN") != nullptr) {
hasPartialCharges = true;
ifs.getline(buffer, BUFF_SIZE); ifs.getline(buffer, BUFF_SIZE);
tokenize(vs, buffer);
while (vs.size() >= 4) {
int atomNb = atoi(vs[0].c_str());
if (!atomNb)
break;
atom = mol.GetAtom(atomNb);
atom->SetPartialCharge(atof(vs[3].c_str()));
if (!ifs.getline(buffer, BUFF_SIZE))
break;
tokenize(vs, buffer);
}
} else if (strstr(buffer, "NUMBER OF OCCUPIED ORBITALS") != nullptr) {
tokenize(vs, buffer);
if (vs.size() == 7) aHOMO = atoi(vs[6].c_str());
else if (vs.size() == 8) bHOMO = atoi(vs[7].c_str());
} else if (strstr(buffer, "TAKEN AS ROTATIONS AND TRANSLATIONS") != nullptr) {
tokenize(vs, buffer);
if (vs.size() < 4)
break;
lowFreqModesBegin = atoi(vs[1].c_str());
lowFreqModesEnd = atoi(vs[3].c_str());
} else if (strstr(buffer, "TOTAL ENERGY =") != nullptr) {
tokenize(vs, buffer);
if (vs.size() == 4)
mol.SetEnergy(atof(vs[3].c_str()));
} else if (strstr(buffer, "FREQUENCY:") != nullptr) {
tokenize(vs, buffer);
for (unsigned int i=1; i < vs.size(); ++i) {
if (vs[i] == "I") continue;
++numFreq;
if (numFreq < lowFreqModesBegin) frequencies.push_back(-atof(vs[i].c_str()));
if (numFreq > lowFreqModesEnd)
frequencies.push_back(atof(vs[i].c_str()));
}
ifs.getline(buffer, BUFF_SIZE); if (strstr(buffer, "SYMMETRY:") != nullptr) {
ifs.getline(buffer, BUFF_SIZE); }
ifs.getline(buffer, BUFF_SIZE); tokenize(vs, buffer);
for (unsigned int i=2; i < vs.size(); ++i) {
++numIntens;
if (numIntens < lowFreqModesBegin || numIntens > lowFreqModesEnd)
intensities.push_back(atof(vs[i].c_str()) * 42.255); }
ifs.getline(buffer, BUFF_SIZE); if (strstr(buffer, "RAMAN") != nullptr) {
tokenize(vs, buffer);
for (unsigned int i=2; i < vs.size(); ++i) {
if (numIntens < lowFreqModesBegin || numIntens > lowFreqModesEnd)
raman_intensities.push_back(atof(vs[i].c_str()));
}
ifs.getline(buffer, BUFF_SIZE); ifs.getline(buffer, BUFF_SIZE); }
unsigned int prevModeCount = displacements.size();
unsigned int newModes = frequencies.size() - displacements.size();
vector<vector3> displacement;
for (unsigned int i=0; i < newModes; ++i) {
displacements.push_back(displacement);
}
ifs.getline(buffer, BUFF_SIZE);
tokenize(vs, buffer);
int modeCount = vs.size() - 3;
double massNormalization;
vector<double> x, y, z;
while (modeCount >= 1) {
atom = mol.GetAtom(atoi(vs[0].c_str()));
massNormalization = 1 / sqrt( atom->GetAtomicMass() );
x.clear();
for (unsigned int i=3; i < vs.size(); ++i) {
x.push_back(massNormalization * atof(vs[i].c_str()));
}
y.clear();
ifs.getline(buffer, BUFF_SIZE);
tokenize(vs, buffer);
for (unsigned int i=1; i < vs.size(); ++i) {
y.push_back(massNormalization * atof(vs[i].c_str()));
}
z.clear();
ifs.getline(buffer, BUFF_SIZE);
tokenize(vs, buffer);
for (unsigned int i=1; i < vs.size(); ++i) {
z.push_back(massNormalization * atof(vs[i].c_str()));
}
if (displacements.size()) {
numDisp = prevModeCount;
for (unsigned int i=0; i < modeCount; ++i) {
if (i >= modeCount - newModes){
displacements[numDisp++].push_back(vector3(x[i], y[i], z[i]));
}
}
}
ifs.getline(buffer, BUFF_SIZE);
tokenize(vs, buffer);
modeCount = vs.size() - 3;
}
} else if (strstr(buffer, "EIGENVECTORS") != nullptr ||
strstr(buffer, "MOLECULAR ORBITALS") != nullptr) {
ifs.getline(buffer, BUFF_SIZE); ifs.getline(buffer, BUFF_SIZE); orbitals.clear();
symmetries.clear();
while (strstr(buffer, "END OF RHF CALCULATION") == nullptr &&
strstr(buffer, "-------") == nullptr) {
ifs.getline(buffer, BUFF_SIZE); ifs.getline(buffer, BUFF_SIZE); tokenize(vs, buffer);
for (unsigned int i=0; i < vs.size(); ++i)
orbitals.push_back(27.21 * atof(vs[i].c_str()));
ifs.getline(buffer, BUFF_SIZE); tokenize(vs, buffer);
for (unsigned int i=0; i < vs.size(); ++i)
symmetries.push_back(vs[i]);
while (ifs.getline(buffer, BUFF_SIZE)
&& strlen(buffer)
&& strstr(buffer, "END") == nullptr
&& strstr(buffer, "---") == nullptr) {
}
if (!ifs.good())
break;
}
} else if (strstr(buffer, "INPUT CARD> $")) {
string attr, value;
char* ptr;
for ( ; ; ) {
ptr = buffer + 14;
tokenize(vs, ptr);
if (vs.size() > 2) {
OBSetData* curset = (OBSetData*) gmsset->GetData(vs[0]);
if (!curset) {
curset = new OBSetData();
curset->SetAttribute(vs[0]);
curset->SetOrigin(fileformatInput);
gmsset->AddData(curset);
}
for (unsigned int i=1; i < vs.size() && vs[i].substr(0, 4) != "$END"; i++) {
string::size_type loc = vs[i].find("=", 0);
if (loc != string::npos) {
OBPairData *data = new OBPairData();
data->SetAttribute(vs[i].substr(0, loc));
data->SetValue(vs[i].substr(loc + 1));
data->SetOrigin(fileformatInput);
curset->AddData(data);
}
}
}
break;
}
}
}
if (mol.NumAtoms() == 0) { mol.EndModify();
return false;
}
if (orbitals.size() > 0) {
OBOrbitalData* od = new OBOrbitalData();
if (aHOMO == bHOMO) {
od->LoadClosedShellOrbitals(orbitals, symmetries, aHOMO);
}
od->SetOrigin(fileformatInput);
mol.SetData(od);
}
const char* keywordsEnable = pConv->IsOption("k", OBConversion::GENOPTIONS);
if (keywordsEnable) {
pmol->SetData(gmsset);
OBSetData* cset = (OBSetData*) gmsset->GetData("CONTRL");
OBSetData* bset = (OBSetData*) gmsset->GetData("BASIS");
string model = "b3lyp";
string basis;
string method;
if (cset) {
OBPairData* pd = nullptr;
pd = (OBPairData*) cset->GetData("SCFTYP");
if (pd) {
if(pd->GetValue() == "RHF")
model = "rhf";
}
pd = (OBPairData*) cset->GetData("DFTTYP");
if (pd) {
if(pd->GetValue() == "BLYP")
model = "b3lyp";
}
pd = (OBPairData*) cset->GetData("MPLEVL");
if (pd) {
if(pd->GetValue() == "2")
model = "mp2";
}
pd = (OBPairData*) cset->GetData("CCTYP");
if (pd) {
if (pd->GetValue() == "CCSD(T)")
model = "ccsd(t)";
}
pd = (OBPairData*) cset->GetData("RUNTYP");
if (pd) {
string value = pd->GetValue();
if (value == "GRADIENT"
|| value == "HESSIAN"
|| value == "RAMAN"
|| value == "OPTIMIZE"
|| value == "SADPOINT") {
method = pd->GetValue();
transform(method.begin(), method.end(), method.begin(), ::tolower);
}
}
}
if (bset) {
OBPairData* gbasis = (OBPairData*) bset->GetData("GBASIS");
OBPairData* ngauss = (OBPairData*) bset->GetData("NGAUSS");
if (gbasis) {
string value = gbasis->GetValue();
if (value == "am1")
model = "am1";
else if (value == "pm3")
model = "pm3";
else if (ngauss) {
if (value == "STO") {
basis.clear();
basis += "sto-";
basis += ngauss->GetValue();
basis += "g";
} else if (ngauss->GetValue() == "3"
|| ngauss->GetValue() == "6") {
basis.clear();
basis = ngauss->GetValue();
basis += "-";
basis += gbasis->GetValue().substr(1);
basis += "G(d)";
}
}
}
}
OBPairData* nd = nullptr;
if (model != "") {
nd = new OBPairData();
nd->SetAttribute("model");
nd->SetValue(model);
nd->SetOrigin(fileformatInput);
pmol->SetData(nd);
}
if (basis != "") {
nd = new OBPairData();
nd->SetAttribute("basis");
nd->SetValue(basis);
nd->SetOrigin(fileformatInput);
pmol->SetData(nd);
}
if (method != "") {
nd = new OBPairData();
nd->SetAttribute("method");
nd->SetValue(method);
nd->SetOrigin(fileformatInput);
pmol->SetData(nd);
}
}
mol.EndModify();
if (vconf.size() > 1)
vconf.pop_back();
mol.SetConformers(vconf);
mol.SetConformer(mol.NumConformers() - 1);
confData->SetDimension(confDimensions);
confData->SetEnergies(confEnergies);
confData->SetForces(confForces);
mol.SetData(confData);
if (!pConv->IsOption("b", OBConversion::INOPTIONS))
mol.ConnectTheDots();
if (!pConv->IsOption("s", OBConversion::INOPTIONS)
&& !pConv->IsOption("b", OBConversion::INOPTIONS)) {
mol.PerceiveBondOrders();
}
if (hasPartialCharges) {
mol.SetPartialChargesPerceived();
OBPairData* dp = new OBPairData;
dp->SetAttribute("PartialCharges");
dp->SetValue("Mulliken");
dp->SetOrigin(fileformatInput);
mol.SetData(dp);
}
if (frequencies.size() != 0) {
OBVibrationData* vd = new OBVibrationData;
vd->SetData(displacements, frequencies, intensities, raman_intensities);
vd->SetOrigin(fileformatInput);
mol.SetData(vd);
}
mol.AssignTotalChargeToAtoms(charge);
mol.SetTotalSpinMultiplicity(mult);
mol.SetTitle(title);
return(true);
}
bool GAMESSInputFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv) {
OBMol* pmol = pOb->CastAndClear<OBMol>();
if (pmol == nullptr)
return false;
istream& ifs = *pConv->GetInStream();
OBMol& mol = *pmol;
char buffer[BUFF_SIZE];
string str, str1;
double x, y, z;
OBAtom* atom;
vector<string> vs;
bool hasPartialCharges = false;
string efragName;
mol.BeginModify();
while (ifs.getline(buffer, BUFF_SIZE)) {
if (strstr(buffer, "$DATA") != nullptr) {
ifs.getline(buffer, BUFF_SIZE);
tokenize(vs, buffer);
mol.SetTitle(buffer);
ifs.getline(buffer, BUFF_SIZE);
ifs.getline(buffer, BUFF_SIZE);
while (strstr(buffer, "$END") == nullptr) {
tokenize(vs, buffer);
if (vs.size() == 5) {
atom = mol.NewAtom();
atom->SetAtomicNum(atoi(vs[1].c_str()));
x = atof((char*) vs[2].c_str());
y = atof((char*) vs[3].c_str());
z = atof((char*) vs[4].c_str());
atom->SetVector(x, y, z);
}
if (!ifs.getline(buffer, BUFF_SIZE))
break;
}
}
if (strstr(buffer, "$FMOXYZ") != nullptr) {
while (strstr(buffer, "$END") == nullptr) {
tokenize(vs, buffer);
if (vs.size() == 5) {
atom = mol.NewAtom();
atom->SetAtomicNum(atoi(vs[1].c_str()));
x = atof((char*) vs[2].c_str());
y = atof((char*) vs[3].c_str());
z = atof((char*) vs[4].c_str());
atom->SetVector(x, y, z);
}
if (!ifs.getline(buffer, BUFF_SIZE))
break;
}
}
if (strstr(buffer, "$EFRAG") != nullptr) {
while (strstr(buffer, "FRAGNAME") == nullptr) {
tokenize(vs, buffer, "=");
if (vs.size() > 1)
efragName = vs[1];
if (!ifs.getline(buffer, BUFF_SIZE))
break;
}
while (strstr(buffer," $END") == nullptr) {
tokenize(vs, buffer);
if (vs.size() == 4) {
atom = mol.NewAtom();
int atomicNum;
if (vs[0].substr(0, 1) == "Z"
|| vs[0].substr(0, 1) == "z") {
atomicNum = OBElements::GetAtomicNum(vs[0].substr(1, 1).c_str());
} else {
atomicNum = OBElements::GetAtomicNum(vs[0].substr(0, 1).c_str());
}
atom->SetAtomicNum(atomicNum);
x = atof((char*) vs[1].c_str());
y = atof((char*) vs[2].c_str());
z = atof((char*) vs[3].c_str());
atom->SetVector(x, y, z);
OBPairData* dp = new OBPairData;
dp->SetAttribute("EFRAG");
dp->SetValue(efragName);
dp->SetOrigin(fileformatInput);
atom->SetData(dp);
}
if (!ifs.getline(buffer, BUFF_SIZE))
break;
}
}
}
if (!pConv->IsOption("b",OBConversion::INOPTIONS))
mol.ConnectTheDots();
if (!pConv->IsOption("s",OBConversion::INOPTIONS)
&& !pConv->IsOption("b",OBConversion::INOPTIONS)) {
mol.PerceiveBondOrders();
}
mol.EndModify();
if (hasPartialCharges)
mol.SetPartialChargesPerceived();
return(true);
}
bool GAMESSInputFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv) {
OBMol* pmol = dynamic_cast<OBMol*>(pOb);
if (pmol == nullptr)
return false;
ostream& ofs = *pConv->GetOutStream();
OBMol& mol = *pmol;
char buffer[BUFF_SIZE];
const char* keywords = pConv->IsOption("k", OBConversion::OUTOPTIONS);
const char* keywordsEnable = pConv->IsOption("k", OBConversion::GENOPTIONS);
const char* keywordFile = pConv->IsOption("f", OBConversion::OUTOPTIONS);
string defaultKeywords = " $CONTRL COORD=CART UNITS=ANGS $END";
int a = 0;
string s = "";
bool wrapped = false;
vector<int> spacePositions;
std::vector<int>::reverse_iterator rit;
std::vector<OBGenericData*>::iterator i, j;
struct local {
static const bool cmpfn(const char& a, const char& b) {
return (a == ' ' && b == ' ');
}
};
if (keywords)
defaultKeywords = keywords;
if (keywordsEnable) {
OBSetData* gmsset = (OBSetData*) pmol->GetData("gamess");
if (gmsset) {
for (i=gmsset->GetBegin(); i != gmsset->GetEnd(); ++i) {
OBSetData* cset = (OBSetData*) (*i);
if (cset) {
wrapped = false;
a = 2 + cset->GetAttribute().length();
ofs << " $" << cset->GetAttribute();
for (j=cset->GetBegin(); j != cset->GetEnd(); ++j) {
OBPairData* pd = (OBPairData*) (*j);
if (pd) {
if (a + 2 + pd->GetAttribute().length() + pd->GetValue().length() > 72) {
s = pd->GetAttribute();
s += "=";
s += pd->GetValue();
s.erase(unique(s.begin(), s.end(), local::cmpfn), s.end());
while (s.length() > 0) {
if (s.find(' ') != string::npos) {
spacePositions.clear();
for (unsigned int n=0; n < s.length(); ++n) {
if (s.at(n) == ' ')
spacePositions.push_back(n);
}
wrapped = false;
if (a + 1 + s.length() <= 72) {
a += 1 + s.length();
ofs << " " << s;
break;
}
for (rit=spacePositions.rbegin(); rit != spacePositions.rend(); ++rit) {
if (a + 1 + (*rit) <= 72) {
ofs << " " << s.substr(0, *rit)
<< endl << " ";
a = 3;
s = s.substr(*rit);
wrapped = true;
break;
}
}
if (!wrapped) {
a = 4 + spacePositions.at(0);
if (a > 72) {
ofs << endl
<< "! Unable to fit " << pd->GetAttribute()
<< " on the line!" << endl;
break;
}
a = 3;
ofs << endl << " ";
}
} else {
a = 4 + s.length();
if (a > 72) {
ofs << endl
<< "! Unable to fit " << pd->GetAttribute()
<< " on the line!" << endl;
break;
}
if (wrapped) {
ofs << s;
} else {
ofs << endl << " " << s;
}
s = "";
}
}
} else {
a += 2 + pd->GetAttribute().length() + pd->GetValue().length();
ofs << " " << pd->GetAttribute() << "=" << pd->GetValue();
}
}
}
ofs << " $END" << endl;
}
}
} else {
ofs << "! Unable to translate keywords!" << endl;
ofs << "! Defining default control keywords." << endl;
ofs << defaultKeywords << endl;
}
} else if (keywordFile) {
ifstream kfstream(keywordFile);
string keyBuffer;
if (kfstream) {
while (getline(kfstream, keyBuffer))
ofs << keyBuffer << endl;
}
} else {
ofs << defaultKeywords << endl;
}
ofs << endl << " $DATA" << endl;
ofs << mol.GetTitle() << endl;
if (!mol.HasData(OBGenericDataType::SymmetryData))
ofs << "C1" << endl;
else {
ofs << "Put symmetry info here" << endl << endl;
}
FOR_ATOMS_OF_MOL(atom, mol) {
snprintf(buffer, BUFF_SIZE, "%-3s %4d.0 %14.10f %14.10f %14.10f ",
OBElements::GetSymbol(atom->GetAtomicNum()),
atom->GetAtomicNum(),
atom->GetX(),
atom->GetY(),
atom->GetZ());
ofs << buffer << endl;
}
ofs << " $END" << endl << endl << endl;
return(true);
}
}