bool ReadAlchemy(istream &ifs,OBMol &mol, const char *title) { int i; int natoms,nbonds; char buffer[BUFF_SIZE]; ifs.getline(buffer,BUFF_SIZE); sscanf(buffer,"%d %*s %d", &natoms, &nbonds); if (!natoms) return(false); mol.ReserveAtoms(natoms); ttab.SetFromType("ALC"); string str; double x,y,z; OBAtom *atom; vector<string> vs; for (i = 1; i <= natoms; i ++) { if (!ifs.getline(buffer,BUFF_SIZE)) return(false); tokenize(vs,buffer); if (vs.size() != 6) return(false); atom = mol.NewAtom(); 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); //set coordinates //set atomic number ttab.SetToType("ATN"); ttab.Translate(str,vs[1]); atom->SetAtomicNum(atoi(str.c_str())); //set type ttab.SetToType("INT"); ttab.Translate(str,vs[1]); atom->SetType(str); } char bobuf[100]; string bostr; int bgn,end,order; for (i = 0; i < nbonds; i++) { if (!ifs.getline(buffer,BUFF_SIZE)) return(false); sscanf(buffer,"%*d%d%d%s",&bgn,&end,bobuf); bostr = bobuf; order = 1; if (bostr == "DOUBLE") order = 2; else if (bostr == "TRIPLE") order = 3; else if (bostr == "AROMATIC") order = 5; mol.AddBond(bgn,end,order); } mol.SetTitle(title); return(true); }
void OBAtomTyper::AssignTypes(OBMol &mol) { if (!_init) Init(); obErrorLog.ThrowError(__FUNCTION__, "Ran OpenBabel::AssignTypes", obAuditMsg); mol.SetAtomTypesPerceived(); vector<vector<int> >::iterator j; vector<pair<OBSmartsPattern*,string> >::iterator i; for (i = _vexttyp.begin();i != _vexttyp.end();++i) if (i->first->Match(mol)) { _mlist = i->first->GetMapList(); for (j = _mlist.begin();j != _mlist.end();++j) mol.GetAtom((*j)[0])->SetType(i->second); } // Special cases vector<OBAtom*>::iterator a; OBAtom* atom; for (atom = mol.BeginAtom(a); atom; atom = mol.NextAtom(a)) { // guanidinium. Fixes PR#1800964 if (strncasecmp(atom->GetType(),"C2", 2) == 0) { int guanidineN = 0; OBAtom *nbr; vector<OBBond*>::iterator k; for (nbr = atom->BeginNbrAtom(k);nbr;nbr = atom->NextNbrAtom(k)) { if (strncasecmp(nbr->GetType(),"Npl", 3) == 0 || strncasecmp(nbr->GetType(),"N2", 2) == 0 || strncasecmp(nbr->GetType(),"Ng+", 3) == 0) ++guanidineN; } if (guanidineN == 3) atom->SetType("C+"); } // end C2 carbon for guanidinium } // end special cases }
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 MacroModFormat::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* defaultTitle = pConv->GetTitle(); // Get Title char buffer[BUFF_SIZE]; int natoms; vector<vector<pair<int,int> > > connections; if (ifs.getline(buffer,BUFF_SIZE)) { vector<string> vs; tokenize(vs,buffer," \n"); if ( !vs.empty() && vs.size() > 0) sscanf(buffer,"%i%*s",&natoms); if (natoms == 0) return false; if ( !vs.empty() && vs.size() > 1) mol.SetTitle(vs[1]); else { string s = defaultTitle; mol.SetTitle(defaultTitle); } } else return(false); mol.BeginModify(); mol.ReserveAtoms(natoms); connections.resize(natoms+1); /***********************************************************************/ // Get Type Bonds, BondOrder, X, Y, Z double x,y,z; vector3 v; char temp_type[10]; int i,j; double charge; OBAtom atom; ttab.SetFromType("MMD"); for (i = 1; i <= natoms; i++) { if (!ifs.getline(buffer,BUFF_SIZE)) break; int end[6], order[6]; sscanf(buffer,"%9s%d%d%d%d%d%d%d%d%d%d%d%d%lf%lf%lf", temp_type,&end[0],&order[0],&end[1],&order[1],&end[2],&order[2], &end[3], &order[3], &end[4], &order[4], &end[5], &order[5], &x, &y, &z); pair<int,int> tmp; for ( j = 0 ; j <=5 ; j++ ) { if ( end[j] > 0 && end[j] > i) { tmp.first = end[j]; tmp.second = order[j]; connections[i].push_back(tmp); } } v.SetX(x); v.SetY(y); v.SetZ(z); atom.SetVector(v); string str = temp_type,str1; ttab.SetToType("ATN"); ttab.Translate(str1,str); atom.SetAtomicNum(atoi(str1.c_str())); ttab.SetToType("INT"); ttab.Translate(str1,str); atom.SetType(str1); // stuff for optional fields buffer[109]='\0'; sscanf(&buffer[101],"%lf", &charge); atom.SetPartialCharge(charge); mol.AddAtom(atom); } for (i = 1; i <= natoms; i++) for (j = 0; j < (signed)connections[i].size(); j++) mol.AddBond(i, connections[i][j].first, connections[i][j].second); mol.EndModify(); OBBond *bond; vector<OBBond*>::iterator bi; for (bond = mol.BeginBond(bi);bond;bond = mol.NextBond(bi)) if (bond->GetBO() == 5 && !bond->IsInRing()) bond->SetBO(1); if ( natoms != (signed)mol.NumAtoms() ) return(false); // clean out remaining blank lines while(ifs.peek() != EOF && ifs.good() && (ifs.peek() == '\n' || ifs.peek() == '\r')) ifs.getline(buffer,BUFF_SIZE); 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 AlchemyFormat::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->GetInFilename().c_str(); int i; int natoms = 0, nbonds = 0; char buffer[BUFF_SIZE]; ifs.getline(buffer,BUFF_SIZE); sscanf(buffer," %d %*s %d", &natoms, &nbonds); if (!natoms) { ifs.getline(buffer,BUFF_SIZE); sscanf(buffer," %d %*s %d", &natoms, &nbonds); if (!natoms) return(false); } mol.ReserveAtoms(natoms); mol.BeginModify(); ttab.SetFromType("ALC"); string str; double x,y,z; OBAtom *atom; vector<string> vs; for (i = 1; i <= natoms; i ++) { if (!ifs.getline(buffer,BUFF_SIZE)) return(false); tokenize(vs,buffer); if (vs.size() < 5) return(false); atom = mol.NewAtom(); 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); //set coordinates //set atomic number ttab.SetToType("ATN"); ttab.Translate(str,vs[1]); atom->SetAtomicNum(atoi(str.c_str())); //set type ttab.SetToType("INT"); ttab.Translate(str,vs[1]); atom->SetType(str); } char bobuf[100]; string bostr; int bgn,end,order; for (i = 0; i < nbonds; i++) { if (!ifs.getline(buffer,BUFF_SIZE)) return(false); sscanf(buffer," %*d%d%d%99s",&bgn,&end,bobuf); bostr = bobuf; order = 1; if (bostr == "DOUBLE") order = 2; else if (bostr == "TRIPLE") order = 3; else if (bostr == "AROMATIC") order = 5; mol.AddBond(bgn,end,order); } // clean out remaining blank lines while(ifs.peek() != EOF && ifs.good() && (ifs.peek() == '\n' || ifs.peek() == '\r')) ifs.getline(buffer,BUFF_SIZE); mol.EndModify(); mol.SetTitle(title); return(true); }
bool ReadXYZ(istream &ifs,OBMol &mol,const char *title) { char buffer[BUFF_SIZE]; // Read the first line, which should contain the number of atoms in // the molecule. if (!ifs.getline(buffer,BUFF_SIZE)) { cerr << "WARNING: Problems reading an XYZ file, method 'bool ReadXYZ(istream &,OBMol &,const char *)'" << endl << " Could not read the first line, file error." << endl; return(false); } unsigned int natoms; // [ejk] assumed natoms could not be -ve if (sscanf(buffer,"%d", &natoms) == 0) { cerr << "WARNING: Problems reading an XYZ file, method 'bool ReadXYZ(istream &,OBMol &,const char *)'" << endl << " Problems reading the first line. The first line must contain the number of atoms." << endl << " OpenBabel found the line '" << buffer << "'" << endl << " which could not be interpreted as a number." << endl; return(false); } if (!natoms) { cerr << "WARNING: Problems reading an XYZ file, method 'bool ReadXYZ(istream &,OBMol &,const char *)'" << endl << " Problems reading the first line. The first line must contain the number of atoms." << endl << " OpenBabel found the number '0' which obviously does not work." << endl; return(false); } mol.ReserveAtoms(natoms); // The next line contains a title string for the molecule. Use this // as the title for the molecule if the line is not // empty. Otherwise, use the title given by the calling function. if (!ifs.getline(buffer,BUFF_SIZE)) { cerr << "WARNING: Problems reading an XYZ file, method 'bool ReadXYZ(istream &,OBMol &,const char *)'" << endl << " Could not read the second line, file error." << endl; return(false); } if (strlen(buffer) == 0) mol.SetTitle(buffer); else mol.SetTitle(title); // The next lines contain four items each, separated by white // spaces: the atom type, and the coordinates of the atom vector<string> vs; for (unsigned int i = 1; i <= natoms; i ++) { if (!ifs.getline(buffer,BUFF_SIZE)) { cerr << "WARNING: Problems reading an XYZ file, method 'bool ReadXYZ(istream &,OBMol &,const char *)'" << endl << " Could not read line #" << i+2 << ", file error." << endl << " According to line one, there should be " << natoms << " atoms, and therefore " << natoms+2 << " lines in the file" << endl; return(false); } tokenize(vs,buffer); if (vs.size() != 4) { cerr << "WARNING: Problems reading an XYZ file, method 'bool ReadXYZ(istream &,OBMol &,const char *)'" << endl << " Could not read line #" << i+2 << "." << endl << " OpenBabel found the line '" << buffer << "'" << endl << " According to the specifications, this line should contain exactly 4 entries, separated by white space." << endl << " However, OpenBabel found " << vs.size() << " items." << endl; return(false); } // Atom Type: get the atomic number from the element table, using // the first entry in the currently read line. If the entry makes // sense, set the atomic number and leave the atomic type open // (the type is then later faulted in when atom->GetType() is // called). If the entry does not make sense to use, set the atom // type manually, assuming that the author of the xyz-file had // something "special" in mind. OBAtom *atom = mol.NewAtom(); int atomicNum = etab.GetAtomicNum(vs[0].c_str()); atom->SetAtomicNum(etab.GetAtomicNum(vs[0].c_str())); //set atomic number, or '0' if the atom type is not recognized if (atomicNum == 0) atom->SetType(vs[0]); // Read the atom coordinates char *endptr; double x = strtod((char*)vs[1].c_str(),&endptr); if (endptr == (char*)vs[1].c_str()) { cerr << "WARNING: Problems reading an XYZ file, method 'bool ReadXYZ(istream &,OBMol &,const char *)'" << endl << " Could not read line #" << i+2 << "." << endl << " OpenBabel found the line '" << buffer << "'" << endl << " According to the specifications, this line should contain exactly 4 entries, separated by white space." << endl << " Item #0: Atom Type, Items #1-#3 cartesian coordinates in Angstrom." << endl << " OpenBabel could not interpret item #1 as a number." << endl; return(false); } double y = strtod((char*)vs[2].c_str(),&endptr); if (endptr == (char*)vs[2].c_str()) { cerr << "WARNING: Problems reading an XYZ file, method 'bool ReadXYZ(istream &,OBMol &,const char *)'" << endl << " Could not read line #" << i+2 << "." << endl << " OpenBabel found the line '" << buffer << "'" << endl << " According to the specifications, this line should contain exactly 4 entries, separated by white space." << endl << " Item #0: Atom Type, Items #1-#3 cartesian coordinates in Angstrom." << endl << " OpenBabel could not interpret item #2 as a number." << endl; return(false); } double z = strtod((char*)vs[3].c_str(),&endptr); if (endptr == (char*)vs[3].c_str()) { cerr << "WARNING: Problems reading an XYZ file, method 'bool ReadXYZ(istream &,OBMol &,const char *)'" << endl << " Could not read line #" << i+2 << "." << endl << " OpenBabel found the line '" << buffer << "'" << endl << " According to the specifications, this line should contain exactly 4 entries, separated by white space." << endl << " Item #0: Atom Type, Items #1-#3 cartesian coordinates in Angstrom." << endl << " OpenBabel could not interpret item #3 as a number." << endl; return(false); } atom->SetVector(x,y,z); //set coordinates } mol.ConnectTheDots(); mol.PerceiveBondOrders(); return(true); }
bool CHEM3D1Format::ReadChem3d(istream &ifs,OBMol &mol,bool mmads,const char *type_key) { char buffer[BUFF_SIZE]; int natoms,i; char tmp[16],tmp1[16]; char atomic_type[16]; double exponent = 0.0; double divisor = 1.0; double Alpha,Beta,Gamma,A,B,C; bool has_fractional = false, has_divisor = false; matrix3x3 m; vector<string> vs; ifs.getline(buffer,BUFF_SIZE); tokenize(vs,buffer); if (mmads) { if (vs.empty()) return(false); natoms = atoi((char*)vs[0].c_str()); if (vs.size() == 2) mol.SetTitle(vs[1]); } else { switch(vs.size()) { case 7 : sscanf(buffer,"%d%lf%lf%lf%lf%lf%lf", &natoms,&Alpha,&Beta,&Gamma,&A,&B,&C); m.FillOrth(Alpha,Beta,Gamma,A,B,C); has_fractional = true; break; case 8 : sscanf(buffer,"%d%lf%lf%lf%lf%lf%lf%lf", &natoms,&Alpha,&Beta,&Gamma,&A,&B,&C,&exponent); m.FillOrth(Alpha,Beta,Gamma,A,B,C); has_fractional = true; has_divisor = true; break; default : sscanf(buffer,"%d",&natoms); break; } } if (!natoms) return(false); divisor = pow(10.0,exponent); mol.ReserveAtoms(natoms); ttab.SetToType("INT"); ttab.SetFromType(type_key); OBAtom *atom; double x,y,z; vector3 v; unsigned int k; for (i = 1; i <= natoms; i++) { ifs.getline(buffer,BUFF_SIZE); sscanf(buffer,"%15s%*d%lf%lf%lf%15s", atomic_type, &x, &y, &z, tmp); v.Set(x,y,z); if (has_fractional) v *= m; if (has_divisor) v/= divisor; tokenize(vs,buffer); if (vs.empty()) return(false); atom = mol.NewAtom(); ttab.Translate(tmp1,tmp); atom->SetType(tmp1); atom->SetVector(v); atom->SetAtomicNum(etab.GetAtomicNum(atomic_type)); for (k = 6;k < vs.size(); k++) mol.AddBond(atom->GetIdx(),atoi((char*)vs[k].c_str()),1); } // clean out remaining blank lines while(ifs.peek() != EOF && ifs.good() && (ifs.peek() == '\n' || ifs.peek() == '\r')) ifs.getline(buffer,BUFF_SIZE); mol.PerceiveBondOrders(); return(true); }
bool TurbomoleFormat::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; double UnitConv=AAU; if(pConv->IsOption("a", OBConversion::INOPTIONS)) UnitConv=1; char buffer[BUFF_SIZE]; do { ifs.getline(buffer,BUFF_SIZE); if (ifs.peek() == EOF || !ifs.good()) return false; } while(strncmp(buffer,"$coord",6)); mol.BeginModify(); OBAtom atom; while(!(!ifs)) { ifs.getline(buffer,BUFF_SIZE); if(*buffer=='$') break; if(*buffer=='#') continue; float x,y,z; char atomtype[8]; if(sscanf(buffer,"%f %f %f %7s",&x,&y,&z,atomtype)!=4) return false; atom.SetVector(x*UnitConv, y*UnitConv, z*UnitConv); atom.SetAtomicNum(OBElements::GetAtomicNum(atomtype)); atom.SetType(atomtype); if(!mol.AddAtom(atom)) return false; atom.Clear(); } while(!(!ifs) && strncmp(buffer,"$end",4)) 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(); // clean out remaining blank lines std::streampos ipos; do { ipos = ifs.tellg(); ifs.getline(buffer,BUFF_SIZE); } while(strlen(buffer) == 0 && !ifs.eof() ); ifs.seekg(ipos); mol.EndModify(); return true; }