unsigned int GetAtomSymClass(OBAtom *atom) { OBPairData *pd = dynamic_cast<OBPairData*>(atom->GetParent()->GetData("OpenBabel Symmetry Classes")); if (pd) { cout << "same? = " << pd->GetValue() << endl; istringstream iss(pd->GetValue()); std::vector<unsigned int> symmetry_classes; copy(istream_iterator<unsigned int>(iss), istream_iterator<unsigned int>(), back_inserter<vector<unsigned int> >(symmetry_classes)); // Now find the number of unique elements vector<unsigned int> copy_sym = symmetry_classes; sort(copy_sym.begin(), copy_sym.end()); vector<unsigned int>::iterator end_pos = unique(copy_sym.begin(), copy_sym.end()); // Requires sorted elements int nclasses = end_pos - copy_sym.begin(); cout << "sym_class[" << atom->GetIndex() << "] = " << symmetry_classes.at(atom->GetIndex()) << endl; return symmetry_classes.at(atom->GetIndex()); } return 99; }
bool MOL2Format::WriteMolecule(OBBase* pOb, OBConversion* pConv) { OBMol* pmol = dynamic_cast<OBMol*>(pOb); if(pmol==NULL) return false; //Define some references so we can use the old parameter names ostream &ofs = *pConv->GetOutStream(); OBMol &mol = *pmol; bool ligandsOnly = pConv->IsOption("l", OBConversion::OUTOPTIONS)!=NULL; //The old code follows.... string str,str1; char buffer[BUFF_SIZE],label[BUFF_SIZE]; char rnum[BUFF_SIZE],rlabel[BUFF_SIZE]; ofs << "@<TRIPOS>MOLECULE" << endl; str = mol.GetTitle(); if (str.empty()) ofs << "*****" << endl; else ofs << str << endl; snprintf(buffer, BUFF_SIZE," %d %d 0 0 0", mol.NumAtoms(),mol.NumBonds()); ofs << buffer << endl; ofs << "SMALL" << endl; OBPairData *dp = (OBPairData*)mol.GetData("PartialCharges"); if (dp != NULL) { // Tripos spec says: // NO_CHARGES, DEL_RE, GASTEIGER, GAST_HUCK, HUCKEL, PULLMAN, // GAUSS80_CHARGES, AMPAC_CHARGES, MULLIKEN_CHARGES, DICT_ CHARGES, // MMFF94_CHARGES, USER_CHARGES if (dp->GetValue() == "Mulliken") ofs << "MULLIKEN_CHARGES" << endl; else // should pick from the Tripos types ofs << "GASTEIGER" << endl; } else { // No idea what these charges are... all our code sets "PartialCharges" ofs << "GASTEIGER" << endl; } ofs << "Energy = " << mol.GetEnergy() << endl; if (mol.HasData(OBGenericDataType::CommentData)) { OBCommentData *cd = (OBCommentData*)mol.GetData(OBGenericDataType::CommentData); ofs << cd->GetData(); } ofs << endl; ofs << "@<TRIPOS>ATOM" << endl; OBAtom *atom; OBResidue *res; vector<OBAtom*>::iterator i; vector<int> labelcount; labelcount.resize( etab.GetNumberOfElements() ); ttab.SetFromType("INT"); ttab.SetToType("SYB"); for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i)) { // // Use sequentially numbered atom names if no residues // snprintf(label,BUFF_SIZE, "%s%d", etab.GetSymbol(atom->GetAtomicNum()), ++labelcount[atom->GetAtomicNum()]); strcpy(rlabel,"<1>"); strcpy(rnum,"1"); str = atom->GetType(); ttab.Translate(str1,str); // // Use original atom names if there are residues // if (!ligandsOnly && (res = atom->GetResidue()) ) { // use original atom names defined by residue snprintf(label,BUFF_SIZE,"%s",(char*)res->GetAtomID(atom).c_str()); // make sure that residue name includes its number snprintf(rlabel,BUFF_SIZE,"%s%d",res->GetName().c_str(), res->GetNum()); snprintf(rnum,BUFF_SIZE,"%d",res->GetNum()); } snprintf(buffer,BUFF_SIZE,"%7d%1s%-6s%12.4f%10.4f%10.4f%1s%-5s%4s%1s %-8s%10.4f", atom->GetIdx(),"",label, atom->GetX(),atom->GetY(),atom->GetZ(), "",str1.c_str(), rnum,"",rlabel, atom->GetPartialCharge()); ofs << buffer << endl; } ofs << "@<TRIPOS>BOND" << endl; OBBond *bond; vector<OBBond*>::iterator j; OBSmartsPattern pat; string s1, s2; for (bond = mol.BeginBond(j);bond;bond = mol.NextBond(j)) { s1 = bond->GetBeginAtom()->GetType(); s2 = bond->GetEndAtom()->GetType(); if (bond->IsAromatic() || s1 == "O.co2" || s2 == "O.co2") strcpy(label,"ar"); else if (bond->IsAmide()) strcpy(label,"am"); else snprintf(label,BUFF_SIZE,"%d",bond->GetBO()); snprintf(buffer, BUFF_SIZE,"%6d%6d%6d%3s%2s", bond->GetIdx()+1,bond->GetBeginAtomIdx(),bond->GetEndAtomIdx(), "",label); ofs << buffer << endl; } // NO trailing blank line (PR#1868929). // ofs << endl; return(true); }
bool TinkerFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv) { OBMol* pmol = dynamic_cast<OBMol*>(pOb); if(pmol==NULL) return false; //Define some references so we can use the old parameter names ostream &ofs = *pConv->GetOutStream(); OBMol &mol = *pmol; bool mmffTypes = pConv->IsOption("m",OBConversion::OUTOPTIONS) != NULL; unsigned int i; char buffer[BUFF_SIZE]; OBBond *bond; vector<OBBond*>::iterator j; // Before we try output of MMFF94 atom types, check if it works OBForceField *ff = OpenBabel::OBForceField::FindForceField("MMFF94"); if (mmffTypes && ff && ff->Setup(mol)) mmffTypes = ff->GetAtomTypes(mol); else mmffTypes = false; // either the force field isn't available, or it doesn't work if (!mmffTypes) snprintf(buffer, BUFF_SIZE, "%6d %-20s MM2 parameters\n",mol.NumAtoms(),mol.GetTitle()); else snprintf(buffer, BUFF_SIZE, "%6d %-20s MMFF94 parameters\n",mol.NumAtoms(),mol.GetTitle()); ofs << buffer; ttab.SetFromType("INT"); OBAtom *atom; string str,str1; for(i = 1;i <= mol.NumAtoms(); i++) { atom = mol.GetAtom(i); str = atom->GetType(); ttab.SetToType("MM2"); ttab.Translate(str1,str); if (mmffTypes) { // Override the MM2 typing OBPairData *type = (OpenBabel::OBPairData*)atom->GetData("FFAtomType"); if (type) str1 = type->GetValue().c_str(); } snprintf(buffer, BUFF_SIZE, "%6d %2s %12.6f%12.6f%12.6f %5d", i, etab.GetSymbol(atom->GetAtomicNum()), atom->GetX(), atom->GetY(), atom->GetZ(), atoi((char*)str1.c_str())); ofs << buffer; for (bond = atom->BeginBond(j); bond; bond = atom->NextBond(j)) { snprintf(buffer, BUFF_SIZE, "%6d", (bond->GetNbrAtom(atom))->GetIdx()); ofs << buffer; } ofs << endl; } return(true); }
bool PDBFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv) { OBMol* pmol = dynamic_cast<OBMol*>(pOb); if(pmol==NULL) return false; //Define some references so we can use the old parameter names ostream &ofs = *pConv->GetOutStream(); OBMol &mol = *pmol; unsigned int i; char buffer[BUFF_SIZE]; char type_name[10], padded_name[10]; char the_res[10]; char the_chain = ' '; const char *element_name; int res_num; bool het=true; int model_num = 0; if (!pConv->IsLast() || pConv->GetOutputIndex() > 1) { // More than one molecule record model_num = pConv->GetOutputIndex(); // MODEL 1-based index snprintf(buffer, BUFF_SIZE, "MODEL %8d", model_num); ofs << buffer << endl; } // write back all fields (REMARKS, HELIX, SHEET, SITE, ...) bool compndWritten = false; bool authorWritten = false; std::vector<OBGenericData*> pairData = mol.GetAllData(OBGenericDataType::PairData); for (std::vector<OBGenericData*>::iterator data = pairData.begin(); data != pairData.end(); ++data) { OBPairData *pd = static_cast<OBPairData*>(*data); string attr = pd->GetAttribute(); // filter to make sure we are writing pdb fields only if (attr != "HEADER" && attr != "OBSLTE" && attr != "TITLE" && attr != "SPLIT" && attr != "CAVEAT" && attr != "COMPND" && attr != "SOURCE" && attr != "KEYWDS" && attr != "EXPDTA" && attr != "NUMMDL" && attr != "MDLTYP" && attr != "AUTHOR" && attr != "REVDAT" && attr != "SPRSDE" && attr != "JRNL" && attr != "REMARK" && attr != "DBREF" && attr != "DBREF1" && attr != "DBREF2" && attr != "SEQADV" && attr != "SEQRES" && attr != "MODRES" && attr != "HET" && attr != "HETNAM" && attr != "HETSYN" && attr != "FORMUL" && attr != "HELIX" && attr != "SHEET" && attr != "SSBOND" && attr != "LINK" && attr != "CISPEP" && attr != "SITE" && attr != "ORIGX1" && attr != "ORIGX2" && attr != "ORIGX3" && attr != "SCALE1" && attr != "SCALE2" && attr != "SCALE3" && attr != "MATRIX1" && attr != "MATRIX2" && attr != "MATRIX3" && attr != "MODEL") continue; if (attr == "COMPND") compndWritten = true; if (attr == "AUTHOR") authorWritten = true; // compute spacing needed. HELIX, SITE, HET, ... are trimmed when reading int nSpacing = 6 - attr.size(); for (int i = 0; i < nSpacing; ++i) attr += " "; std::string lines = pd->GetValue(); string::size_type last = 0; string::size_type pos = lines.find('\n'); while (last != string::npos) { string line = lines.substr(last, pos - last); if (pos == string::npos) last = string::npos; else last = pos + 1; pos = lines.find('\n', last); ofs << attr << line << endl; } } if (!compndWritten) { if (strlen(mol.GetTitle()) > 0) snprintf(buffer, BUFF_SIZE, "COMPND %s ",mol.GetTitle()); else snprintf(buffer, BUFF_SIZE, "COMPND UNNAMED"); ofs << buffer << endl; } if (!authorWritten) { snprintf(buffer, BUFF_SIZE, "AUTHOR GENERATED BY OPEN BABEL %s",BABEL_VERSION); ofs << buffer << endl; } // Write CRYST1 record, containing unit cell parameters, space group // and Z value (supposed to be 1) if (pmol->HasData(OBGenericDataType::UnitCell)) { OBUnitCell *pUC = (OBUnitCell*)pmol->GetData(OBGenericDataType::UnitCell); if(pUC->GetSpaceGroup()){ string tmpHM=pUC->GetSpaceGroup()->GetHMName(); // Do we have an extended HM symbol, with origin choice as ":1" or ":2" ? If so, remove it. size_t n=tmpHM.find(":"); if(n!=string::npos) tmpHM=tmpHM.substr(0,n); snprintf(buffer, BUFF_SIZE, "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f %-11s 1", pUC->GetA(), pUC->GetB(), pUC->GetC(), pUC->GetAlpha(), pUC->GetBeta(), pUC->GetGamma(), tmpHM.c_str()); } else snprintf(buffer, BUFF_SIZE, "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f %-11s 1", pUC->GetA(), pUC->GetB(), pUC->GetC(), pUC->GetAlpha(), pUC->GetBeta(), pUC->GetGamma(), "P1"); ofs << buffer << endl; } // before we write any records, we should check to see if any coord < -1000 // which will cause errors in the formatting double minX, minY, minZ; minX = minY = minZ = -999.0f; FOR_ATOMS_OF_MOL(a, mol) { if (a->GetX() < minX) minX = a->GetX(); if (a->GetY() < minY) minY = a->GetY(); if (a->GetZ() < minZ) minZ = a->GetZ(); } vector3 transV = VZero; if (minX < -999.0) transV.SetX(-1.0*minX - 900.0); if (minY < -999.0) transV.SetY(-1.0*minY - 900.0); if (minZ < -999.0) transV.SetZ(-1.0*minZ - 900.0); // if minX, minY, or minZ was never changed, shift will be 0.0f // otherwise, move enough so that smallest coord is > -999.0f mol.Translate(transV); OBAtom *atom; OBResidue *res; for (i = 1; i <= mol.NumAtoms(); i++) { atom = mol.GetAtom(i); strncpy(type_name, etab.GetSymbol(atom->GetAtomicNum()), sizeof(type_name)); type_name[sizeof(type_name) - 1] = '\0'; //two char. elements are on position 13 and 14 one char. start at 14 if (strlen(type_name) > 1) type_name[1] = toupper(type_name[1]); else { char tmp[10]; strncpy(tmp, type_name, 9); // make sure to null-terminate tmp snprintf(type_name, sizeof(type_name), " %-3s", tmp); } if ( (res = atom->GetResidue()) != 0 ) { het = res->IsHetAtom(atom); snprintf(the_res,4,"%s",(char*)res->GetName().c_str()); the_res[4] = '\0'; snprintf(type_name,5,"%s",(char*)res->GetAtomID(atom).c_str()); the_chain = res->GetChain(); //two char. elements are on position 13 and 14 one char. start at 14 if (strlen(etab.GetSymbol(atom->GetAtomicNum())) == 1) { if (strlen(type_name) < 4) { char tmp[10]; strncpy(tmp, type_name, 9); // make sure to null-terminate tmp snprintf(padded_name, sizeof(padded_name), " %-3s", tmp); strncpy(type_name,padded_name,4); type_name[4] = '\0'; } else { /* type_name[4] = type_name[3]; type_name[3] = type_name[2]; type_name[2] = type_name[1]; type_name[1] = type_name[0]; type_name[0] = type_name[4]; */ type_name[4] = '\0'; } } res_num = res->GetNum(); } else { strcpy(the_res,"UNK"); the_res[3] = '\0'; snprintf(padded_name,sizeof(padded_name), "%s",type_name); strncpy(type_name,padded_name,4); type_name[4] = '\0'; res_num = 1; } element_name = etab.GetSymbol(atom->GetAtomicNum()); int charge = atom->GetFormalCharge(); char scharge[3] = { ' ', ' ', '\0' }; if(0 != charge) { snprintf(scharge, 3, "%+d", charge); char tmp = scharge[1]; scharge[1] = scharge[0]; scharge[0] = tmp; } snprintf(buffer, BUFF_SIZE, "%s%5d %-4s %-3s %c%4d %8.3f%8.3f%8.3f 1.00 0.00 %2s%2s\n", het?"HETATM":"ATOM ", i, type_name, the_res, the_chain, res_num, atom->GetX(), atom->GetY(), atom->GetZ(), element_name, scharge); ofs << buffer; } OBAtom *nbr; vector<OBBond*>::iterator k; for (i = 1; i <= mol.NumAtoms(); i ++) { atom = mol.GetAtom(i); if (atom->GetValence() == 0) continue; // no need to write a CONECT record -- no bonds snprintf(buffer, BUFF_SIZE, "CONECT%5d", i); ofs << buffer; // Write out up to 4 real bonds per line PR#1711154 int currentValence = 0; for (nbr = atom->BeginNbrAtom(k);nbr;nbr = atom->NextNbrAtom(k)) { snprintf(buffer, BUFF_SIZE, "%5d", nbr->GetIdx()); ofs << buffer; if (++currentValence % 4 == 0) { // Add the trailing space to finish this record ofs << " \n"; // write the start of a new CONECT record snprintf(buffer, BUFF_SIZE, "CONECT%5d", i); ofs << buffer; } } // Add trailing spaces int remainingValence = atom->GetValence() % 4; for (int count = 0; count < (4 - remainingValence); count++) { snprintf(buffer, BUFF_SIZE, " "); ofs << buffer; } ofs << " \n"; } snprintf(buffer, BUFF_SIZE, "MASTER 0 0 0 0 0 0 0 0 "); ofs << buffer; snprintf(buffer, BUFF_SIZE, "%4d 0 %4d 0\n",mol.NumAtoms(),mol.NumAtoms()); ofs << buffer; ofs << "END\n"; if (model_num) { ofs << "ENDMDL" << endl; } return(true); }
int main(int argc,char *argv[]) { // turn off slow sync with C-style output (we don't use it anyway). std::ios::sync_with_stdio(false); OBConversion conv; OBFormat *inFormat, *canFormat; OBMol mol; ifstream ifs; vector<OBMol> fragments; unsigned int fragmentCount = 0; // track how many in library -- give a running count map<string, int> index; // index of cansmi string currentCAN; unsigned int size; OBAtom *atom; OBBond *bond; bool nonRingAtoms, nonRingBonds; char buffer[BUFF_SIZE]; canFormat = conv.FindFormat("can"); conv.SetOutFormat(canFormat); if (argc < 2) { cout << "Usage: obfragment <file>" << endl; return(-1); } for (int i = 1; i < argc; i++) { cerr << " Reading file " << argv[i] << endl; inFormat = conv.FormatFromExt(argv[i]); if(inFormat==NULL || !conv.SetInFormat(inFormat)) { cerr << " Cannot read file format for " << argv[i] << endl; continue; // try next file } ifs.open(argv[i]); if (!ifs) { cerr << "Cannot read input file: " << argv[i] << endl; continue; } while(ifs.peek() != EOF && ifs.good()) { conv.Read(&mol, &ifs); if (!mol.Has3D()) continue; // invalid coordinates! mol.DeleteHydrogens(); // remove these before we do anything else do { nonRingAtoms = false; size = mol.NumAtoms(); for (unsigned int i = 1; i <= size; ++i) { atom = mol.GetAtom(i); if (!atom->IsInRing()) { mol.DeleteAtom(atom); nonRingAtoms = true; break; // don't know how many atoms there are } // Previously, we changed atoms to carbon here. // Now we perform this alchemy in terms of string-rewriting // once the canonical SMILES is generated } } while (nonRingAtoms); if (mol.NumAtoms() < 3) continue; if (mol.NumBonds() == 0) continue; do { nonRingBonds = false; size = mol.NumBonds(); for (unsigned int i = 0; i < size; ++i) { bond = mol.GetBond(i); if (!bond->IsInRing()) { mol.DeleteBond(bond); nonRingBonds = true; break; // don't know how many bonds there are } } } while (nonRingBonds); fragments = mol.Separate(); for (unsigned int i = 0; i < fragments.size(); ++i) { if (fragments[i].NumAtoms() < 3) // too small to care continue; currentCAN = conv.WriteString(&fragments[i], true); currentCAN = RewriteSMILES(currentCAN); // change elements to "a/A" for compression if (index.find(currentCAN) != index.end()) { // already got this index[currentCAN] += 1; // add to the count for bookkeeping continue; } index[currentCAN] = 1; // don't ever write this ring fragment again // OK, now retrieve the canonical ordering for the fragment vector<string> canonical_order; if (fragments[i].HasData("Canonical Atom Order")) { OBPairData *data = (OBPairData*)fragments[i].GetData("Canonical Atom Order"); tokenize(canonical_order, data->GetValue().c_str()); } // Write out an XYZ-style file with the CANSMI as the title cout << fragments[i].NumAtoms() << '\n'; cout << currentCAN << '\n'; // endl causes a flush vector<string>::iterator can_iter; unsigned int order; OBAtom *atom; fragments[i].Center(); fragments[i].ToInertialFrame(); for (unsigned int index = 0; index < canonical_order.size(); ++index) { order = atoi(canonical_order[index].c_str()); atom = fragments[i].GetAtom(order); snprintf(buffer, BUFF_SIZE, "C%8.3f%8.3f%8.3f\n", atom->x(), atom->y(), atom->z()); cout << buffer; } } fragments.clear(); if (index.size() > fragmentCount) { fragmentCount = index.size(); cerr << " Fragments: " << fragmentCount << endl; } } // while reading molecules (in this file) ifs.close(); ifs.clear(); } // while reading files // loop through the map and output frequencies map<string, int>::const_iterator indexItr; for (indexItr = index.begin(); indexItr != index.end(); ++indexItr) { cerr << (*indexItr).second << " INDEX " << (*indexItr).first << "\n"; } return(0); }
bool TinkerFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv) { OBMol* pmol = dynamic_cast<OBMol*>(pOb); if(pmol==NULL) return false; //Define some references so we can use the old parameter names ostream &ofs = *pConv->GetOutStream(); OBMol &mol = *pmol; bool mm2Types = false; bool mmffTypes = pConv->IsOption("m",OBConversion::OUTOPTIONS) != NULL; bool mm3Types = pConv->IsOption("3",OBConversion::OUTOPTIONS) != NULL; bool classTypes = pConv->IsOption("c", OBConversion::OUTOPTIONS) != NULL; unsigned int i; char buffer[BUFF_SIZE]; OBBond *bond; vector<OBBond*>::iterator j; // Before we try output of MMFF94 atom types, check if it works OBForceField *ff = OpenBabel::OBForceField::FindForceField("MMFF94"); if (mmffTypes && ff && ff->Setup(mol)) mmffTypes = ff->GetAtomTypes(mol); else mmffTypes = false; // either the force field isn't available, or it doesn't work if (!mmffTypes && !mm3Types && !classTypes) { snprintf(buffer, BUFF_SIZE, "%6d %-20s MM2 parameters\n",mol.NumAtoms(),mol.GetTitle()); mm2Types = true; } else if (mm3Types) snprintf(buffer, BUFF_SIZE, "%6d %-20s MM3 parameters\n",mol.NumAtoms(),mol.GetTitle()); else if (classTypes) snprintf(buffer, BUFF_SIZE, "%6d %-20s Custom parameters\n",mol.NumAtoms(),mol.GetTitle()); else snprintf(buffer, BUFF_SIZE, "%6d %-20s MMFF94 parameters\n",mol.NumAtoms(),mol.GetTitle()); ofs << buffer; ttab.SetFromType("INT"); OBAtom *atom; string str,str1; int atomType; for(i = 1;i <= mol.NumAtoms(); i++) { atom = mol.GetAtom(i); str = atom->GetType(); atomType = 0; // Something is very wrong if this doesn't get set below if (mm2Types) { ttab.SetToType("MM2"); ttab.Translate(str1,str); atomType = atoi((char*)str1.c_str()); } if (mmffTypes) { // Override the MM2 typing OBPairData *type = (OpenBabel::OBPairData*)atom->GetData("FFAtomType"); if (type) { str1 = type->GetValue().c_str(); atomType = atoi((char*)str1.c_str()); } } if (mm3Types) { // convert to integer for MM3 typing atomType = SetMM3Type(atom); } if (classTypes) { // Atom classes are set by the user, so use those OBGenericData *data = atom->GetData("Atom Class"); if (data) { OBPairInteger* acdata = dynamic_cast<OBPairInteger*>(data); // Could replace with C-style cast if willing to live dangerously if (acdata) { int ac = acdata->GetGenericValue(); if (ac >= 0) atomType = ac; } } } snprintf(buffer, BUFF_SIZE, "%6d %2s %12.6f%12.6f%12.6f %5d", i, OBElements::GetSymbol(atom->GetAtomicNum()), atom->GetX(), atom->GetY(), atom->GetZ(), atomType); ofs << buffer; for (bond = atom->BeginBond(j); bond; bond = atom->NextBond(j)) { snprintf(buffer, BUFF_SIZE, "%6d", (bond->GetNbrAtom(atom))->GetIdx()); ofs << buffer; } ofs << endl; } return(true); }
void mmff94_validate() { OBForceField* pFF = OBForceField::FindForceField("MMFF94"); OBConversion conv; OBFormat *format_in = conv.FindFormat("mol2"); vector<string> vs; vector<int> types; vector<double> fcharges, pcharges; vector<double> bond_lengths; char buffer[BUFF_SIZE], _logbuf[BUFF_SIZE]; bool molfound, atomfound, bondfound, fchgfound, pchgfound; double etot, ebond, eangle, eoop, estbn, etor, evdw, eeq; double termcount; //1=bond, 2=angle, 3=strbnd, 4=torsion, 5=oop int n = 0; BOOST_REQUIRE_MESSAGE( format_in && conv.SetInFormat(format_in), "Could not set mol2 input format" ); ifstream ifs, ifs2; ofstream ofs; ifs.open("MMFF94_dative.mol2"); BOOST_REQUIRE_MESSAGE( ifs, "Could not open ./MMFF94_dative.mol2" ); ifs2.open("MMFF94_opti.log"); BOOST_REQUIRE_MESSAGE( ifs2, "Could not open ./MMFF94_opti.log" ); ofs.open("MMFF94_openbabel.log"); BOOST_REQUIRE_MESSAGE( ofs, "Could not open ./MMFF94_openbabel.log" ); pFF->SetLogFile(&ofs); pFF->SetLogLevel(OBFF_LOGLVL_HIGH); OBMol mol; for (unsigned int c=1;; c++) { mol.Clear(); types.clear(); fcharges.clear(); pcharges.clear(); bond_lengths.clear(); if (!conv.Read(&mol, &ifs)) break; if (mol.Empty()) break; BOOST_CHECK_MESSAGE( pFF->Setup(mol), "Could not setup calculations (missing parameters...)" ); pFF->GetAtomTypes(mol); //pFF->GetFormalCharges(mol); pFF->GetPartialCharges(mol); termcount = 0; molfound = false; atomfound = false; bondfound = false; fchgfound = false; pchgfound = false; // Parse log file for types, charges, energies, .. while (ifs2.getline(buffer, 150)) { tokenize(vs, buffer); if (vs.size() == 0) { bondfound = false; continue; } string str(buffer); if (string::npos != str.find(mol.GetTitle(),0)) molfound = true; // read atom types if (atomfound) { if (n) { types.push_back(atoi(vs[2].c_str())); types.push_back(atoi(vs[5].c_str())); types.push_back(atoi(vs[8].c_str())); types.push_back(atoi(vs[11].c_str())); } else { if (vs.size() > 2) types.push_back(atoi(vs[2].c_str())); if (vs.size() > 5) types.push_back(atoi(vs[5].c_str())); if (vs.size() > 8) types.push_back(atoi(vs[8].c_str())); atomfound = false; } n--; } // read formal charges if (fchgfound) { if (n) { fcharges.push_back(atof(vs[2].c_str())); fcharges.push_back(atof(vs[5].c_str())); fcharges.push_back(atof(vs[8].c_str())); fcharges.push_back(atof(vs[11].c_str())); } else { if (vs.size() > 2) fcharges.push_back(atof(vs[2].c_str())); if (vs.size() > 5) fcharges.push_back(atof(vs[5].c_str())); if (vs.size() > 8) fcharges.push_back(atof(vs[8].c_str())); fchgfound = false; } n--; } // read partial charges if (pchgfound) { if (n) { pcharges.push_back(atof(vs[2].c_str())); pcharges.push_back(atof(vs[5].c_str())); pcharges.push_back(atof(vs[8].c_str())); pcharges.push_back(atof(vs[11].c_str())); } else { if (vs.size() > 2) pcharges.push_back(atof(vs[2].c_str())); if (vs.size() > 5) pcharges.push_back(atof(vs[5].c_str())); if (vs.size() > 8) pcharges.push_back(atof(vs[8].c_str())); pchgfound = false; } n--; } // identify blocks if (molfound && EQn(buffer, " ATOM NAME TYPE", 16)) { atomfound = true; n = mol.NumAtoms() / 4; } if (molfound && EQn(buffer, " ATOM FCHARGE", 17)) { fchgfound = true; n = mol.NumAtoms() / 4; } if (molfound && EQn(buffer, " ATOM CHARGE", 17)) { pchgfound = true; n = mol.NumAtoms() / 4; } if (bondfound) bond_lengths.push_back(atof(vs[7].c_str())); // Get the energies if (molfound) { if (EQn(buffer, " Total ENERGY", 13)) etot = atof(vs[3].c_str()); if (EQn(buffer, " Bond Stretching", 16)) ebond = atof(vs[2].c_str()); if (EQn(buffer, " Angle Bending", 14)) eangle = atof(vs[2].c_str()); if (EQn(buffer, " Out-of-Plane Bending", 21)) eoop = atof(vs[2].c_str()); if (EQn(buffer, " Stretch-Bend", 13)) estbn = atof(vs[1].c_str()); if (EQn(buffer, " Total Torsion", 18)) etor = atof(vs[2].c_str()); if (EQn(buffer, " Net vdW", 12)) evdw = atof(vs[2].c_str()); if (EQn(buffer, " Electrostatic", 14)) eeq = atof(vs[1].c_str()); if (EQn(buffer, " ---------------------", 22) && (termcount == 0)) { termcount++; bondfound = true; } if (EQn(buffer, " OPTIMOL> # read next", 22)) break; } } // while (getline) ostringstream os; vector<int>::iterator i; vector<double>::iterator di; unsigned int ni; bool failed; cout << "--------------------------------------------------------------------------------" << endl; cout << " " << endl; cout << " VALIDATE MOLECULE " << c << ": " << mol.GetTitle() << endl; cout << " " << endl; cout << "IDX HYB AROM OB_TYPE LOG_TYPE RESULT " << endl; cout << "---------------------------------------------- " << endl; // // validate atom types // ni = 1; failed = false; for (i = types.begin(); i != types.end();i++) { if (ni > mol.NumAtoms()) continue; OBPairData *type = (OBPairData*) mol.GetAtom(ni)->GetData("FFAtomType"); if (!type) continue; os.str(""); os << "In molecule " << mol.GetTitle() << ": Wrong atom type for atom "; os << ni << " # found " << type->GetValue() << ", expected " << *i; BOOST_CHECK_MESSAGE( atoi(type->GetValue().c_str()) == (*i), os.str().c_str()); if (atoi(type->GetValue().c_str()) == (*i)) snprintf(_logbuf, BUFF_SIZE, "%2d %3d %4d %3d %3d PASSED", mol.GetAtom(ni)->GetIdx(), mol.GetAtom(ni)->GetHyb(), mol.GetAtom(ni)->IsAromatic(), atoi(mol.GetAtom(ni)->GetType()), *i); else { snprintf(_logbuf, BUFF_SIZE, "%2d %3d %4d %3d %3d XXX FAILED XXX", mol.GetAtom(ni)->GetIdx(), mol.GetAtom(ni)->GetHyb(), mol.GetAtom(ni)->IsAromatic(), atoi(type->GetValue().c_str()), *i); failed = true; } cout << _logbuf << endl; ni++; } /* cout << endl; cout << "IDX OB_FCARGE LOG_FCHARGE RESULT" << endl; cout << "----------------------------------------" << endl; // // validate formal charges // ni = 1; for (di = fcharges.begin(); di != fcharges.end(); di++) { if (ni > mol.NumAtoms()) continue; if (fabs((*di) - mol.GetAtom(ni)->GetPartialCharge()) <= 0.001) snprintf(_logbuf, BUFF_SIZE, "%2d %7.4f %7.4f PASSED", mol.GetAtom(ni)->GetIdx(), mol.GetAtom(ni)->GetPartialCharge(), *di); else { snprintf(_logbuf, BUFF_SIZE, "%2d %7.4f %7.4f XXX FAILED XXX", mol.GetAtom(ni)->GetIdx(), mol.GetAtom(ni)->GetPartialCharge(), *di); failed = true; } cout << _logbuf << endl; ni++; } */ cout << endl; cout << "IDX OB_PCARGE LOG_PCHARGE RESULT" << endl; cout << "----------------------------------------" << endl; // // validate partial charges // ni = 1; for (di = pcharges.begin(); di != pcharges.end(); di++) { if (ni > mol.NumAtoms()) continue; OBPairData *chg = (OBPairData*) mol.GetAtom(ni)->GetData("FFPartialCharge"); if (!chg) continue; os.str(""); os << "In molecule " << mol.GetTitle() << ": Wrong partial charge for atom "; os << ni << " # found " << chg->GetValue() << ", expected " << *di; BOOST_CHECK_MESSAGE( fabs((*di) - atof(chg->GetValue().c_str())) <= 0.001, os.str().c_str()); if (fabs((*di) - atof(chg->GetValue().c_str())) <= 0.001) snprintf(_logbuf, BUFF_SIZE, "%2d %7.4f %7.4f PASSED", mol.GetAtom(ni)->GetIdx(), atof(chg->GetValue().c_str()), *di); else { snprintf(_logbuf, BUFF_SIZE, "%2d %7.4f %7.4f XXX FAILED XXX", mol.GetAtom(ni)->GetIdx(), atof(chg->GetValue().c_str()), *di); failed = true; } cout << _logbuf << endl; ni++; } double ene, delta; cout << endl; cout << "TERM OB ENERGY LOG ENERGY DELTA" << endl; cout << "---------------------------------------------------------------" << endl; // // validate energies // // bond stretching ene = pFF->E_Bond(); delta = (ene - ebond); os.str(""); os << "In molecule " << mol.GetTitle() << ": Wrong bond stretching energy "; os << " # found " << ene << ", expected " << ebond; BOOST_CHECK_MESSAGE( delta < 0.005, os.str().c_str()); snprintf(_logbuf, BUFF_SIZE, "Bond Stretching %11.5f %11.5f %11.5f", ene, ebond, delta); cout << _logbuf << endl; // angle bending ene = pFF->E_Angle(); delta = (ene - eangle); os.str(""); os << "In molecule " << mol.GetTitle() << ": Wrong angle bending energy "; os << " # found " << ene << ", expected " << eangle; BOOST_CHECK_MESSAGE( delta < 0.005, os.str().c_str()); snprintf(_logbuf, BUFF_SIZE, "Angle Bending %11.5f %11.5f %11.5f", ene, eangle, delta); cout << _logbuf << endl; // stretch bending ene = pFF->E_StrBnd(); delta = (ene - estbn); os.str(""); os << "In molecule " << mol.GetTitle() << ": Wrong stretch bending energy "; os << " # found " << ene << ", expected " << estbn; BOOST_CHECK_MESSAGE( delta < 0.005, os.str().c_str()); snprintf(_logbuf, BUFF_SIZE, "Stretch-Bending %11.5f %11.5f %11.5f", ene, estbn, delta); cout << _logbuf << endl; // OOP ene = pFF->E_OOP(); delta = (ene - eoop); os.str(""); os << "In molecule " << mol.GetTitle() << ": Wrong out-of-plane bending energy "; os << " # found " << ene << ", expected " << eoop; BOOST_CHECK_MESSAGE( delta < 0.005, os.str().c_str()); snprintf(_logbuf, BUFF_SIZE, "Out-Of-Plane Bending %11.5f %11.5f %11.5f", ene, eoop, delta); cout << _logbuf << endl; // Torsional ene = pFF->E_Torsion(); delta = (ene - etor); os.str(""); os << "In molecule " << mol.GetTitle() << ": Wrong torsional energy "; os << " # found " << ene << ", expected " << etor; BOOST_CHECK_MESSAGE( delta < 0.005, os.str().c_str()); snprintf(_logbuf, BUFF_SIZE, "Torsional %11.5f %11.5f %11.5f", ene, etor, delta); cout << _logbuf << endl; // VDW ene = pFF->E_VDW(); delta = (ene - evdw); os.str(""); os << "In molecule " << mol.GetTitle() << ": Wrong van der waals energy "; os << " # found " << ene << ", expected " << evdw; BOOST_CHECK_MESSAGE( delta < 0.005, os.str().c_str()); snprintf(_logbuf, BUFF_SIZE, "Van der Waals %11.5f %11.5f %11.5f", ene, evdw, delta); cout << _logbuf << endl; // Electrostatic ene = pFF->E_Electrostatic(); delta = (ene - eeq); os << "In molecule " << mol.GetTitle() << ": Wrong electrostatic energy "; os << " # found " << ene << ", expected " << eeq; BOOST_CHECK_MESSAGE( delta < 0.005, os.str().c_str()); snprintf(_logbuf, BUFF_SIZE, "Electrostatic %11.5f %11.5f %11.5f", ene, eeq, delta); cout << _logbuf << endl; cout << endl; ene = pFF->Energy(); delta = (ene - etot); os.str(""); os << "In molecule " << mol.GetTitle() << ": Wrong total energy "; os << " # found " << ene << ", expected " << etot; BOOST_CHECK_MESSAGE( delta < 0.005, os.str().c_str()); snprintf(_logbuf, BUFF_SIZE, "Total ENERGY %11.5f %11.5f %11.5f", ene, etot, delta); cout << _logbuf << endl; } // for (unsigned int c;; c++ ) if (ifs) ifs.close(); if (ifs2) ifs2.close(); if (ofs) ofs.close(); }