mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-03 21:44:30 +08:00
143 lines
4.9 KiB
C++
143 lines
4.9 KiB
C++
//
|
|
// Copyright (C) 2003-2006 Rational Discovery LLC
|
|
//
|
|
// @@ 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 <RDGeneral/Invariant.h>
|
|
|
|
#include "Depictor.h"
|
|
#include <GraphMol/Substruct/SubstructMatch.h>
|
|
#include <RDGeneral/RDLog.h>
|
|
#include <cstdlib>
|
|
namespace RDKit {
|
|
#ifdef WIN32_DLLBUILD
|
|
//*************************************************************************************
|
|
//
|
|
// Uses the Depict DLL to generate a Mol file (on disk) for a
|
|
// SMILES.
|
|
//
|
|
// ARGUMENTS:
|
|
// smi: the SMILES string to be converted
|
|
// fName: the name of the output file
|
|
// dllName: (OPTIONAL) the name of the actual DLL to be opened. The path
|
|
// to the DLL is taken from the environment (see below).
|
|
//
|
|
// RETURNS:
|
|
// 1 on success, 0 otherwise
|
|
//
|
|
// NOTES:
|
|
// - To use the DLL, it's essential that the COMBICHEM_ROOT and
|
|
// COMBICHEM_RELEASE
|
|
// environment variables be set. If this isn't done, this whole process
|
|
// will fail.
|
|
// - The Depict DLL is not re-entrant, which means it can't be used from
|
|
// multiple
|
|
// threads at the same time. We're going to try and minimize this problem
|
|
// by
|
|
// leaving it open for as short a period of time as possible.
|
|
// Still, opening the DLL may fail, in which case we'll return 0 for
|
|
// failure.
|
|
// You can always try again.
|
|
//
|
|
//*************************************************************************************
|
|
int SmilesToMolFileDLL(std::string smi, std::string fName,
|
|
std::string dllName) {
|
|
// std::string dllName="c:/glandrum/dgen/combi/bin/depict32-0.dll";
|
|
const char *root = getenv("COMBICHEM_ROOT");
|
|
const char *release = getenv("COMBICHEM_RELEASE");
|
|
if (!root || !release) {
|
|
BOOST_LOG(rdErrorLog) << "ERROR: COMBICHEM_ROOT and COMBICHEM_RELEASE must "
|
|
"be set to use depictor\n";
|
|
return 0;
|
|
}
|
|
std::string fullName = root;
|
|
fullName += std::string("/") + release;
|
|
fullName += std::string("/bin/") + dllName;
|
|
|
|
Depictor_TwoArgFunc func1;
|
|
HINSTANCE hDLL;
|
|
hDLL = LoadLibrary(fullName.c_str());
|
|
if (!hDLL) {
|
|
BOOST_LOG(rdErrorLog) << "ERROR: could not load depict32.dll\n"
|
|
<< std::endl;
|
|
return 0;
|
|
}
|
|
func1 = (Depictor_TwoArgFunc)GetProcAddress(hDLL, "SMILESSTRINGTOMOLFILE");
|
|
if (!func1) {
|
|
FreeLibrary(hDLL);
|
|
BOOST_LOG(rdErrorLog)
|
|
<< "ERROR: could not find SmilesToMolFile function in DLL\n"
|
|
<< std::endl;
|
|
return 0;
|
|
}
|
|
func1(smi.c_str(), fName.c_str());
|
|
|
|
FreeLibrary(hDLL);
|
|
return 1;
|
|
}
|
|
|
|
//*************************************************************************************
|
|
//
|
|
// Adds 2D coordinates to a molecule using the Depict.dll
|
|
//
|
|
// ARGUMENTS:
|
|
// mol: the molecule to be altered
|
|
// tempFilename: (OPTIONAL) the name of the temporary file
|
|
//
|
|
// RETURNS:
|
|
// 1 on success, 0 otherwise
|
|
//
|
|
// Here's the process by which this works (it's kind of contorted):
|
|
// 1) convert the mol to SMILES
|
|
// 2) use the DLL to convert the SMILES to a mol file (on disk)
|
|
// 3) parse the mol file into a temporary molecule
|
|
// 4) do a substructure match from the old molecule to the
|
|
// temp one (which may have a different atom numbering or additional
|
|
// atoms added).
|
|
// 5) Update the positions of the atoms on the old molecule.
|
|
// 6) Free the temp molecule.
|
|
//
|
|
// NOTES:
|
|
// - *FIX:* at the moment we're not doing anything to clear up the
|
|
// temp file created in this process. It'll always have the same
|
|
// name unless the user explicitly asks that we do something different.
|
|
// - To use the DLL, it's essential that the COMBICHEM_ROOT and
|
|
// COMBICHEM_RELEASE
|
|
// environment variables be set. If this isn't done, this whole process
|
|
// will fail.
|
|
// - See the notes above about failures when opening the DLL.
|
|
//
|
|
//*************************************************************************************
|
|
int Add2DCoordsToMolDLL(ROMol &mol, std::string tempFilename) {
|
|
std::string smi = MolToSmiles(mol, true);
|
|
int tmp = SmilesToMolFileDLL(smi, tempFilename);
|
|
int res = -1;
|
|
if (tmp) {
|
|
// build another mol from that mol file:
|
|
RWMol *tmpMol = MolFileToMol(tempFilename, false);
|
|
// match it up with the starting mol:
|
|
// (We need to do this because the depict.dll conversion
|
|
// to a mol file may have added Hs)
|
|
MatchVectType matchVect;
|
|
bool hasMatch = SubstructMatch(tmpMol, &mol, matchVect);
|
|
if (hasMatch) {
|
|
const Conformer &conf = tmpMol->getCoformer(0);
|
|
Coformer *nconf = new Coformer(mol.getNumAtoms());
|
|
for (MatchVectType::const_iterator mvi = matchVect.begin();
|
|
mvi != matchVect.end(); mvi++) {
|
|
nconf->setAtomPos(conf.getAtomPos(mvi->first));
|
|
}
|
|
confId = (int)mol.addConformer(nconf, true);
|
|
}
|
|
delete tmpMol;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
#endif
|
|
}
|