// $Id$ // // Copyright (C) 2007-2008 Greg Landrum // // @@ All Rights Reserved @@ // This file is part of the RDKit. // The contents are covered by the terms of the BSD license // which is included in the file license.txt, found at the root // of the RDKit source tree. // #include "FileParsers.h" #include #include #include #include #include namespace RDKit { namespace TPLWriter { void writeAtom(const ROMol &mol, unsigned int atomId, ROMol::ConstConformerIterator confIt, std::ostringstream &dest, std::string partialChargeProp) { const Atom *atom = mol.getAtomWithIdx(atomId); dest << atomId + 1; dest << " " << atom->getSymbol(); dest << " " << atom->getFormalCharge(); std::string propVal; if (atom->hasProp(partialChargeProp)) { atom->getProp(partialChargeProp, propVal); } else { propVal = "0.0"; } dest << " " << propVal; const RDGeom::Point3D &pos = (*confIt)->getAtomPos(atomId); dest << " " << 100. * pos.x << " " << 100. * pos.y << " " << 100. * pos.z; ROMol::ADJ_ITER nbrIdx, endNbrs; boost::tie(nbrIdx, endNbrs) = mol.getAtomNeighbors(atom); dest << " " << (endNbrs - nbrIdx); while (nbrIdx != endNbrs) { dest << " " << (*nbrIdx + 1); ++nbrIdx; } // FIX: get this right: dest << " " << "U"; dest << "\n"; } void writeBond(const ROMol &mol, unsigned int bondId, std::ostringstream &dest) { const Bond *bond = mol.getBondWithIdx(bondId); dest << bondId + 1; std::string bondLabel; switch (bond->getBondType()) { case Bond::SINGLE: if (bond->getIsAromatic()) { bondLabel = "1.5"; } else { bondLabel = "1.0"; } break; case Bond::DOUBLE: if (bond->getIsAromatic()) { bondLabel = "1.5"; } else { bondLabel = "2.0"; } break; case Bond::AROMATIC: bondLabel = "1.5"; break; case Bond::TRIPLE: bondLabel = "3.0"; break; default: BOOST_LOG(rdWarningLog) << "TPL files only support single, double, " "aromatic, and triple bonds." << std::endl; BOOST_LOG(rdWarningLog) << "Bond of with type " << bond->getBondType() << " written as single in output." << std::endl; bondLabel = "1.0"; } dest << " " << bondLabel; dest << " " << bond->getBeginAtomIdx() + 1 << " " << bond->getEndAtomIdx() + 1; // FIX: add these dest << " " << "0" << " " << "0"; dest << "\n"; } } // namespace TPLWriter std::string MolToTPLText(const ROMol &mol, const std::string &partialChargeProp, bool writeFirstConfTwice) { if (!mol.getNumConformers()) { BOOST_LOG(rdErrorLog) << "Cannot write molecules with no conformers to TPL files\n"; return ""; } std::ostringstream res; std::string tempStr; res << "BioCAD format, all rights reserved" << "\n"; res << "Output from RDKit" << "\n"; if (!mol.hasProp(common_properties::_Name)) { BOOST_LOG(rdWarningLog) << "Molecule has no name; arbitrary name assigned.\n"; tempStr = "Unnamed molecule"; } else { mol.getProp(common_properties::_Name, tempStr); } res << "NAME " << tempStr << "\n"; res << "PROP 7 1" << "\n"; res << mol.getNumAtoms() << " " << mol.getNumBonds() << "\n"; auto confIt = mol.beginConformers(); // write the atoms: for (unsigned int i = 0; i < mol.getNumAtoms(); ++i) { TPLWriter::writeAtom(mol, i, confIt, res, partialChargeProp); } // write the bonds: for (unsigned int i = 0; i < mol.getNumBonds(); ++i) { TPLWriter::writeBond(mol, i, res); } // write the additional conformations: res << "CONFS " << mol.getNumConformers() - 1 << "\n"; if (!writeFirstConfTwice) { ++confIt; } while (confIt != mol.endConformers()) { std::stringstream tmpStrm; std::string confName; tmpStrm << "conformer_" << (*confIt)->getId(); confName = tmpStrm.str(); res << "NAME " << confName << "\n"; for (unsigned int i = 0; i < mol.getNumAtoms(); ++i) { const RDGeom::Point3D &pos = (*confIt)->getAtomPos(i); res << " " << 100. * pos.x << " " << 100. * pos.y << " " << 100. * pos.z << "\n"; } ++confIt; if (confIt != mol.endConformers()) { res << "\n"; } } return res.str(); } void MolToTPLFile(const ROMol &mol, const std::string &fName, const std::string &partialChargeProp, bool writeFirstConfTwice) { auto *outStream = new std::ofstream(fName.c_str()); if (!(*outStream) || outStream->bad()) { delete outStream; std::ostringstream errout; errout << "Bad output file " << fName; throw BadFileException(errout.str()); } std::string outString = MolToTPLText(mol, partialChargeProp, writeFirstConfTwice); *outStream << outString; delete outStream; } } // namespace RDKit