void OBPhModel::ParseLine(const char *buffer) { vector<string> vs; OBSmartsPattern *sp; if (buffer[0] == '#') return; if (EQn(buffer,"TRANSFORM",7)) { tokenize(vs,buffer); if (vs.size() < 5) { obErrorLog.ThrowError(__FUNCTION__, " Could not parse line in phmodel table from phmodel.txt", obInfo); return; } OBChemTsfm *tsfm = new OBChemTsfm; if (!tsfm->Init(vs[1],vs[3])) { delete tsfm; tsfm = NULL; obErrorLog.ThrowError(__FUNCTION__, " Could not parse line in phmodel table from phmodel.txt", obInfo); return; } _vtsfm.push_back(tsfm); _vpKa.push_back(atof(vs[4].c_str())); } else if (EQn(buffer,"SEEDCHARGE",10)) { tokenize(vs,buffer); if (vs.size() < 2) { obErrorLog.ThrowError(__FUNCTION__, " Could not parse line in phmodel table from phmodel.txt", obInfo); return; } sp = new OBSmartsPattern; if (!sp->Init(vs[1]) || (vs.size()-2) != sp->NumAtoms()) { delete sp; sp = NULL; obErrorLog.ThrowError(__FUNCTION__, " Could not parse line in phmodel table from phmodel.txt", obInfo); return; } vector<double> vf; vector<string>::iterator i; for (i = vs.begin()+2;i != vs.end();++i) vf.push_back(atof((char*)i->c_str())); _vschrg.push_back(pair<OBSmartsPattern*,vector<double> > (sp,vf)); } }
void OpTransform::ParseLine(const char *buffer) { vector<string> vs; if (buffer[0] == '#') return; if (EQn(buffer,"TRANSFORM",7)) { //Split into TRANSFORM reactantSMARTS ProductSMARTS tokenize(vs, buffer, " >\t\n"); OBChemTsfm tr; if (vs.empty() || vs.size() < 3 || vs[1].empty() || vs[2].empty()) { string mes("Could not parse line:\n"); obErrorLog.ThrowError(__FUNCTION__, mes + buffer, obWarning); } else { if(!tr.Init(vs[1],vs[2])) { string mes("Could not make valid transform from the line:\n"); obErrorLog.ThrowError(__FUNCTION__, mes + buffer, obWarning); } else _transforms.push_back(tr); } } }
bool BoxFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv) { OBMol* pmol = pOb->CastAndClear<OBMol>(); if(pmol==NULL) return false; //Define some references so we can use the old parameter names istream &ifs = *pConv->GetInStream(); OBMol &mol = *pmol; const char* title = pConv->GetTitle(); char buffer[BUFF_SIZE]; vector<string> vs; vector<string>::iterator i; OBAtom atom; mol.BeginModify(); while (ifs.getline(buffer,BUFF_SIZE) && !EQn(buffer,"END",3)) { if (EQn(buffer,"ATOM",4)) { string sbuf = &buffer[6]; /* X, Y, Z */ string x = sbuf.substr(24,8); string y = sbuf.substr(32,8); string z = sbuf.substr(40,8); vector3 v(atof(x.c_str()),atof(y.c_str()),atof(z.c_str())); atom.SetVector(v); if (!mol.AddAtom(atom)) return(false); } if (EQn(buffer,"CONECT",6)) { tokenize(vs,buffer); if (!vs.empty() && vs.size() > 2) for (i = vs.begin(),i+=2; i != vs.end(); i++) mol.AddBond(atoi(vs[1].c_str()),atoi((*i).c_str()),1); } } mol.EndModify(); mol.SetTitle(title); return(true); }
bool OBGroupContrib::ParseFile(const char *filename) { OBSmartsPattern *sp; // open data file ifstream ifs; if (OpenDatafile(ifs, filename).length() == 0) { obErrorLog.ThrowError(__FUNCTION__, " Could not find contribution data file.", obError); return false; } vector<string> vs; bool heavy = false; char buffer[80]; while (ifs.getline(buffer, 80)) { if (EQn(buffer, "#", 1)) continue; if (EQn(buffer, ";heavy", 6)) heavy = true; else if (EQn(buffer, ";", 1)) continue; tokenize(vs, buffer); if (vs.size() < 2) continue; sp = new OBSmartsPattern; if (sp->Init(vs[0])) { if (heavy) _contribsHeavy.push_back(pair<OBSmartsPattern*, double> (sp, atof(vs[1].c_str()))); else _contribsHydrogen.push_back(pair<OBSmartsPattern*, double> (sp, atof(vs[1].c_str()))); } else { delete sp; sp = NULL; obErrorLog.ThrowError(__FUNCTION__, " Could not parse SMARTS from contribution data file", obInfo); return false; } } return true; }
bool MOL2Format::ReadMolecule(OBBase* pOb, OBConversion* pConv) { OBMol* pmol = pOb->CastAndClear<OBMol>(); if(pmol==NULL) return false; //Define some references so we can use the old parameter names istream &ifs = *pConv->GetInStream(); OBMol &mol = *pmol; //Old code follows... bool foundAtomLine = false; char buffer[BUFF_SIZE]; char *comment = NULL; string str,str1; vector<string> vstr; int len; mol.BeginModify(); for (;;) { if (!ifs.getline(buffer,BUFF_SIZE)) return(false); if (EQn(buffer,"@<TRIPOS>MOLECULE",17)) break; } int lcount; int natoms,nbonds; for (lcount=0;;lcount++) { if (!ifs.getline(buffer,BUFF_SIZE)) return(false); if (EQn(buffer,"@<TRIPOS>ATOM",13)) { foundAtomLine = true; break; } if (lcount == 0) { tokenize(vstr,buffer); if (!vstr.empty()) mol.SetTitle(buffer); } else if (lcount == 1) sscanf(buffer,"%d%d",&natoms,&nbonds); else if (lcount == 4) //energy { tokenize(vstr,buffer); if (!vstr.empty() && vstr.size() == 3) if (vstr[0] == "Energy") mol.SetEnergy(atof(vstr[2].c_str())); } else if (lcount == 5) //comment { if ( buffer[0] ) { len = (int) strlen(buffer)+1; // TODO allow better multi-line comments // which don't allow ill-formed data to consume memory // Thanks to Andrew Dalke for the pointer if (comment != NULL) delete [] comment; comment = new char [len]; memcpy(comment,buffer,len); } } } if (!foundAtomLine) { mol.EndModify(); mol.Clear(); obErrorLog.ThrowError(__FUNCTION__, "Unable to read Mol2 format file. No atoms found.", obWarning); return(false); } mol.ReserveAtoms(natoms); int i; vector3 v; OBAtom atom; bool hasPartialCharges=false; double x,y,z,pcharge; char temp_type[BUFF_SIZE], resname[BUFF_SIZE], atmid[BUFF_SIZE]; int elemno, resnum = -1; ttab.SetFromType("SYB"); for (i = 0;i < natoms;i++) { if (!ifs.getline(buffer,BUFF_SIZE)) return(false); sscanf(buffer," %*s %1024s %lf %lf %lf %1024s %d %1024s %lf", atmid, &x,&y,&z, temp_type, &resnum, resname, &pcharge); atom.SetVector(x, y, z); // Handle "CL" and "BR" and other mis-typed atoms str = temp_type; if (strncmp(temp_type, "CL", 2) == 0) { str = "Cl"; } else if (strncmp(temp_type,"BR",2) == 0) { str = "Br"; } else if (strncmp(temp_type,"S.o2", 4) == 02) { str = "S.O2"; } else if (strncmp(temp_type,"S.o", 3) == 0) { str = "S.O"; } else if (strncmp(temp_type,"SI", 2) == 0) { str = "Si"; // The following cases are entries which are not in openbabel/data/types.txt // and should probably be added there } else if (strncmp(temp_type,"S.1", 3) == 0) { str = "S.2"; // no idea what the best type might be here } else if (strncmp(temp_type,"P.", 2) == 0) { str = "P.3"; } else if (strncasecmp(temp_type,"Ti.", 3) == 0) { // e.g. Ti.th str = "Ti"; } else if (strncasecmp(temp_type,"Ru.", 3) == 0) { // e.g. Ru.oh str = "Ru"; } ttab.SetToType("ATN"); ttab.Translate(str1,str); elemno = atoi(str1.c_str()); ttab.SetToType("IDX"); // We might have missed some SI or FE type things above, so here's // another check if( !elemno && isupper(temp_type[1]) ) { temp_type[1] = (char)tolower(temp_type[1]); str = temp_type; ttab.Translate(str1,str); elemno = atoi(str1.c_str()); } // One last check if there isn't a period in the type, // it's a malformed atom type, but it may be the element symbol // GaussView does this (PR#1739905) if ( !elemno ) { obErrorLog.ThrowError(__FUNCTION__, "This Mol2 file is non-standard. Cannot interpret atom types correctly, instead attempting to interpret as elements instead.", obWarning); string::size_type dotPos = str.find('.'); if (dotPos == string::npos) { elemno = etab.GetAtomicNum(str.c_str()); } } atom.SetAtomicNum(elemno); ttab.SetToType("INT"); ttab.Translate(str1,str); atom.SetType(str1); atom.SetPartialCharge(pcharge); if (!mol.AddAtom(atom)) return(false); if (!IsNearZero(pcharge)) hasPartialCharges = true; // Add residue information if it exists if (resnum != -1 && resnum != 0 && strlen(resname) != 0 && strncmp(resname,"<1>", 3) != 0) { OBResidue *res = (mol.NumResidues() > 0) ? mol.GetResidue(mol.NumResidues()-1) : NULL; if (res == NULL || res->GetName() != resname || static_cast<int>(res->GetNum()) != resnum) { vector<OBResidue*>::iterator ri; for (res = mol.BeginResidue(ri) ; res ; res = mol.NextResidue(ri)) if (res->GetName() == resname && static_cast<int>(res->GetNum()) == resnum) break; if (res == NULL) { res = mol.NewResidue(); res->SetName(resname); res->SetNum(resnum); } } OBAtom *atomPtr = mol.GetAtom(mol.NumAtoms()); res->AddAtom(atomPtr); res->SetAtomID(atomPtr, atmid); } // end adding residue info } for (;;) { if (!ifs.getline(buffer,BUFF_SIZE)) return(false); str = buffer; if (!strncmp(buffer,"@<TRIPOS>BOND",13)) break; } int start,end,order; for (i = 0; i < nbonds; i++) { if (!ifs.getline(buffer,BUFF_SIZE)) return(false); sscanf(buffer,"%*d %d %d %1024s",&start,&end,temp_type); str = temp_type; order = 1; if (str == "ar" || str == "AR" || str == "Ar") order = 5; else if (str == "AM" || str == "am" || str == "Am") order = 1; else order = atoi(str.c_str()); mol.AddBond(start,end,order); } // update neighbour bonds information for each atom. vector<OBAtom*>::iterator apos; vector<OBBond*>::iterator bpos; OBAtom* patom; OBBond* pbond; for (patom = mol.BeginAtom(apos); patom; patom = mol.NextAtom(apos)) { patom->ClearBond(); for (pbond = mol.BeginBond(bpos); pbond; pbond = mol.NextBond(bpos)) { if (patom == pbond->GetBeginAtom() || patom == pbond->GetEndAtom()) { patom->AddBond(pbond); } } } // Suggestion by Liu Zhiguo 2008-01-26 // Mol2 files define atom types -- there is no need to re-perceive mol.SetAtomTypesPerceived(); mol.EndModify(); //must add generic data after end modify - otherwise it will be blown away if (comment) { OBCommentData *cd = new OBCommentData; cd->SetData(comment); cd->SetOrigin(fileformatInput); mol.SetData(cd); delete [] comment; comment = NULL; } if (hasPartialCharges) mol.SetPartialChargesPerceived(); // continue untill EOF or untill next molecule record streampos pos; for(;;) { pos = ifs.tellg(); if (!ifs.getline(buffer,BUFF_SIZE)) break; if (EQn(buffer,"@<TRIPOS>MOLECULE",17)) break; } ifs.seekg(pos); // go back to the end of the molecule return(true); }
//------------------------------------------------------------------------------ bool OBOpenDXCubeFormat::ReadMolecule( OBBase* pOb, OBConversion* pConv ) { OBMol* pmol = pOb->CastAndClear<OBMol>(); if(pmol == 0) return false; istream& ifs = *pConv->GetInStream(); const char* title = pConv->GetTitle(); char buffer[BUFF_SIZE]; stringstream errorMsg; if (!ifs) return false; // We are attempting to read past the end of the file pmol->SetTitle(title); while (ifs.good() && ifs.getline(buffer,BUFF_SIZE)) { if (buffer[0] == '#') continue; // comment line if (EQn(buffer, "object", 6)) break; } if (!ifs) return false; // ran out of lines vector<string> vs; tokenize(vs, buffer); // Number of grid points (voxels) vector<int> voxels(3); if (!EQn(buffer, "object", 6) || vs.size() != 8) return false; else { voxels[0] = atoi(vs[5].c_str()); voxels[1] = atoi(vs[6].c_str()); voxels[2] = atoi(vs[7].c_str()); } double x, y, z; if (!ifs.getline(buffer, BUFF_SIZE) || !EQn(buffer, "origin", 6)) return false; else { tokenize(vs, buffer); if (vs.size() != 4) return false; x = atof(vs[1].c_str()); y = atof(vs[2].c_str()); z = atof(vs[3].c_str()); } vector3 origin(x, y, z); // now three lines with the x, y, and z axes vector<vector3> axes; for (unsigned int i = 0; i < 3; ++i) { if (!ifs.getline(buffer, BUFF_SIZE) || !EQn(buffer, "delta", 5)) return false; else { tokenize(vs, buffer); if (vs.size() != 4) return false; x = atof(vs[1].c_str()); y = atof(vs[2].c_str()); z = atof(vs[3].c_str()); axes.push_back(vector3(x, y, z)); } } // Two remaining header lines before the data: /* object 2 class gridconnections counts nx ny nz object 3 class array type double rank 0 times n data follows */ if (!ifs.getline(buffer, BUFF_SIZE) || !EQn(buffer, "object", 6)) return false; if (!ifs.getline(buffer, BUFF_SIZE) || !EQn(buffer, "object", 6)) return false; pmol->BeginModify(); pmol->SetDimension(3); OBGridData *gd = new OBGridData; gd->SetAttribute("OpenDX"); // get all values as one vector<double> char *endptr; vector<double> values; int n = voxels[0]*voxels[1]*voxels[2]; int line = 0; values.reserve(n); while (ifs.getline(buffer, BUFF_SIZE)) { ++line; if (EQn(buffer, "attribute", 9)) break; // we're finished with reading data -- although we should probably have a voxel check in here too tokenize(vs, buffer); if (vs.size() == 0) { errorMsg << "Problem reading the OpenDX grid file: cannot" << " read line " << line << ", there does not appear to be any data in it.\n" << buffer << "\n"; obErrorLog.ThrowError(__FUNCTION__, errorMsg.str(), obError); return false; } for (unsigned int l = 0; l < vs.size(); ++l) { values.push_back(strtod(static_cast<const char*>(vs[l].c_str()), &endptr)); } } gd->SetNumberOfPoints(voxels[0], voxels[1], voxels[2]); gd->SetLimits(origin, axes[0], axes[1], axes[2]); gd->SetUnit(OBGridData::ANGSTROM); gd->SetOrigin(fileformatInput); // i.e., is this data from a file or determined by Open Babel gd->SetValues(values); // set the values pmol->SetData(gd); // store the grids in the OBMol pmol->EndModify(); // Trailing control lines /* attribute "dep" string "positions" object "regular positions regular connections" class field component "positions" value 1 component "connections" value 2 component "data" value 3 */ if (!ifs.getline(buffer, BUFF_SIZE) || !EQn(buffer, "object", 6)) return false; if (!ifs.getline(buffer, BUFF_SIZE) || !EQn(buffer, "component", 9)) return false; if (!ifs.getline(buffer, BUFF_SIZE) || !EQn(buffer, "component", 9)) return false; if (!ifs.getline(buffer, BUFF_SIZE) || !EQn(buffer, "component", 9)) return false; // clean out any remaining blank lines std::streampos ipos; do { ipos = ifs.tellg(); ifs.getline(buffer,BUFF_SIZE); } while(strlen(buffer) == 0 && !ifs.eof() ); ifs.seekg(ipos); return true; }
bool MSIFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv) { OBMol* pmol = pOb->CastAndClear<OBMol>(); if(pmol==NULL) return false; //Define some references so we can use the old parameter names istream &ifs = *pConv->GetInStream(); OBMol &mol = *pmol; const char* title = pConv->GetTitle(); char buffer[BUFF_SIZE]; stringstream errorMsg; if (!ifs) return false; // we're attempting to read past the end of the file if (!ifs.getline(buffer,BUFF_SIZE)) { obErrorLog.ThrowError(__FUNCTION__, "Problems reading an MSI file: Cannot read the first line.", obWarning); return(false); } if (!EQn(buffer, "# MSI CERIUS2 DataModel File", 28)) { obErrorLog.ThrowError(__FUNCTION__, "Problems reading an MSI file: The first line must contain the MSI header.", obWarning); return(false); } // "records" start with // (1 Model // .... // and end with // .... // ) unsigned int openParens = 0; // the count of "open parentheses" tags unsigned int startBondAtom, endBondAtom, bondOrder; bool atomRecord = false; bool bondRecord = false; OBAtom *atom; // OBBond *bond; vector<string> vs; const SpaceGroup *sg; bool setSpaceGroup = false; double x,y,z; vector3 translationVectors[3]; int numTranslationVectors = 0; mol.BeginModify(); while (ifs.getline(buffer,BUFF_SIZE)) { // model record if (strstr(buffer, "Model") != NULL) { openParens++; continue; } // atom record if (!bondRecord && strstr(buffer, "Atom") != NULL) { atomRecord = true; openParens++; continue; } if (strstr(buffer, "Bond") != NULL) { bondRecord = true; startBondAtom = endBondAtom = 0; bondOrder = 1; openParens++; continue; } /* (A I PeriodicType 100) (A D A3 (6.2380000000000004 0 0)) (A D B3 (0 6.9909999999999997 0)) (A D C3 (0 0 6.9960000000000004)) (A C SpaceGroup "63 5") */ if (strstr(buffer, "PeriodicType") != NULL) { ifs.getline(buffer,BUFF_SIZE); // next line should be translation vector tokenize(vs,buffer); while (vs.size() == 6) { x = atof((char*)vs[3].erase(0,1).c_str()); y = atof((char*)vs[4].c_str()); z = atof((char*)vs[5].c_str()); translationVectors[numTranslationVectors++].Set(x, y, z); if (!ifs.getline(buffer,BUFF_SIZE)) break; tokenize(vs,buffer); } } if (strstr(buffer, "SpaceGroup") != NULL) { tokenize(vs, buffer); if (vs.size() != 5) continue; // invalid space group setSpaceGroup = true; sg = SpaceGroup::GetSpaceGroup(vs[4]); // remove the initial " character } // atom information if (atomRecord) { if (strstr(buffer, "ACL") != NULL) { tokenize(vs, buffer); // size should be 5 -- need a test here if (vs.size() != 5) return false; // timvdm 18/06/2008 vs[3].erase(0,1); // "6 => remove the first " character int atomicNum = atoi(vs[3].c_str()); if (atomicNum == 0) atomicNum = 1; // hydrogen ? if (atomicNum <= 0 || atomicNum > etab.GetNumberOfElements()) continue; // valid element, so create the atom atom = mol.NewAtom(); atom->SetAtomicNum(atomicNum); continue; } else if (strstr(buffer, "XYZ") != NULL) { tokenize(vs, buffer); // size should be 6 -- need a test here if (vs.size() != 6) return false; // timvdm 18/06/2008 vs[3].erase(0,1); // remove ( character vs[5].erase(vs[5].length()-2, 2); // remove trailing )) characters atom->SetVector(atof(vs[3].c_str()), atof(vs[4].c_str()), atof(vs[5].c_str())); continue; } } // end of atom records // bond information if (bondRecord) { if (strstr(buffer, "Atom1") != NULL) { tokenize(vs, buffer); if (vs.size() < 4) return false; // timvdm 18/06/2008 vs[3].erase(vs[3].length()-1,1); startBondAtom = atoi(vs[3].c_str()); continue; } else if (strstr(buffer, "Atom2") != NULL) { tokenize(vs, buffer); if (vs.size() < 4) return false; // timvdm 18/06/2008 vs[3].erase(vs[3].length()-1,1); endBondAtom = atoi(vs[3].c_str()); continue; } else if (strstr(buffer, "Type") != NULL) { tokenize(vs, buffer); if (vs.size() < 4) return false; // timvdm 18/06/2008 vs[3].erase(vs[3].length()-1,1); bondOrder = atoi(vs[3].c_str()); if (bondOrder == 4) // triple bond? bondOrder = 3; else if (bondOrder == 8) // aromatic? bondOrder = 5; else if (bondOrder != 2) // 1 OK, 2 OK, others unknown bondOrder = 1; continue; } } // ending a "tag" -- a lone ")" on a line if (strstr(buffer,")") != NULL && strstr(buffer, "(") == NULL) { openParens--; if (atomRecord) { atomRecord = false; } if (bondRecord) { // Bond records appear to be questionable mol.AddBond(startBondAtom - 1, endBondAtom - 1, bondOrder); bondRecord = false; } if (openParens == 0) { ifs.getline(buffer, BUFF_SIZE); break; // closed this molecule } } } mol.EndModify(); // clean out any remaining blank lines while(ifs.peek() != EOF && ifs.good() && (ifs.peek() == '\n' || ifs.peek() == '\r')) ifs.getline(buffer,BUFF_SIZE); /* if (!pConv->IsOption("b",OBConversion::INOPTIONS)) mol.ConnectTheDots(); if (!pConv->IsOption("s",OBConversion::INOPTIONS) && !pConv->IsOption("b",OBConversion::INOPTIONS)) mol.PerceiveBondOrders(); */ if (numTranslationVectors > 0) { OBUnitCell* uc = new OBUnitCell; uc->SetData(translationVectors[0], translationVectors[1], translationVectors[2]); uc->SetOrigin(fileformatInput); if (setSpaceGroup) { uc->SetSpaceGroup(sg); } mol.SetData(uc); } return(true); }
bool BGFFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv) { OBMol* pmol = pOb->CastAndClear<OBMol>(); if(pmol==NULL) return false; //Define some references so we can use the old parameter names istream &ifs = *pConv->GetInStream(); OBMol &mol = *pmol; mol.SetTitle( pConv->GetTitle()); //default title is the filename mol.BeginModify(); char buffer[BUFF_SIZE]; char tmp[16],tmptyp[16]; vector<string> vs; while (ifs.getline(buffer,BUFF_SIZE)) { if (EQn(buffer,"CRYSTX",6)) { // Parse unit cell tokenize(vs,buffer," \n\t,"); if (vs.size() != 7) continue; // something strange double A, B, C, Alpha, Beta, Gamma; A = atof(vs[1].c_str()); B = atof(vs[2].c_str()); C = atof(vs[3].c_str()); Alpha = atof(vs[4].c_str()); Beta = atof(vs[5].c_str()); Gamma = atof(vs[6].c_str()); OBUnitCell *uc = new OBUnitCell; uc->SetOrigin(fileformatInput); uc->SetData(A, B, C, Alpha, Beta, Gamma); mol.SetData(uc); } else if (EQn(buffer,"FORMAT",6)) break; } ttab.SetFromType("DRE"); ttab.SetToType("INT"); OBAtom *atom; double x,y,z,chrg; for (;;) { if (!ifs.getline(buffer,BUFF_SIZE)) break; if (EQn(buffer,"FORMAT",6)) break; sscanf(buffer,"%*s %*s %*s %*s %*s %*s %lf %lf %lf %15s %*s %*s %lf", &x,&y,&z, tmptyp, &chrg); atom = mol.NewAtom(); ttab.Translate(tmp,tmptyp); atom->SetType(tmp); CleanAtomType(tmptyp); atom->SetAtomicNum(etab.GetAtomicNum(tmptyp)); atom->SetVector(x,y,z); } unsigned int i; vector<int> vtmp; vector<vector<int> > vcon; vector<vector<int> > vord; for (i = 0; i < mol.NumAtoms();i++) { vcon.push_back(vtmp); vord.push_back(vtmp); } unsigned int bgn; for (;;) { if (!ifs.getline(buffer,BUFF_SIZE) || EQn(buffer,"END",3)) break; tokenize(vs,buffer); if (vs.empty() || vs.size() < 3 || vs.size() > 10) continue; if (EQn(buffer,"CONECT",6)) { bgn = atoi((char*)vs[1].c_str()) - 1; if (bgn < 1 || bgn > mol.NumAtoms()) continue; for (i = 2;i < vs.size();i++) { vcon[bgn].push_back(atoi((char*)vs[i].c_str())); vord[bgn].push_back(1); } } else if (EQn(buffer,"ORDER",5)) { bgn = atoi((char*)vs[1].c_str()) - 1; if (bgn < 1 || bgn > mol.NumAtoms()) continue; if (vs.size() > vord[bgn].size()+2) continue; for (i = 2;i < vs.size();i++) vord[bgn][i-2] = atoi((char*)vs[i].c_str()); } } unsigned int j; for (i = 1;i <= mol.NumAtoms();i++) if (!vcon[i - 1].empty()) for (j = 0;j < vcon[i - 1].size();j++) { mol.AddBond(i,vcon[i - 1][j],vord[i - 1][j]); } //load up the next line after the END marker ifs.getline(buffer,BUFF_SIZE); mol.EndModify(); return(true); }
bool GAMESSUKInputFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv) { /* * Stuff to think about: * - At outset check whether we are in zmatrix, cartesian or nw-chem format * (we currently only suppot homogeneous formats - not mixed). * * For each line need to check: * - Is this a comment (?,#) * - Are the tokens separated by commas, if so use tokenize to split at commas * - Is there an 'end' token on the line * * For each line we want to check that we haven't hit a change from c to zm or vv * */ OBMol* pmol = dynamic_cast<OBMol*>(pOb); if (pmol==NULL) return false; //Define some references so we can use the old parameter names istream& ifs = *pConv->GetInStream(); OBMol &mol = *pmol; // Get a default title as the filename const char* title = pConv->GetTitle(); mol.BeginModify(); mol.SetTitle(title); mol.EndModify(); vector<string> geomList, tokens; // list of lines and list of tokens on a line string line; // For convenience so we can refer to lines from the iterator as 'line' ReadMode_t ReadMode=SKIP; double factor=BOHR_TO_ANGSTROM; // Read File and copy geometry specification into geomList while (ifs.good() && ifs.getline(buffer, BUFF_SIZE)) { // Skip commnents if (EQn(buffer, "#", 1) || EQn(buffer, "?", 1)) continue; // Copy line to a C++ string and convert to lower case // & remove leading and trailing spaces line = buffer; // transform(method.begin(), method.end(), method.begin(), ::tolower); ToLower(line); Trim(line); // Start of coordinate specifiation if (line.compare(0, 4, "zmat")==0) { ReadMode=ZMATRIX; geomList.push_back(line); continue; } else if (line.compare(0, 4, "geom")==0) { ReadMode=CARTESIAN; geomList.push_back(line); continue; } // Reading the coordinate specification into the list if (ReadMode==ZMATRIX || ReadMode==CARTESIAN) { // Variables specification - process directly from filestream // and then remove from the geometry specification if (line.compare(0, 4, "vari")==0 || line.compare(0, 4, "const")==0) { // Check for commas & split with that as the separator if necessary if (line.find(',')!=string::npos) { tokenize(tokens, line, ","); } else { tokenize(tokens, line, " \t\n"); } // See if we need to rescale if (IsUnits(tokens[1])) factor=Rescale(tokens[1]); if (! ReadVariables(ifs, factor, "end")) return false; ReadMode=SKIP; geomList.push_back("end\n"); continue; } if (line.compare(0, 3, "end")==0) ReadMode=SKIP; geomList.push_back(line); } }// End while reading loop // Now go and process the coordinate specification if we got any bool ok = ReadGeometry(mol, geomList); if (mol.NumAtoms() == 0) { // e.g., if we're at the end of a file PR#1737209 mol.EndModify(); return false; } else { return ok; } } // End ReadMolecule
bool GAMESSUKFormat::ReadVariables(istream &ifs, double factor, string stopstr) { /* * This takes an input stream that is positioned where the list of variables * starts and the reads the variables into the supplied map * * This is different to ReadGeometry (which takes a vector of strings as input) because * currently the variables always need to be read after the geometry, so we need to save the * geometry and then read the variables. However this means that we can parse the variables * directly into a map and don't need to keep a copy of the specifcation as strings. * * stopstr is a string that defines when we stop reading */ string line; vector<string> tokens; // Now read in all the varibles while (ifs.good() && ifs.getline(buffer, BUFF_SIZE)) { // Skip commnents if (EQn(buffer, "#", 1) || EQn(buffer, "?", 1)) continue; // Copy line to a C++ string and convert to lower case // & remove leading and trailing spaces line = buffer; // transform(method.begin(), method.end(), method.begin(), ::tolower); ToLower(line); Trim(line); // Check for end of variables if (line.length()==0 and stopstr.length()==0) break; if (stopstr.length()>0 && line.compare(0, stopstr.length(), stopstr)==0) break; // Check for commas & split with that as the separator if necessary if (line.find(',')!=string::npos) { tokenize(tokens, line, ","); } else { tokenize(tokens, line, " \t\n"); } char *endptr; double var = strtod((char*)tokens[1].c_str(), &endptr); if (endptr == (char*)tokens[1].c_str()) { errorMsg << "Problems reading a GAMESS-UK file: " << "Could not read variable line: " << line; obErrorLog.ThrowError(__FUNCTION__, errorMsg.str() , obWarning); return false; } // Add to list of variables variables[tokens[0]]=var*factor; } /* cerr << "Got list of variables: " << endl; for (map<string,double>::iterator i=variables.begin(); i != variables.end(); i++) { cerr << "Name: " << i->first << " Value: " << i->second << endl; } */ return true; }