mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-03 21:44:30 +08:00
merge back in changes from ChemTransforms (r30:51);
the makefile for linux is still missing (I have one, I just need to retrieve it) but otherwise this is in pretty good shape. err, I think so at least.
This commit is contained in:
@@ -82,6 +82,8 @@ namespace RDGeom {
|
||||
.def(python::self -= python::self)
|
||||
.def(python::self + python::self)
|
||||
.def(python::self += python::self)
|
||||
.def(python::self * double())
|
||||
.def(python::self / double())
|
||||
.def("__imul__", &Point3D::operator*=,
|
||||
python::return_value_policy<python::copy_non_const_reference>(),
|
||||
"Scalar multiplication")
|
||||
@@ -120,6 +122,8 @@ namespace RDGeom {
|
||||
.def(python::self -= python::self)
|
||||
.def(python::self + python::self)
|
||||
.def(python::self += python::self)
|
||||
.def(python::self * double())
|
||||
.def(python::self / double())
|
||||
.def("__imul__", &Point2D::operator*=,
|
||||
python::return_value_policy<python::copy_non_const_reference>(),
|
||||
"Scalar multiplication")
|
||||
|
||||
@@ -366,6 +366,25 @@ void Atom::expandQuery(Atom::QUERYATOM_QUERY *what,
|
||||
|
||||
bool Atom::Match(Atom const *what) const {
|
||||
bool res = getAtomicNum() == what->getAtomicNum();
|
||||
// special dummy--dummy match case:
|
||||
// X matches X, Xa, Xb, etc
|
||||
// Xa only matches X and Xa
|
||||
if(res && !getAtomicNum()){
|
||||
std::string l1;
|
||||
if(this->hasProp("dummyLabel")){
|
||||
this->getProp("dummyLabel",l1);
|
||||
} else{
|
||||
l1="X";
|
||||
}
|
||||
if(l1!="X"){
|
||||
std::string l2;
|
||||
if(what->hasProp("dummyLabel")) what->getProp("dummyLabel",l2);
|
||||
else l2="X";
|
||||
if(l2!="X" && l1!=l2){
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
bool Atom::Match(const Atom::ATOM_SPTR what) const {
|
||||
|
||||
183
Code/GraphMol/ChemTransforms/ChemTransforms.cpp
Normal file
183
Code/GraphMol/ChemTransforms/ChemTransforms.cpp
Normal file
@@ -0,0 +1,183 @@
|
||||
// $Id$
|
||||
//
|
||||
// Copyright (C) 2006 Greg Landrum
|
||||
//
|
||||
// @@ All Rights Reserved @@
|
||||
//
|
||||
#include <RDGeneral/utils.h>
|
||||
#include <RDGeneral/Invariant.h>
|
||||
#include <GraphMol/RDKitBase.h>
|
||||
#include <GraphMol/Substruct/SubstructMatch.h>
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
namespace RDKit{
|
||||
|
||||
ROMol *deleteSubstructs(const ROMol &mol, const ROMol &query,
|
||||
bool onlyFrags) {
|
||||
RWMol *res = static_cast<RWMol*>(new ROMol(mol,false));
|
||||
std::vector<MatchVectType> fgpMatches;
|
||||
std::vector<MatchVectType>::const_iterator mati;
|
||||
std::pair<int, int> amat;
|
||||
VECT_INT_VECT matches; // all matches onto the molecule - list of list of atom ids
|
||||
MatchVectType::const_iterator mi;
|
||||
// do the substructure matching and get the atoms that match the query
|
||||
SubstructMatch(*res, query, fgpMatches);
|
||||
|
||||
// if didn't find any matches nothing to be done here
|
||||
// simply return a copy of the molecule
|
||||
if (fgpMatches.size() == 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
for (mati = fgpMatches.begin(); mati != fgpMatches.end(); mati++) {
|
||||
INT_VECT match; // each match onto the molecule - list of atoms ids
|
||||
for (mi = mati->begin(); mi != mati->end(); mi++) {
|
||||
match.push_back(mi->second);
|
||||
}
|
||||
matches.push_back(match);
|
||||
}
|
||||
|
||||
// now loop over the list of matches and check if we can delete any of them
|
||||
INT_VECT delList;
|
||||
|
||||
VECT_INT_VECT_I mxi, fi;
|
||||
if (onlyFrags) {
|
||||
VECT_INT_VECT frags;
|
||||
|
||||
unsigned int nfrags = MolOps::getMolFrags(*res, frags);
|
||||
for (fi = frags.begin(); fi != frags.end(); fi++) {
|
||||
std::sort(fi->begin(), fi->end());
|
||||
for (mxi = matches.begin(); mxi != matches.end(); mxi++) {
|
||||
std::sort(mxi->begin(), mxi->end());
|
||||
if ((*fi) == (*mxi) ) {
|
||||
INT_VECT tmp;
|
||||
Union((*mxi), delList, tmp);
|
||||
delList = tmp;
|
||||
break;
|
||||
} // end of if we found a matching fragment
|
||||
} // endof loop over matches
|
||||
} // end of loop over fragments
|
||||
} // end of if onlyFrags
|
||||
else {
|
||||
// in this case we want to delete any matches we find
|
||||
// simply loop over the matches and collect the atoms that need to
|
||||
// be removed
|
||||
for (mxi = matches.begin(); mxi != matches.end(); mxi++) {
|
||||
INT_VECT tmp;
|
||||
Union((*mxi), delList, tmp);
|
||||
delList = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
// now loop over the union list and delete the atoms
|
||||
// Will do this in the decreasing order of the atomIds
|
||||
// this is so that the AtomIds ids in the "delList" are
|
||||
// not invalidated by a previous removal (removing atom number i changes
|
||||
// the atom indices only atoms with indices >i )
|
||||
std::sort(delList.begin(), delList.end());
|
||||
|
||||
INT_VECT_RI dri;
|
||||
for (dri = delList.rbegin(); dri != delList.rend(); dri++) {
|
||||
res->removeAtom(*dri);
|
||||
}
|
||||
// if we removed any atoms, clear the computed properties:
|
||||
if(delList.size()){
|
||||
res->clearComputedProps(true);
|
||||
// update our properties, but allow unhappiness:
|
||||
res->updatePropertyCache(false);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<ROMOL_SPTR>
|
||||
replaceSubstructs(const ROMol &mol, const ROMol &query,const ROMol &replacement,
|
||||
bool replaceAll) {
|
||||
std::vector<ROMOL_SPTR> res;
|
||||
std::vector<MatchVectType> fgpMatches;
|
||||
|
||||
// do the substructure matching and get the atoms that match the query
|
||||
SubstructMatch(mol, query, fgpMatches);
|
||||
|
||||
// if we didn't find any matches, there's nothing to be done here
|
||||
// simply return a list with a copy of the starting molecule
|
||||
if (fgpMatches.size() == 0) {
|
||||
res.push_back(ROMOL_SPTR(new ROMol(mol,false)));
|
||||
return res;
|
||||
}
|
||||
|
||||
INT_VECT delList;
|
||||
|
||||
// now loop over the list of matches and replace them:
|
||||
for (std::vector<MatchVectType>::const_iterator mati = fgpMatches.begin();
|
||||
mati != fgpMatches.end(); mati++) {
|
||||
INT_VECT match; // each match onto the molecule - list of atoms ids
|
||||
for (MatchVectType::const_iterator mi = mati->begin();
|
||||
mi != mati->end(); mi++) {
|
||||
match.push_back(mi->second);
|
||||
}
|
||||
INT_VECT sortMatch = match;
|
||||
std::sort(sortMatch.begin(),sortMatch.end());
|
||||
|
||||
if( !replaceAll || !res.size() ) {
|
||||
res.push_back(ROMOL_SPTR(new ROMol(mol,false)));
|
||||
}
|
||||
RWMol *newMol = static_cast<RWMol *>(res.rbegin()->get());
|
||||
|
||||
// we need a tab to the orig number of atoms because the
|
||||
// new molecule will start numbered above this:
|
||||
int numOrigAtoms=newMol->getNumAtoms();
|
||||
|
||||
// Add the atoms and bonds from the replacement:
|
||||
newMol->insertMol(replacement);
|
||||
|
||||
// loop over the central atom's (the first atom in match) bonds
|
||||
// and duplicate any that connect to the remainder of the molecule:
|
||||
Atom *origAtom=newMol->getAtomWithIdx(match[0]);
|
||||
ROMol::ADJ_ITER nbrIdx,endNbrs;
|
||||
boost::tie(nbrIdx,endNbrs) = newMol->getAtomNeighbors(origAtom);
|
||||
while(nbrIdx!=endNbrs){
|
||||
// we don't want to duplicate any "intra-match" bonds:
|
||||
if(!std::binary_search(sortMatch.begin(),sortMatch.end(),int(*nbrIdx))){
|
||||
Bond *oBond=newMol->getBondBetweenAtoms(match[0],*nbrIdx);
|
||||
CHECK_INVARIANT(oBond,"required bond not found");
|
||||
newMol->addBond(numOrigAtoms,*nbrIdx,oBond->getBondType());
|
||||
}
|
||||
nbrIdx++;
|
||||
}
|
||||
|
||||
if(replaceAll){
|
||||
// we'll accumulate a list of atoms to be removed:
|
||||
INT_VECT tmp;
|
||||
Union(sortMatch, delList, tmp);
|
||||
delList = tmp;
|
||||
} else {
|
||||
// just delete the atoms now:
|
||||
for (INT_VECT_RI dri = sortMatch.rbegin(); dri != sortMatch.rend(); dri++) {
|
||||
newMol->removeAtom(*dri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(replaceAll){
|
||||
// remove the atoms from the delList:
|
||||
std::sort(delList.begin(),delList.end());
|
||||
RWMol *newMol = static_cast<RWMol *>(res[0].get());
|
||||
for (INT_VECT_RI dri = delList.rbegin(); dri != delList.rend(); dri++) {
|
||||
newMol->removeAtom(*dri);
|
||||
}
|
||||
}
|
||||
|
||||
// clear computed props and do basic updates on the
|
||||
// the resulting molecules, but allow unhappiness:
|
||||
for(std::vector<ROMOL_SPTR>::iterator resI=res.begin();
|
||||
resI!=res.end();resI++){
|
||||
(*resI)->clearComputedProps(true);
|
||||
(*resI)->updatePropertyCache(false);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
72
Code/GraphMol/ChemTransforms/ChemTransforms.h
Normal file
72
Code/GraphMol/ChemTransforms/ChemTransforms.h
Normal file
@@ -0,0 +1,72 @@
|
||||
//
|
||||
// Copyright (C) 2006 Greg Landrum
|
||||
//
|
||||
// @@ All Rights Reserved @@
|
||||
//
|
||||
#ifndef _RD_CHEMTRANSFORMS_H__
|
||||
#define _RD_CHEMTRANSFORMS_H__
|
||||
|
||||
#include <boost/smart_ptr.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace RDKit{
|
||||
class ROMol;
|
||||
typedef boost::shared_ptr<ROMol> ROMOL_SPTR;
|
||||
|
||||
//! \brief Returns a copy of an ROMol with the atoms and bonds that
|
||||
//! match a pattern removed.
|
||||
/*!
|
||||
\param mol the ROMol of interest
|
||||
\param query the query ROMol
|
||||
\param onlyFrags if this is set, only matches that correspond to an
|
||||
entire fragment will be removed. This is useful for
|
||||
salt removal
|
||||
|
||||
\return a copy of \c mol with the matching atoms and bonds (if any)
|
||||
removed.
|
||||
*/
|
||||
ROMol *deleteSubstructs(const ROMol &mol, const ROMol &query,
|
||||
bool replaceAll=false);
|
||||
|
||||
//! \brief Returns a list of copies of an ROMol with the atoms and bonds that
|
||||
//! match a pattern replaced with the atoms contained in another molecule.
|
||||
/*!
|
||||
Bonds are created between the joining atom in the existing molecule
|
||||
and the atoms in the new molecule. So, using SMILES instead of molecules:
|
||||
replaceSubstructs('OC(=O)NCCNC(=O)O','C(=O)O','[X]') ->
|
||||
['[X]NCCNC(=O)O','OC(=O)NCCN[X]']
|
||||
replaceSubstructs('OC(=O)NCCNC(=O)O','C(=O)O','[X]',true) ->
|
||||
['[X]NCCN[X]']
|
||||
Chains should be handled "correctly":
|
||||
replaceSubstructs('CC(=O)C','C(=O)','[X]') ->
|
||||
['C[X]C']
|
||||
As should rings:
|
||||
replaceSubstructs('C1C(=O)C1','C(=O)','[X]') ->
|
||||
['C1[X]C1']
|
||||
And higher order branches:
|
||||
replaceSubstructs('CC(=O)(C)C','C(=O)','[X]') ->
|
||||
['C[X](C)C']
|
||||
Note that the client is responsible for making sure that the
|
||||
resulting molecule actually makes sense - this function does not
|
||||
perform sanitization.
|
||||
|
||||
\param mol the ROMol of interest
|
||||
\param query the query ROMol
|
||||
\param replacement the ROMol to be inserted
|
||||
\param replaceAll if this is true, only a single result, with all occurances
|
||||
of the substructure replaced, will be returned.
|
||||
|
||||
\return a vector of pointers to copies of \c mol with the matching atoms
|
||||
and bonds (if any) replaced
|
||||
|
||||
*/
|
||||
std::vector<ROMOL_SPTR> replaceSubstructs(const ROMol &mol, const ROMol &query,
|
||||
const ROMol &replacement,
|
||||
bool replaceAll=false);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
143
Code/GraphMol/ChemTransforms/ChemTransforms.vcproj
Normal file
143
Code/GraphMol/ChemTransforms/ChemTransforms.vcproj
Normal file
@@ -0,0 +1,143 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="libChemTransforms"
|
||||
SccProjectName=""
|
||||
SccLocalPath="">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\Debug"
|
||||
IntermediateDirectory=".\Debug"
|
||||
ConfigurationType="4"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="$(RDBASE)/Code,$(BOOSTHOME)\include\$(BOOSTBASE),$(RDBASE)/External/vflib-2.0/include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
RuntimeTypeInfo="TRUE"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderFile=".\Debug/ChemTransforms.pch"
|
||||
AssemblerListingLocation=".\Debug/"
|
||||
ObjectFile=".\Debug/"
|
||||
ProgramDataBaseFileName=".\Debug/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile=".\Debug\ChemTransforms.lib"
|
||||
SuppressStartupBanner="TRUE"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\Release"
|
||||
IntermediateDirectory=".\Release"
|
||||
ConfigurationType="4"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="$(RDBASE)/Code,$(BOOSTHOME)\include\$(BOOSTBASE),$(RDBASE)/External/vflib-2.0/include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
RuntimeTypeInfo="TRUE"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderFile=".\Release/ChemTransforms.pch"
|
||||
AssemblerListingLocation=".\Release/"
|
||||
ObjectFile=".\Release/"
|
||||
ProgramDataBaseFileName=".\Release/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile=".\Release\ChemTransforms.lib"
|
||||
SuppressStartupBanner="TRUE"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
|
||||
<File
|
||||
RelativePath=".\ChemTransforms.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl">
|
||||
<File
|
||||
RelativePath="ChemTransforms.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
194
Code/GraphMol/ChemTransforms/testChemTransforms.cpp
Normal file
194
Code/GraphMol/ChemTransforms/testChemTransforms.cpp
Normal file
@@ -0,0 +1,194 @@
|
||||
// $Id$
|
||||
//
|
||||
// Copyright (C) 2006 Greg Landrum
|
||||
//
|
||||
// @@ All Rights Reserved @@
|
||||
//
|
||||
#include <RDGeneral/RDLog.h>
|
||||
#include <GraphMol/RDKitBase.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <GraphMol/SmilesParse/SmilesParse.h>
|
||||
#include <GraphMol/ChemTransforms/ChemTransforms.h>
|
||||
|
||||
using namespace RDKit;
|
||||
|
||||
void testDeleteSubstruct()
|
||||
{
|
||||
int i = 0;
|
||||
ROMol *mol1=0,*mol2=0,*matcher1=0,*matcher2=0,*matcher3=0;
|
||||
std::string smi,sma;
|
||||
|
||||
BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
|
||||
BOOST_LOG(rdInfoLog) << "Testing deleteSubstruct" << std::endl;
|
||||
|
||||
// a lot of the seemingly repetitive stuff is here for Issue96
|
||||
smi = "CCC(=O).C=O";
|
||||
mol1 = SmilesToMol(smi);
|
||||
TEST_ASSERT(mol1);
|
||||
TEST_ASSERT(mol1->getNumAtoms()==6)
|
||||
sma = "C=O";
|
||||
matcher1 = SmartsToMol(sma);
|
||||
TEST_ASSERT(matcher1);
|
||||
|
||||
|
||||
mol2 = deleteSubstructs(*mol1,*matcher1,0);
|
||||
TEST_ASSERT(mol2);
|
||||
TEST_ASSERT(mol2->getNumAtoms()==2)
|
||||
mol2 = deleteSubstructs(*mol2,*matcher1,0);
|
||||
TEST_ASSERT(mol2);
|
||||
TEST_ASSERT(mol2->getNumAtoms()==2)
|
||||
|
||||
delete matcher1;
|
||||
sma = "[Cl;H1&X1,-]";
|
||||
matcher1 = SmartsToMol(sma);
|
||||
sma = "[Na+]";
|
||||
matcher2 = SmartsToMol(sma);
|
||||
sma = "[O;H2,H1&-,X0&-2]";
|
||||
matcher3 = SmartsToMol(sma);
|
||||
delete mol1;
|
||||
mol1 = SmilesToMol("CCO.Cl");
|
||||
TEST_ASSERT(mol1);
|
||||
TEST_ASSERT(mol1->getNumAtoms()==4);
|
||||
|
||||
delete mol2;
|
||||
mol2 = deleteSubstructs(*mol1,*matcher1,true);
|
||||
TEST_ASSERT(mol2);
|
||||
TEST_ASSERT(mol2->getNumAtoms()==3);
|
||||
mol2 = deleteSubstructs(*mol2,*matcher2,true);
|
||||
TEST_ASSERT(mol2);
|
||||
TEST_ASSERT(mol2->getNumAtoms()==3);
|
||||
mol2 = deleteSubstructs(*mol2,*matcher3,true);
|
||||
TEST_ASSERT(mol2);
|
||||
TEST_ASSERT(mol2->getNumAtoms()==3);
|
||||
|
||||
delete mol1;
|
||||
mol1 = SmilesToMol("CC(=O)[O-].[Na+]");
|
||||
TEST_ASSERT(mol1);
|
||||
TEST_ASSERT(mol1->getNumAtoms()==5);
|
||||
|
||||
delete matcher1;
|
||||
matcher1 = SmartsToMol("[Cl;H1&X1,-]");
|
||||
delete matcher2;
|
||||
matcher2 = SmartsToMol("[Na+]");
|
||||
|
||||
mol2 = deleteSubstructs(*mol1,*matcher1,true);
|
||||
TEST_ASSERT(mol2);
|
||||
TEST_ASSERT(mol2->getNumAtoms()==5);
|
||||
|
||||
mol2 = deleteSubstructs(*mol2,*matcher2,true);
|
||||
TEST_ASSERT(mol2);
|
||||
TEST_ASSERT(mol2->getNumAtoms()==4);
|
||||
|
||||
mol2 = deleteSubstructs(*mol2,*matcher1,true);
|
||||
TEST_ASSERT(mol2);
|
||||
TEST_ASSERT(mol2->getNumAtoms()==4);
|
||||
|
||||
BOOST_LOG(rdInfoLog) << "\tdone" << std::endl;
|
||||
}
|
||||
|
||||
void testReplaceSubstructs()
|
||||
{
|
||||
int i = 0;
|
||||
ROMol *mol1=0,*mol2=0,*matcher1=0,*frag=0;
|
||||
std::string smi,sma;
|
||||
std::vector<ROMOL_SPTR> vect;
|
||||
|
||||
|
||||
BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
|
||||
BOOST_LOG(rdInfoLog) << "Testing replaceSubstruct" << std::endl;
|
||||
|
||||
smi = "CCCC";
|
||||
mol1 = SmilesToMol(smi);
|
||||
TEST_ASSERT(mol1);
|
||||
|
||||
sma = "C(=O)O";
|
||||
matcher1 = SmartsToMol(sma);
|
||||
TEST_ASSERT(matcher1);
|
||||
|
||||
smi = "N";
|
||||
frag = SmilesToMol(smi);
|
||||
TEST_ASSERT(frag);
|
||||
|
||||
vect = replaceSubstructs(*mol1,*matcher1,*frag);
|
||||
TEST_ASSERT(vect.size()==1);
|
||||
TEST_ASSERT(mol1->getNumAtoms()==4);
|
||||
TEST_ASSERT(vect[0]->getNumAtoms()==4);
|
||||
|
||||
|
||||
delete mol1;
|
||||
smi = "CCCC(=O)O";
|
||||
mol1 = SmilesToMol(smi);
|
||||
TEST_ASSERT(mol1);
|
||||
vect = replaceSubstructs(*mol1,*matcher1,*frag);
|
||||
TEST_ASSERT(vect.size()==1);
|
||||
TEST_ASSERT(mol1->getNumAtoms()==6);
|
||||
TEST_ASSERT(vect[0]->getNumAtoms()==4);
|
||||
|
||||
vect = replaceSubstructs(*mol1,*matcher1,*frag,true);
|
||||
TEST_ASSERT(vect.size()==1);
|
||||
TEST_ASSERT(mol1->getNumAtoms()==6);
|
||||
TEST_ASSERT(vect[0]->getNumAtoms()==4);
|
||||
|
||||
delete mol1;
|
||||
smi = "OC(=O)CCCC(=O)O";
|
||||
mol1 = SmilesToMol(smi);
|
||||
TEST_ASSERT(mol1);
|
||||
vect = replaceSubstructs(*mol1,*matcher1,*frag);
|
||||
TEST_ASSERT(vect.size()==2);
|
||||
TEST_ASSERT(mol1->getNumAtoms()==9);
|
||||
TEST_ASSERT(vect[0]->getNumAtoms()==7);
|
||||
TEST_ASSERT(vect[1]->getNumAtoms()==7);
|
||||
|
||||
// use replaceAll when a single replacement is available:
|
||||
vect = replaceSubstructs(*mol1,*matcher1,*frag,true);
|
||||
TEST_ASSERT(vect.size()==1);
|
||||
TEST_ASSERT(mol1->getNumAtoms()==9);
|
||||
TEST_ASSERT(vect[0]->getNumAtoms()==5);
|
||||
|
||||
delete matcher1;
|
||||
sma = "C=O";
|
||||
matcher1 = SmartsToMol(sma);
|
||||
TEST_ASSERT(matcher1);
|
||||
|
||||
delete mol1;
|
||||
smi = "CC(=O)C";
|
||||
mol1 = SmilesToMol(smi);
|
||||
TEST_ASSERT(mol1);
|
||||
vect = replaceSubstructs(*mol1,*matcher1,*frag);
|
||||
TEST_ASSERT(vect.size()==1);
|
||||
TEST_ASSERT(mol1->getNumAtoms()==4);
|
||||
TEST_ASSERT(vect[0]->getNumAtoms()==3);
|
||||
|
||||
delete mol1;
|
||||
smi = "C1C(=O)C1";
|
||||
mol1 = SmilesToMol(smi);
|
||||
TEST_ASSERT(mol1);
|
||||
vect = replaceSubstructs(*mol1,*matcher1,*frag);
|
||||
TEST_ASSERT(vect.size()==1);
|
||||
TEST_ASSERT(mol1->getNumAtoms()==4);
|
||||
TEST_ASSERT(vect[0]->getNumAtoms()==3);
|
||||
TEST_ASSERT(vect[0]->getNumBonds()==3);
|
||||
|
||||
|
||||
BOOST_LOG(rdInfoLog) << "\tdone" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int main() {
|
||||
RDLog::InitLogs();
|
||||
|
||||
BOOST_LOG(rdInfoLog) << "********************************************************\n";
|
||||
BOOST_LOG(rdInfoLog) << "Testing Chemical Transforms \n";
|
||||
|
||||
#if 1
|
||||
testDeleteSubstruct();
|
||||
testReplaceSubstructs();
|
||||
#endif
|
||||
|
||||
BOOST_LOG(rdInfoLog) << "*******************************************************\n";
|
||||
return(0);
|
||||
}
|
||||
|
||||
156
Code/GraphMol/ChemTransforms/testChemTransforms.vcproj
Normal file
156
Code/GraphMol/ChemTransforms/testChemTransforms.vcproj
Normal file
@@ -0,0 +1,156 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="testChemTransforms"
|
||||
ProjectGUID="{5408B0E6-0B50-4E12-921A-8F1B3E483716}"
|
||||
SccProjectName=""
|
||||
SccLocalPath="">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\testExecs"
|
||||
IntermediateDirectory=".\Debug"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="$(BOOSTHOME)/include/$(BOOSTBASE),$(RDBASE)/Code"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\Debug/testChemTransforms.pch"
|
||||
AssemblerListingLocation=".\Debug/"
|
||||
ObjectFile=".\Debug/"
|
||||
ProgramDataBaseFileName=".\Debug/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="boost_log-vc71-mt-gd-$(BOOSTVERSION).lib"
|
||||
OutputFile="./testExecs/main.exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="$(BOOSTHOME)\lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\Debug/test.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName=".\Debug/testChemTransforms.tlb"
|
||||
HeaderFileName=""/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\testExecs\"
|
||||
IntermediateDirectory=".\Release"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="$(BOOSTHOME)/include/$(BOOSTBASE),$(RDBASE)/Code"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
PrecompiledHeaderFile=".\Release/testChemTransforms.pch"
|
||||
AssemblerListingLocation=".\Release/"
|
||||
ObjectFile=".\Release/"
|
||||
ProgramDataBaseFileName=".\Release/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="boost_log-vc71-mt-$(BOOSTVERSION).lib"
|
||||
OutputFile="./testExecs/main.exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="$(BOOSTHOME)\lib"
|
||||
ProgramDatabaseFile=".\Release/test.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName=".\Release/testChemTransforms.tlb"
|
||||
HeaderFileName=""/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
|
||||
<File
|
||||
RelativePath=".\testChemTransforms.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl">
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
14
Code/GraphMol/ChemTransforms/test_list.py
Normal file
14
Code/GraphMol/ChemTransforms/test_list.py
Normal file
@@ -0,0 +1,14 @@
|
||||
import sys
|
||||
|
||||
tests=[
|
||||
("testExecs/main.exe","",{}),
|
||||
]
|
||||
|
||||
longTests=[
|
||||
]
|
||||
|
||||
if __name__=='__main__':
|
||||
import sys
|
||||
import TestRunner
|
||||
failed,tests = TestRunner.RunScript('test_list.py',0,1)
|
||||
sys.exit(len(failed))
|
||||
@@ -197,7 +197,8 @@ namespace RDKit{
|
||||
//double pX,pY,pZ;
|
||||
std::string symb;
|
||||
int massDiff,chg,hCount;
|
||||
//int rxnComponentType,rxnComponentNumber,atomMapNumber,inversionFlag,exactChangeFlag;
|
||||
int stereoCare,totValence;
|
||||
int atomMapNumber,inversionFlag,exactChangeFlag;
|
||||
|
||||
try {
|
||||
pos.x = stripSpacesAndCast<double>(text.substr(0,10));
|
||||
@@ -250,6 +251,18 @@ namespace RDKit{
|
||||
if(symb=="L" || symb=="A" || symb=="Q" || symb=="*" || symb=="LP"
|
||||
|| (symb>="R0" && symb<="R9") ){
|
||||
res->setAtomicNum(0);
|
||||
if(symb=="*") res->setProp("dummyLabel",std::string("X"));
|
||||
else if(symb=="R0") res->setProp("dummyLabel",std::string("Xa"));
|
||||
else if(symb=="R1") res->setProp("dummyLabel",std::string("Xb"));
|
||||
else if(symb=="R2") res->setProp("dummyLabel",std::string("Xc"));
|
||||
else if(symb=="R3") res->setProp("dummyLabel",std::string("Xd"));
|
||||
else if(symb=="R4") res->setProp("dummyLabel",std::string("Xe"));
|
||||
else if(symb=="R5") res->setProp("dummyLabel",std::string("Xf"));
|
||||
else if(symb=="R6") res->setProp("dummyLabel",std::string("Xg"));
|
||||
else if(symb=="R7") res->setProp("dummyLabel",std::string("Xh"));
|
||||
else if(symb=="R8") res->setProp("dummyLabel",std::string("Xi"));
|
||||
else if(symb=="R9") res->setProp("dummyLabel",std::string("Xj"));
|
||||
else res->setProp("dummyLabel",symb);
|
||||
} else {
|
||||
res->setAtomicNum(PeriodicTable::getTable()->getAtomicNumber(symb));
|
||||
res->setMass(PeriodicTable::getTable()->getAtomicWeight(res->getAtomicNum()));
|
||||
@@ -264,7 +277,7 @@ namespace RDKit{
|
||||
res->setMass(res->getMass()+massDiff);
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
stereoCare=0;
|
||||
if(text.size()>=48){
|
||||
try {
|
||||
@@ -287,28 +300,6 @@ namespace RDKit{
|
||||
throw FileParseException(errout.str()) ;
|
||||
}
|
||||
}
|
||||
rxnComponentType=0;
|
||||
if(text.size()>=57){
|
||||
try {
|
||||
rxnComponentType= stripSpacesAndCast<int>(text.substr(54,3));
|
||||
}
|
||||
catch (boost::bad_lexical_cast &) {
|
||||
std::ostringstream errout;
|
||||
errout << "Cannot convert " << text.substr(54,3) << " to int";
|
||||
throw FileParseException(errout.str()) ;
|
||||
}
|
||||
}
|
||||
rxnComponentNumber=0;
|
||||
if(text.size()>=60){
|
||||
try {
|
||||
rxnComponentNumber= stripSpacesAndCast<int>(text.substr(57,3));
|
||||
}
|
||||
catch (boost::bad_lexical_cast &) {
|
||||
std::ostringstream errout;
|
||||
errout << "Cannot convert " << text.substr(57,3) << " to int";
|
||||
throw FileParseException(errout.str()) ;
|
||||
}
|
||||
}
|
||||
atomMapNumber=0;
|
||||
if(text.size()>=63){
|
||||
try {
|
||||
@@ -345,13 +336,11 @@ namespace RDKit{
|
||||
|
||||
|
||||
// save it for later
|
||||
res->setProp("stereoCare",stereoCare);
|
||||
res->setProp("totValence",totValence);
|
||||
res->setProp("rxnComponentType",rxnComponentType);
|
||||
res->setProp("rxnComponentNumber",rxnComponentNumber);
|
||||
res->setProp("atomMapNumber",atomMapNumber);
|
||||
res->setProp("inversionFlag",inversionFlag);
|
||||
res->setProp("exactChangeFlag",exactChangeFlag);
|
||||
res->setProp("molStereoCare",stereoCare);
|
||||
res->setProp("molTotValence",totValence);
|
||||
res->setProp("molAtomMapNumber",atomMapNumber);
|
||||
res->setProp("molInversionFlag",inversionFlag);
|
||||
res->setProp("molExactChangeFlag",exactChangeFlag);
|
||||
#endif
|
||||
return res;
|
||||
};
|
||||
@@ -442,19 +431,19 @@ namespace RDKit{
|
||||
} catch (boost::bad_lexical_cast) {
|
||||
;
|
||||
}
|
||||
#if 0
|
||||
#if 1
|
||||
if( text.size() >= 18 )
|
||||
try {
|
||||
topology = stripSpacesAndCast<int>(text.substr(15,3));
|
||||
res->setProp("topology",topology);
|
||||
int topology = stripSpacesAndCast<int>(text.substr(15,3));
|
||||
res->setProp("molTopology",topology);
|
||||
} catch (boost::bad_lexical_cast) {
|
||||
;
|
||||
}
|
||||
|
||||
if( text.size() >= 21 )
|
||||
try {
|
||||
reactStatus = stripSpacesAndCast<int>(text.substr(18,3));
|
||||
res->setProp("reactStatus",reactStatus);
|
||||
int reactStatus = stripSpacesAndCast<int>(text.substr(18,3));
|
||||
res->setProp("molReactStatus",reactStatus);
|
||||
} catch (boost::bad_lexical_cast) {
|
||||
;
|
||||
}
|
||||
|
||||
@@ -509,7 +509,8 @@ ATOM_EQUALS_QUERY *makeAtomInRingQuery(){
|
||||
}
|
||||
|
||||
ATOM_EQUALS_QUERY *makeAtomInNRingsQuery(int what){
|
||||
ATOM_EQUALS_QUERY *res= makeAtomSimpleQuery(what,queryIsAtomInNRings);
|
||||
ATOM_EQUALS_QUERY *res;
|
||||
res = makeAtomSimpleQuery(what,queryIsAtomInNRings);
|
||||
res->setDescription("AtomInNRings");
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -79,7 +79,53 @@ namespace RDKit{
|
||||
//! returns a Query for matching any atom
|
||||
ATOM_NULL_QUERY *makeAtomNullQuery();
|
||||
|
||||
static int queryAtomRingMembership(Atom const *at) {
|
||||
return static_cast<int>(at->getOwningMol().getRingInfo()->numAtomRings(at->getIdx()));
|
||||
}
|
||||
|
||||
// I'm pretty sure that this typedef shouldn't be necessary,
|
||||
// but VC++ generates a warning about const Atom const * in
|
||||
// the definition of Match, then complains about an override
|
||||
// that differs only by const/volatile (c4301), then generates
|
||||
// incorrect code if we don't do this... so let's do it.
|
||||
typedef Atom const *ConstAtomPtr;
|
||||
class InRingQuery : public Queries::EqualityQuery<int, ConstAtomPtr,true> {
|
||||
public:
|
||||
InRingQuery() : Queries::EqualityQuery<int,ConstAtomPtr,true>(-1) {
|
||||
this->setDescription("AtomInNRings");
|
||||
this->setDataFunc(queryAtomRingMembership);
|
||||
};
|
||||
explicit InRingQuery(int v) : Queries::EqualityQuery<int,ConstAtomPtr,true>(v) {
|
||||
this->setDescription("AtomInNRings");
|
||||
this->setDataFunc(queryAtomRingMembership);
|
||||
};
|
||||
|
||||
virtual bool Match(const ConstAtomPtr what) const {
|
||||
int v = this->TypeConvert(what,Queries::Int2Type<true>());
|
||||
bool res;
|
||||
if(this->d_val<0){
|
||||
res = v!=0;
|
||||
} else {
|
||||
res=!Queries::queryCmp(v,this->d_val,this->d_tol);
|
||||
}
|
||||
if(this->getNegation()){
|
||||
res=!res;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//! returns a copy of this query
|
||||
Queries::Query<int,ConstAtomPtr,true> *
|
||||
copy() const {
|
||||
InRingQuery *res =
|
||||
new InRingQuery(this->d_val);
|
||||
res->setNegation(getNegation());
|
||||
res->setTol(this->getTol());
|
||||
res->d_description = this->d_description;
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
//! allows use of recursive structure queries (e.g. recursive SMARTS)
|
||||
class RecursiveStructureQuery : public Queries::SetQuery<int,Atom const *,true> {
|
||||
public:
|
||||
|
||||
@@ -294,7 +294,7 @@ namespace RDKit{
|
||||
... atomPtr is a const Atom * ...
|
||||
ROMol::OEDGE_ITER beg,end;
|
||||
ROMol::GRAPH_MOL_BOND_PMAP::const_type pMap = molPtr->getBondPMap();
|
||||
boost::tie(beg,end) = molPtr->getAtomNeighbors(atomPtr);
|
||||
boost::tie(beg,end) = molPtr->getAtomBonds(atomPtr);
|
||||
while(beg!=end){
|
||||
const Bond *bond=pMap[*beg];
|
||||
... do something with the Bond ...
|
||||
@@ -307,7 +307,7 @@ namespace RDKit{
|
||||
... atomPtr is a const Atom * ...
|
||||
ROMol::OEDGE_ITER beg,end;
|
||||
ROMol::GRAPH_MOL_BOND_PMAP::type pMap = molPtr->getBondPMap();
|
||||
boost::tie(beg,end) = molPtr->getAtomNeighbors(atomPtr);
|
||||
boost::tie(beg,end) = molPtr->getAtomBonds(atomPtr);
|
||||
while(beg!=end){
|
||||
Bond *bond=pMap[*beg];
|
||||
... do something with the Bond ...
|
||||
|
||||
@@ -150,7 +150,10 @@ namespace RDKit {
|
||||
needParen = true;
|
||||
}
|
||||
else if (descrip == "AtomInNRings") {
|
||||
res << "R" << query->getVal();
|
||||
res << "R";
|
||||
if(query->getVal()>=0){
|
||||
res << query->getVal();
|
||||
}
|
||||
needParen = true;
|
||||
}
|
||||
else if (descrip == "AtomFormalCharge") {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// @@ All Rights Reserved @@
|
||||
//
|
||||
#include <GraphMol/RDKitBase.h>
|
||||
#include <GraphMol/RDKitQueries.h>
|
||||
#include "SmilesParse.h"
|
||||
#include "SmilesParseOps.h"
|
||||
#include <list>
|
||||
@@ -28,7 +29,7 @@ namespace SmilesParseOps{
|
||||
// between the fragment and the molecule
|
||||
//
|
||||
void AddFragToMol(RWMol *mol,RWMol *frag,Bond::BondType bondOrder,
|
||||
Bond::BondDir bondDir,bool closeRings ){
|
||||
Bond::BondDir bondDir,bool closeRings,bool doingQuery ){
|
||||
RWMol::GRAPH_NODE_TYPE lastAt = mol->getActiveAtom();
|
||||
int nOrigAtoms = mol->getNumAtoms();
|
||||
int nOrigBonds = mol->getNumBonds();
|
||||
@@ -84,28 +85,56 @@ namespace SmilesParseOps{
|
||||
leadingBond->setEndAtomIdx(atomIdx1);
|
||||
mol->addBond(leadingBond,true);
|
||||
} else {
|
||||
if(bondOrder == Bond::UNSPECIFIED){
|
||||
// no bond order provided, figure it out ourselves
|
||||
if(lastAt->getIsAromatic() && firstAt->getIsAromatic() ){
|
||||
bo = Bond::AROMATIC;
|
||||
if(!doingQuery){
|
||||
if(bondOrder == Bond::UNSPECIFIED){
|
||||
// no bond order provided, figure it out ourselves
|
||||
if(lastAt->getIsAromatic() && firstAt->getIsAromatic() ){
|
||||
bo = Bond::AROMATIC;
|
||||
}
|
||||
else{
|
||||
bo = Bond::SINGLE;
|
||||
}
|
||||
}
|
||||
else{
|
||||
bo = Bond::SINGLE;
|
||||
bo = bondOrder;
|
||||
}
|
||||
if(bo==Bond::DATIVEL){
|
||||
int tmp=atomIdx2;
|
||||
atomIdx2 = atomIdx1;
|
||||
atomIdx1 = tmp;
|
||||
bo = Bond::DATIVE;
|
||||
} else if(bo == Bond::DATIVER){
|
||||
bo = Bond::DATIVE;
|
||||
}
|
||||
int idx = mol->addBond(atomIdx2,atomIdx1,bo)-1;
|
||||
mol->getBondWithIdx(idx)->setBondDir(bondDir);
|
||||
} else {
|
||||
// semantics are different in SMARTS, unspecified bonds can be single or aromatic:
|
||||
if(bondOrder == Bond::UNSPECIFIED){
|
||||
QueryBond *newB=new QueryBond(Bond::SINGLE);
|
||||
newB->expandQuery(makeBondOrderEqualsQuery(Bond::AROMATIC),
|
||||
Queries::COMPOSITE_OR,
|
||||
true);
|
||||
newB->setOwningMol(mol);
|
||||
newB->setBeginAtomIdx(atomIdx1);
|
||||
newB->setEndAtomIdx(atomIdx2);
|
||||
mol->addBond(newB);
|
||||
delete newB;
|
||||
}
|
||||
else{
|
||||
bo=bondOrder;
|
||||
if(bo==Bond::DATIVEL){
|
||||
int tmp=atomIdx2;
|
||||
atomIdx2 = atomIdx1;
|
||||
atomIdx1 = tmp;
|
||||
bo = Bond::DATIVE;
|
||||
} else if(bo == Bond::DATIVER){
|
||||
bo = Bond::DATIVE;
|
||||
}
|
||||
int idx = mol->addBond(atomIdx2,atomIdx1,bo)-1;
|
||||
mol->getBondWithIdx(idx)->setBondDir(bondDir);
|
||||
}
|
||||
}
|
||||
else{
|
||||
bo = bondOrder;
|
||||
}
|
||||
if(bo==Bond::DATIVEL){
|
||||
int tmp=atomIdx2;
|
||||
atomIdx2 = atomIdx1;
|
||||
atomIdx1 = tmp;
|
||||
bo = Bond::DATIVE;
|
||||
} else if(bo == Bond::DATIVER){
|
||||
bo = Bond::DATIVE;
|
||||
}
|
||||
int idx = mol->addBond(atomIdx2,atomIdx1,bo)-1;
|
||||
mol->getBondWithIdx(idx)->setBondDir(bondDir);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace SmilesParseOps {
|
||||
void AddFragToMol(RDKit::RWMol *mol,RDKit::RWMol *frag,
|
||||
RDKit::Bond::BondType bondOrder=RDKit::Bond::UNSPECIFIED,
|
||||
RDKit::Bond::BondDir bondDir=RDKit::Bond::NONE,
|
||||
bool closeRings=false);
|
||||
bool closeRings=false,bool doingQuery=false);
|
||||
RDKit::Bond::BondType GetUnspecifiedBondType(const RDKit::RWMol *mol,
|
||||
const RDKit::Atom *atom1,
|
||||
const RDKit::Atom *atom2);
|
||||
|
||||
@@ -300,7 +300,9 @@ namespace RDKit{
|
||||
// decisions and I'm gonna want to smack myself for doing this,
|
||||
// but we'll try anyway.
|
||||
std::string MolToSmiles(ROMol &mol,bool doIsomericSmiles,
|
||||
bool doKekule){
|
||||
bool doKekule,int rootedAtAtom){
|
||||
PRECONDITION(rootedAtAtom<0||static_cast<unsigned int>(rootedAtAtom)<mol.getNumAtoms(),
|
||||
"rootedAtomAtom must be less than the number of atoms");
|
||||
if(doIsomericSmiles){
|
||||
mol.setProp("_doIsoSmiles",1);
|
||||
} else if(mol.hasProp("_doIsoSmiles")){
|
||||
@@ -315,18 +317,17 @@ namespace RDKit{
|
||||
#endif
|
||||
std::string res;
|
||||
|
||||
int nAtoms=mol.getNumAtoms();
|
||||
for(ROMol::AtomIterator atIt=mol.beginAtoms();atIt!=mol.endAtoms();atIt++)
|
||||
for(ROMol::AtomIterator atIt=mol.beginAtoms();atIt!=mol.endAtoms();atIt++){
|
||||
(*atIt)->updatePropertyCache();
|
||||
}
|
||||
|
||||
INT_VECT ranks;
|
||||
ranks.resize(nAtoms);
|
||||
unsigned int nAtoms=mol.getNumAtoms();
|
||||
INT_VECT ranks(nAtoms,-1);
|
||||
|
||||
// clean up the chirality on any atom that is marked as chiral,
|
||||
// but that should not be:
|
||||
if(doIsomericSmiles){
|
||||
MolOps::assignAtomChiralCodes(mol,true);
|
||||
//MolOps::assignBondStereoCodes(mol,true);
|
||||
MolOps::rankAtoms(mol,ranks,ComprehensiveInvariants,
|
||||
true,0,true);
|
||||
} else {
|
||||
@@ -343,14 +344,20 @@ namespace RDKit{
|
||||
colorIt = colors.begin();
|
||||
// loop to deal with the possibility that there might be disconnected fragments
|
||||
while(colorIt != colors.end()){
|
||||
int i,nextAtomIdx,nextRank;
|
||||
int nextAtomIdx;
|
||||
std::string subSmi;
|
||||
|
||||
// find the next atom for a traverse
|
||||
nextRank = nAtoms+1;
|
||||
for(i=0;i<nAtoms;i++){
|
||||
if( colors[i] == Canon::WHITE_NODE && ranks[i] < nextRank ){
|
||||
nextRank = ranks[i];
|
||||
nextAtomIdx = i;
|
||||
if(rootedAtAtom>=0){
|
||||
nextAtomIdx=rootedAtAtom;
|
||||
rootedAtAtom=-1;
|
||||
} else {
|
||||
int nextRank = nAtoms+1;
|
||||
for(unsigned int i=0;i<nAtoms;i++){
|
||||
if( colors[i] == Canon::WHITE_NODE && ranks[i] < nextRank ){
|
||||
nextRank = ranks[i];
|
||||
nextAtomIdx = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,6 @@ namespace SmilesWrite {
|
||||
|
||||
namespace RDKit{
|
||||
std::string MolToSmiles(ROMol &mol,bool doIsomericSmiles=false,
|
||||
bool doKekule=false);
|
||||
bool doKekule=false,int rootedAtAtom=-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -160,14 +160,12 @@ using namespace RDKit;
|
||||
}
|
||||
<IN_ATOM_STATE>R {
|
||||
yysmarts_lval.atom = new QueryAtom();
|
||||
// FIX: this doesn't default properly
|
||||
yysmarts_lval.atom->setQuery(makeAtomInNRingsQuery(1));
|
||||
yysmarts_lval.atom->setQuery(new InRingQuery(-1));
|
||||
return COMPLEX_ATOM_QUERY_TOKEN;
|
||||
}
|
||||
<IN_ATOM_STATE>r {
|
||||
yysmarts_lval.atom = new QueryAtom();
|
||||
// FIX: this doesn't default properly
|
||||
yysmarts_lval.atom->setQuery(makeAtomInRingOfSizeQuery(3));
|
||||
yysmarts_lval.atom->setQuery(makeAtomInRingQuery());
|
||||
return RINGSIZE_ATOM_QUERY_TOKEN;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ static RWMol * curMol_gps = 0;
|
||||
%left SEMI_TOKEN
|
||||
%left OR_TOKEN
|
||||
%left AND_TOKEN
|
||||
%nonassoc NOT_TOKEN
|
||||
%right NOT_TOKEN
|
||||
|
||||
%%
|
||||
|
||||
@@ -190,7 +190,7 @@ mol: atomd {
|
||||
| mol branch {
|
||||
RWMol *m1_p = molList_g[$$],*m2_p=molList_g[$2];
|
||||
// FIX: handle generic bonds here
|
||||
SmilesParseOps::AddFragToMol(m1_p,m2_p,Bond::UNSPECIFIED,Bond::NONE,false);
|
||||
SmilesParseOps::AddFragToMol(m1_p,m2_p,Bond::UNSPECIFIED,Bond::NONE,false,true);
|
||||
delete m2_p;
|
||||
int sz = molList_g.size();
|
||||
if ( sz==$2+1) {
|
||||
|
||||
@@ -133,6 +133,8 @@ std::vector< MatchVectType > _checkMatches(std::string smarts, std::string smile
|
||||
|
||||
matcher = SmartsToMol(smarts);
|
||||
CHECK_INVARIANT(matcher,smarts);
|
||||
|
||||
//std::cerr << "\tSMA: " << smarts << " -> " << MolToSmarts(*matcher) << std::endl;;
|
||||
|
||||
mol = SmilesToMol(smiles);
|
||||
CHECK_INVARIANT(mol,smiles);
|
||||
@@ -240,17 +242,45 @@ void testMatches3(){
|
||||
|
||||
_checkMatches("[CH3][CH]", "C(C)(C)CC(=O)[O-]", 2, 2);
|
||||
|
||||
_checkMatches("[!C;R]", "c1ccccc1", 6, 1);
|
||||
|
||||
_checkMatches("[!C;R]", "C1COC1", 1, 1);
|
||||
|
||||
_checkMatches("[c;H]", "c1ccccc1", 6, 1);
|
||||
_checkNoMatches("[c;H]", "C1CCCCC1");
|
||||
|
||||
_checkMatches("[#6]([#7])[#6]", "c1ncccc1", 2, 3);
|
||||
|
||||
_checkMatches("[c;H]", "c1c[c-]ccc1", 5, 1);
|
||||
|
||||
_checkMatches("C~O", "C(=O)[O-]", 2, 2);
|
||||
|
||||
|
||||
// -----
|
||||
// This block is connected to SF-Issue 1538280
|
||||
// http://sourceforge.net/tracker/index.php?func=detail&aid=1538280&group_id=160139&atid=814650
|
||||
_checkMatches("[R]", "c1ccccc1", 6, 1);
|
||||
|
||||
_checkMatches("[r]", "c1ccccc1", 6, 1);
|
||||
|
||||
_checkMatches("[R;!O]", "c1ccccc1", 6, 1);
|
||||
|
||||
_checkMatches("[c]", "c1ccccc1", 6, 1);
|
||||
|
||||
_checkMatches("[R;c]", "c1ccccc1", 6, 1);
|
||||
|
||||
_checkMatches("[c;#6]", "c1ccccc1", 6, 1);
|
||||
|
||||
_checkMatches("[R;R]", "c1ccccc1", 6, 1);
|
||||
|
||||
_checkMatches("[#6;R]", "c1ccccc1", 6, 1);
|
||||
|
||||
_checkMatches("[c;R]", "c1ccccc1", 6, 1);
|
||||
|
||||
_checkMatches("[!O;R]", "c1ccccc1", 6, 1);
|
||||
|
||||
_checkMatches("[!C;R]", "c1ccccc1", 6, 1);
|
||||
|
||||
_checkMatches("[!C;R]", "C1COC1", 1, 1);
|
||||
|
||||
|
||||
|
||||
BOOST_LOG(rdInfoLog) << "\tdone" << std::endl;
|
||||
}
|
||||
|
||||
@@ -613,77 +643,6 @@ void testSmartsWrite() {
|
||||
}
|
||||
|
||||
|
||||
void testDeleteSubstruct()
|
||||
{
|
||||
int i = 0;
|
||||
ROMol *mol1=0,*mol2=0,*matcher1=0,*matcher2=0,*matcher3=0;
|
||||
std::string smi,sma;
|
||||
|
||||
BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
|
||||
BOOST_LOG(rdInfoLog) << "Testing deleteSubstruct" << std::endl;
|
||||
|
||||
// a lot of the seemingly repetitive stuff is here for Issue96
|
||||
smi = "CCC(=O).C=O";
|
||||
mol1 = SmilesToMol(smi);
|
||||
TEST_ASSERT(mol1);
|
||||
sma = "C=O";
|
||||
matcher1 = SmartsToMol(sma);
|
||||
TEST_ASSERT(matcher1);
|
||||
|
||||
mol2 = deleteSubstructs(*mol1,*matcher1,0);
|
||||
TEST_ASSERT(mol2);
|
||||
TEST_ASSERT(mol2->getNumAtoms(4))
|
||||
mol2 = deleteSubstructs(*mol2,*matcher1,0);
|
||||
TEST_ASSERT(mol2);
|
||||
TEST_ASSERT(mol2->getNumAtoms(4))
|
||||
|
||||
delete matcher1;
|
||||
sma = "[Cl;H1&X1,-]";
|
||||
matcher1 = SmartsToMol(sma);
|
||||
sma = "[Na+]";
|
||||
matcher2 = SmartsToMol(sma);
|
||||
sma = "[O;H2,H1&-,X0&-2]";
|
||||
matcher3 = SmartsToMol(sma);
|
||||
delete mol1;
|
||||
mol1 = SmilesToMol("CCO.Cl");
|
||||
TEST_ASSERT(mol1);
|
||||
TEST_ASSERT(mol1->getNumAtoms()==4);
|
||||
|
||||
delete mol2;
|
||||
mol2 = deleteSubstructs(*mol1,*matcher1,true);
|
||||
TEST_ASSERT(mol2);
|
||||
TEST_ASSERT(mol2->getNumAtoms()==3);
|
||||
mol2 = deleteSubstructs(*mol2,*matcher2,true);
|
||||
TEST_ASSERT(mol2);
|
||||
TEST_ASSERT(mol2->getNumAtoms()==3);
|
||||
mol2 = deleteSubstructs(*mol2,*matcher3,true);
|
||||
TEST_ASSERT(mol2);
|
||||
TEST_ASSERT(mol2->getNumAtoms()==3);
|
||||
|
||||
delete mol1;
|
||||
mol1 = SmilesToMol("CC(=O)[O-].[Na+]");
|
||||
TEST_ASSERT(mol1);
|
||||
TEST_ASSERT(mol1->getNumAtoms()==5);
|
||||
|
||||
delete matcher1;
|
||||
matcher1 = SmartsToMol("[Cl;H1&X1,-]");
|
||||
delete matcher2;
|
||||
matcher2 = SmartsToMol("[Na+]");
|
||||
|
||||
mol2 = deleteSubstructs(*mol1,*matcher1,true);
|
||||
TEST_ASSERT(mol2);
|
||||
TEST_ASSERT(mol2->getNumAtoms()==5);
|
||||
|
||||
mol2 = deleteSubstructs(*mol2,*matcher2,true);
|
||||
TEST_ASSERT(mol2);
|
||||
TEST_ASSERT(mol2->getNumAtoms()==4);
|
||||
|
||||
mol2 = deleteSubstructs(*mol2,*matcher1,true);
|
||||
TEST_ASSERT(mol2);
|
||||
TEST_ASSERT(mol2->getNumAtoms()==4);
|
||||
|
||||
BOOST_LOG(rdInfoLog) << "\tdone" << std::endl;
|
||||
}
|
||||
|
||||
void testIssue196()
|
||||
{
|
||||
@@ -864,7 +823,7 @@ int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
RDLog::InitLogs();
|
||||
#if LOCAL_TEST_ALL
|
||||
#if 1
|
||||
testPass();
|
||||
testFail();
|
||||
testMatches();
|
||||
@@ -876,12 +835,12 @@ main(int argc, char *argv[])
|
||||
testSmartsWrite();
|
||||
testFrags();
|
||||
testProblems();
|
||||
testDeleteSubstruct();
|
||||
testIssue196();
|
||||
testIssue254();
|
||||
testIssue255();
|
||||
testIssue330();
|
||||
#endif
|
||||
testIssue351();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1231,6 +1231,28 @@ void testIssue266(){
|
||||
BOOST_LOG(rdInfoLog) << "\tdone" << std::endl;
|
||||
}
|
||||
|
||||
void testRootedAt(){
|
||||
RWMol *mol;
|
||||
std::string smi;
|
||||
int numE=0;
|
||||
|
||||
BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
|
||||
BOOST_LOG(rdInfoLog) << "Testing rootedAtAtom functionality" << std::endl;
|
||||
|
||||
smi ="CN(C)C";
|
||||
mol = SmilesToMol(smi);
|
||||
TEST_ASSERT(mol);
|
||||
smi = MolToSmiles(*mol,false,false,-1);
|
||||
TEST_ASSERT(smi=="CN(C)C");
|
||||
smi = MolToSmiles(*mol,false,false,1);
|
||||
TEST_ASSERT(smi=="N(C)(C)C");
|
||||
smi = MolToSmiles(*mol,false,false,2);
|
||||
TEST_ASSERT(smi=="CN(C)C");
|
||||
|
||||
|
||||
BOOST_LOG(rdInfoLog) << "\tdone" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
@@ -1257,6 +1279,7 @@ main(int argc, char *argv[])
|
||||
testIssue184();
|
||||
testIssue191();
|
||||
testIssue256();
|
||||
#endif
|
||||
testIssue266();
|
||||
#endif
|
||||
testRootedAt();
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testQuery", "Query\QueryTes
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testSmartsParse", "GraphMol\SmilesParse\SmartsParseTest.vcproj", "{1F0176D6-8882-4399-B8AF-E75B8287A591}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{676E091A-4E6E-429B-91EE-0399C46060C6} = {676E091A-4E6E-429B-91EE-0399C46060C6}
|
||||
{DDF70921-1F56-4EBF-BE90-0E3A0C8BFACB} = {DDF70921-1F56-4EBF-BE90-0E3A0C8BFACB}
|
||||
{08AF0B31-BA0F-4C46-A889-4411ADB81D68} = {08AF0B31-BA0F-4C46-A889-4411ADB81D68}
|
||||
{2E8DFE39-3377-45C0-81D6-D32A2C192F34} = {2E8DFE39-3377-45C0-81D6-D32A2C192F34}
|
||||
@@ -97,6 +98,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libSmilesParse", "GraphMol\
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testSmilesParse", "GraphMol\SmilesParse\SmilesParseTest.vcproj", "{20AFEDA7-3046-41F0-9BEF-425D0398362A}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{676E091A-4E6E-429B-91EE-0399C46060C6} = {676E091A-4E6E-429B-91EE-0399C46060C6}
|
||||
{DDF70921-1F56-4EBF-BE90-0E3A0C8BFACB} = {DDF70921-1F56-4EBF-BE90-0E3A0C8BFACB}
|
||||
{08AF0B31-BA0F-4C46-A889-4411ADB81D68} = {08AF0B31-BA0F-4C46-A889-4411ADB81D68}
|
||||
{2E8DFE39-3377-45C0-81D6-D32A2C192F34} = {2E8DFE39-3377-45C0-81D6-D32A2C192F34}
|
||||
@@ -185,6 +187,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wrapGraphMol", "GraphMol\Wr
|
||||
{33BB4E07-B13A-44EB-931F-E748D22A548D} = {33BB4E07-B13A-44EB-931F-E748D22A548D}
|
||||
{58DBEB0A-76E7-4029-83DC-0B2AC5AAFA5F} = {58DBEB0A-76E7-4029-83DC-0B2AC5AAFA5F}
|
||||
{0B51D40C-2E72-42AF-97EE-C7D188E717C0} = {0B51D40C-2E72-42AF-97EE-C7D188E717C0}
|
||||
{676E091A-4E6E-429B-91EE-0399C46060C6} = {676E091A-4E6E-429B-91EE-0399C46060C6}
|
||||
{08AF0B31-BA0F-4C46-A889-4411ADB81D68} = {08AF0B31-BA0F-4C46-A889-4411ADB81D68}
|
||||
{2E8DFE39-3377-45C0-81D6-D32A2C192F34} = {2E8DFE39-3377-45C0-81D6-D32A2C192F34}
|
||||
{1D9A3F4A-DAFD-498E-9C56-59FAE69194C8} = {1D9A3F4A-DAFD-498E-9C56-59FAE69194C8}
|
||||
@@ -222,6 +225,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wrapMolOps", "GraphMol\Wrap
|
||||
{33BB4E07-B13A-44EB-931F-E748D22A548D} = {33BB4E07-B13A-44EB-931F-E748D22A548D}
|
||||
{58DBEB0A-76E7-4029-83DC-0B2AC5AAFA5F} = {58DBEB0A-76E7-4029-83DC-0B2AC5AAFA5F}
|
||||
{0B51D40C-2E72-42AF-97EE-C7D188E717C0} = {0B51D40C-2E72-42AF-97EE-C7D188E717C0}
|
||||
{676E091A-4E6E-429B-91EE-0399C46060C6} = {676E091A-4E6E-429B-91EE-0399C46060C6}
|
||||
{2E8DFE39-3377-45C0-81D6-D32A2C192F34} = {2E8DFE39-3377-45C0-81D6-D32A2C192F34}
|
||||
{1D9A3F4A-DAFD-498E-9C56-59FAE69194C8} = {1D9A3F4A-DAFD-498E-9C56-59FAE69194C8}
|
||||
{8DA7765B-EF8E-45D4-B192-2C950C5C79F5} = {8DA7765B-EF8E-45D4-B192-2C950C5C79F5}
|
||||
@@ -458,6 +462,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZZZGraphMolRegrs", "GraphMo
|
||||
{C6555EDD-5666-4CF7-8AE2-1CF49A262636} = {C6555EDD-5666-4CF7-8AE2-1CF49A262636}
|
||||
{55973DDE-14F0-47A9-9F85-5B387884F136} = {55973DDE-14F0-47A9-9F85-5B387884F136}
|
||||
{B873A5E6-B25D-425C-8527-C52FB524F607} = {B873A5E6-B25D-425C-8527-C52FB524F607}
|
||||
{5408B0E6-0B50-4E12-921A-8F1B3E483716} = {5408B0E6-0B50-4E12-921A-8F1B3E483716}
|
||||
{4D9A72F3-BF82-4B1D-BF0C-580DF04E7429} = {4D9A72F3-BF82-4B1D-BF0C-580DF04E7429}
|
||||
{BB2B6CF7-385A-4478-8D03-F7BA96F5ABD4} = {BB2B6CF7-385A-4478-8D03-F7BA96F5ABD4}
|
||||
EndProjectSection
|
||||
@@ -949,6 +954,22 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testDistGeom", "DistGeom\te
|
||||
{DD564ACC-9799-4A4F-AA43-C42565165EFD} = {DD564ACC-9799-4A4F-AA43-C42565165EFD}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libChemTransforms", "GraphMol\ChemTransforms\ChemTransforms.vcproj", "{676E091A-4E6E-429B-91EE-0399C46060C6}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testChemTransforms", "GraphMol\ChemTransforms\testChemTransforms.vcproj", "{5408B0E6-0B50-4E12-921A-8F1B3E483716}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{676E091A-4E6E-429B-91EE-0399C46060C6} = {676E091A-4E6E-429B-91EE-0399C46060C6}
|
||||
{DDF70921-1F56-4EBF-BE90-0E3A0C8BFACB} = {DDF70921-1F56-4EBF-BE90-0E3A0C8BFACB}
|
||||
{08AF0B31-BA0F-4C46-A889-4411ADB81D68} = {08AF0B31-BA0F-4C46-A889-4411ADB81D68}
|
||||
{2E8DFE39-3377-45C0-81D6-D32A2C192F34} = {2E8DFE39-3377-45C0-81D6-D32A2C192F34}
|
||||
{8DA7765B-EF8E-45D4-B192-2C950C5C79F5} = {8DA7765B-EF8E-45D4-B192-2C950C5C79F5}
|
||||
{41B2DB92-DBB1-4C73-916C-BD7372F46FD4} = {41B2DB92-DBB1-4C73-916C-BD7372F46FD4}
|
||||
{8A443D9F-4C81-455C-82AB-AA26C9F9EE1C} = {8A443D9F-4C81-455C-82AB-AA26C9F9EE1C}
|
||||
{A6FD01DB-2F79-4317-85F8-BA361B8EA095} = {A6FD01DB-2F79-4317-85F8-BA361B8EA095}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
@@ -1616,6 +1637,18 @@ Global
|
||||
{91158915-015A-434B-AE89-CE55709440DC}.DebugPython.Build.0 = Debug|Win32
|
||||
{91158915-015A-434B-AE89-CE55709440DC}.Release.ActiveCfg = Release|Win32
|
||||
{91158915-015A-434B-AE89-CE55709440DC}.Release.Build.0 = Release|Win32
|
||||
{676E091A-4E6E-429B-91EE-0399C46060C6}.Debug.ActiveCfg = Debug|Win32
|
||||
{676E091A-4E6E-429B-91EE-0399C46060C6}.Debug.Build.0 = Debug|Win32
|
||||
{676E091A-4E6E-429B-91EE-0399C46060C6}.DebugPython.ActiveCfg = Debug|Win32
|
||||
{676E091A-4E6E-429B-91EE-0399C46060C6}.DebugPython.Build.0 = Debug|Win32
|
||||
{676E091A-4E6E-429B-91EE-0399C46060C6}.Release.ActiveCfg = Release|Win32
|
||||
{676E091A-4E6E-429B-91EE-0399C46060C6}.Release.Build.0 = Release|Win32
|
||||
{5408B0E6-0B50-4E12-921A-8F1B3E483716}.Debug.ActiveCfg = Debug|Win32
|
||||
{5408B0E6-0B50-4E12-921A-8F1B3E483716}.Debug.Build.0 = Debug|Win32
|
||||
{5408B0E6-0B50-4E12-921A-8F1B3E483716}.DebugPython.ActiveCfg = Debug|Win32
|
||||
{5408B0E6-0B50-4E12-921A-8F1B3E483716}.DebugPython.Build.0 = Debug|Win32
|
||||
{5408B0E6-0B50-4E12-921A-8F1B3E483716}.Release.ActiveCfg = Release|Win32
|
||||
{5408B0E6-0B50-4E12-921A-8F1B3E483716}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
|
||||
Reference in New Issue
Block a user