Files
rdkit/Code/GraphMol/Depictor/Basement/DepictorDLL.cpp
2020-05-04 10:40:57 +02:00

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
}