diff --git a/Code/JavaWrappers/csharp_wrapper/GraphMolCSharp.i b/Code/JavaWrappers/csharp_wrapper/GraphMolCSharp.i new file mode 100644 index 000000000..fef92f1a8 --- /dev/null +++ b/Code/JavaWrappers/csharp_wrapper/GraphMolCSharp.i @@ -0,0 +1,290 @@ +/* +* $Id: GraphMolJava.i 2141 2012-07-27 06:16:45Z glandrum $ +* +* Copyright (c) 2010, Novartis Institutes for BioMedical Research Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are +* met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above +* copyright notice, this list of conditions and the following +* disclaimer in the documentation and/or other materials provided +* with the distribution. +* * Neither the name of Novartis Institutes for BioMedical Research Inc. +* nor the names of its contributors may be used to endorse or promote +* products derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +%module RDKFuncs + +/* Suppress the unimportant warnings */ +#pragma SWIG nowarn=503,516 + +%include +%{ + #include + #include +%} +// The actual definition isn't in the top level hpp file! +%include + +/* Include the base types before anything that will utilize them */ +%include "stdint.i" +%include "std_string.i" +%include "../gmwrapper/std_list.i" +%include "../gmwrapper/std_vector.i" +%include "std_map.i" +%include "std_pair.i" +%include "carrays.i" + + +// an extremely unsatisfying way of handling exceptions, but it's better than +// crashing mono (which otherwise happened) +%exception { + try { + $action + } + catch (RDKit::ChemicalReactionException &e) { + std::string err="ChemicalReactionException: "; + err+=e.message(); + SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, err.c_str()); + } + catch (RDKit::ChemicalReactionParserException &e) { + std::string err="ChemicalReactionParserException: "; + err+=e.message(); + SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, err.c_str()); + } + catch (RDKit::ConformerException &e) { + std::string err="ConformerException: "; + err+=e.message(); + SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, err.c_str()); + } + catch (RDKit::MolPicklerException &e) { + std::string err="MolPicklerException: "; + err+=e.message(); + SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, err.c_str()); + } + catch (RDKit::MolSanitizeException &e) { + std::string err="MolSanitizeException: "; + err+=e.message(); + SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, err.c_str()); + } + catch (RDKit::SmilesParseException e) { + std::string err="SmilesParseException: "; + err+=e.message(); + SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, err.c_str()); + } + catch (KeyErrorException e) { + std::string err="KeyError: "; + err+=e.key(); + SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, err.c_str()); + } + catch (std::exception e) { + SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, "error"); + } +} + + +/* + * Custom handler for longs. The problem is described in swig-Bugs-2965875 + * and most of this solution is taken from the proposed patch in that bug report. + * ------------------------------------------------------------------------- + * Define typemaps for `long` + * + * This is complicated by the fact `long` is 32-bits on some platforms + * but is 64-bits on other platforms. We're just going to override the + * important ones here. + */ +#if defined(SWIGWORDSIZE64) +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +typedef long long int int_least64_t; +typedef unsigned long long int uint_least64_t; +typedef long long int int_fast64_t; +typedef unsigned long long int uint_fast64_t; +typedef long long int intmax_t; +typedef unsigned long long int uintmax_t; +%apply long long { long }; +%apply const long long & { const long & }; +%apply unsigned long long { unsigned long }; +%apply const unsigned long long & { const unsigned long & }; +/* +#elif defined(SWIGWORDSIZE32) +%apply int { long }; +%apply const int & { const long & }; +%apply unsigned int { unsigned long }; +%apply const unsigned int & { const unsigned long & }; +#else +#error "Neither SWIGWORDSIZE64 nor SWIGWORDSIZE32 is defined" +*/ +#endif + +%shared_ptr(RDKit::ROMol) +%shared_ptr(RDKit::RWMol) +%shared_ptr(RDKit::Atom) +%shared_ptr(RDKit::Bond) +%shared_ptr(RDKit::PeriodicTable) +%shared_ptr(Canon::MolStackElem) +%shared_ptr(RDKit::QueryAtom) +%shared_ptr(RDKit::QueryBond) +%shared_ptr(RDKit::QueryOps) +%shared_ptr(RDKit::MolSanitizeException) +%shared_ptr(RDKit::SmilesParseException) +%shared_ptr(RDKit::RingInfo) +%shared_ptr(RDKit::ChemicalReaction) +%shared_ptr(ForceFields::ForceFieldContrib); +%shared_ptr(ForceFields::UFF::AngleBendContrib); +%shared_ptr(ForceFields::UFF::BondStretchContrib); +%shared_ptr(ForceFields::UFF::DistanceConstraintContrib); +%shared_ptr(ForceFields::UFF::vdWContrib); +%shared_ptr(ForceFields::UFF::TorsionAngleContrib); + +/* Some utility classes for passing arrays in and out */ +%array_class(double, Double_Array); + +/* Since documentation management is deprecated in SWIG 1.3, we're using the suggested workarounds. Apply them + here so that can be removed easily later */ +// Documentation +// DO THIS BEFORE ANY OF THE OTHER INCLUDES +//%include "../RDKitExceptions.i" + +%include "../point.i" +// Need the types wrapper or we get undefined errors for STR_VECT +%include "../types.i" +// Conformer seems to need to come before ROMol +%include "../Conformer.i" +%include "../ROMol.i" +%include "../RWMol.i" +%include "../Bond.i" +%include "../BondIterators.i" +%include "../Atom.i" +%include "../AtomIterators.i" +%include "../AtomPairs.i" +%include "../Canon.i" +%include "../Conformer.i" +%include "../QueryAtom.i" +%include "../QueryBond.i" +%include "../QueryOps.i" +%include "../PeriodicTable.i" +%include "../SanitException.i" +%include "../SmilesParse.i" +%include "../SmilesWrite.i" +%include "../SmartsWrite.i" +%include "../MolOps.i" +%include "../MolSupplier.i" +%include "../MolWriters.i" +%include "../RingInfo.i" +%include "../ChemReactions.i" +%include "../BitOps.i" +%include "../ExplicitBitVect.i" +%include "../Fingerprints.i" +%include "../MorganFingerprints.i" +%include "../Rings.i" +%include "../transforms.i" +%include "../DistGeom.i" +%include "../ForceField.i" +%include "../ChemTransforms.i" +%include "../Subgraphs.i" + +// Create a class to throw various sorts of errors for testing. Required for unit tests in ErrorHandlingTests.java +#ifdef INCLUDE_ERROR_GENERATOR +%include "../ErrorGenerator.i" +#endif + +/* Done explicitly in BitOps.i +%include +%template(TanimotoSimilarityEBV) TanimotoSimilarity; +%template(DiceSimilarityEBV) DiceSimilarity; +*/ +%template(DiceSimilarity) RDKit::DiceSimilarity; + +/* vector */ +%template(Int_Vect) std::vector; +%template(Byte_Vect) std::vector; +%template(Double_Vect) std::vector; +%template(UInt_Vect) std::vector; +%template(Str_Vect) std::vector ; +%template(Point_Vect) std::vector; +%template(Point2D_Vect) std::vector; +%template(Point3D_Vect) std::vector; +%template(Atomic_Params_Vect) std::vector; + +/* pair */ +%template(Int_Pair) std::pair; +%template(Double_Pair) std::pair; +%template(UInt_Pair) std::pair; +%template(Long_Pair) std::pair; + +/* map */ +%template(String_String_Map) std::map; +%template(Int_Int_Map) std::map; +%template(Int_Point2D_Map) std::map; +%template(Int_Point3D_Map) std::map; +%template(Int_Int_Vect_List_Map) std::map > >; + +/* vector pair */ +%template(UInt_Pair_Vect) std::vector >; +%template(Match_Vect) std::vector >; +%template(Long_Pair_Vect) std::vector >; + +/* vector vector */ +%template(Int_Vect_Vect) std::vector >; + +/* list */ +%template(Int_Vect_List) std::list >; + + +/* other */ +%template(Match_Vect_Vect) std::vector > >; +%template(Flagged_Atomic_Params_Vect) std::pair,bool>; +%template(Shared_Int_Array) boost::shared_array; +%template(Shared_Double_Array) boost::shared_array; + +// Methods to get at elements of shared arrays +%extend boost::shared_array { + double getElement(int i) { + return (*($self))[i]; + } + double setElement(int i, double value) { + (*($self))[i] = value; + } +} +%extend boost::shared_array { + int getElement(int i) { + return (*($self))[i]; + } + int setElement(int i, int value) { + (*($self))[i] = value; + } +} + +%include "../Descriptors.i" + +#ifdef BUILD_AVALON_SUPPORT +%include "../AvalonLib.i" +#endif +#ifdef BUILD_INCHI_SUPPORT +%include "../Inchi.i" +#endif + +%include "../DiversityPick.i" + +%{ +#include +%} +%include diff --git a/Code/JavaWrappers/csharp_wrapper/README b/Code/JavaWrappers/csharp_wrapper/README new file mode 100644 index 000000000..f154e6826 --- /dev/null +++ b/Code/JavaWrappers/csharp_wrapper/README @@ -0,0 +1,16 @@ +To build on a linux system with mono installed: + +Run SWIG: +--------- +swig -c++ -csharp -namespace GraphMolWrap -DBUILD_AVALON_SUPPORT -DBUILD_INCHI_SUPPORT -DSWIGWORDSIZE64 -outdir ./swig_csharp -I/usr/include -I/usr/local/include -I$RDBASE/Code -I$RDBASE/Code/JavaWrappers -I$RDBASE/External -o GraphMolCSharp_wrap.cxx ./GraphMolCSharp.i + +Compile and link the shared library: +------------------------------------ +g++ -DGraphMolWrap_EXPORTS -DRDK_64BIT_BUILD -O3 -DNDEBUG -fPIC -I/usr/local/include -I$RDBASE/Code -I$RDBASE/Code/JavaWrappers -I$RDBASE/External -Wno-deprecated -Wno-unused-function -fno-strict-aliasing -fPIC -o GraphMolCSharp_wrap.cxx.o -c GraphMolCSharp_wrap.cxx +g++ -fPIC -O3 -DNDEBUG -shared -Wl,-soname,libRDKFuncs.so -o libRDKFuncs.so GraphMolCSharp_wrap.cxx.o -L/usr/local/lib $RDBASE/lib/libAvalonLib_static.a $RDBASE/lib/libavalon_clib_static.a $RDBASE/lib/libRDInchiLib_static.a $RDBASE/lib/libInchi_static.a $RDBASE/lib/libFileParsers_static.a $RDBASE/lib/libSmilesParse_static.a $RDBASE/lib/libDepictor_static.a $RDBASE/lib/libSubstructMatch_static.a $RDBASE/lib/libChemReactions_static.a $RDBASE/lib/libFingerprints_static.a $RDBASE/lib/libChemTransforms_static.a $RDBASE/lib/libSubgraphs_static.a $RDBASE/lib/libGraphMol_static.a $RDBASE/lib/libDataStructs_static.a $RDBASE/lib/libDescriptors_static.a $RDBASE/lib/libPartialCharges_static.a $RDBASE/lib/libMolTransforms_static.a $RDBASE/lib/libDistGeomHelpers_static.a $RDBASE/lib/libDistGeometry_static.a $RDBASE/lib/libForceFieldHelpers_static.a $RDBASE/lib/libForceField_static.a $RDBASE/lib/libEigenSolvers_static.a $RDBASE/lib/libOptimizer_static.a $RDBASE/lib/libMolAlign_static.a $RDBASE/lib/libAlignment_static.a $RDBASE/lib/libSimDivPickers_static.a $RDBASE/lib/libRDGeometryLib_static.a $RDBASE/lib/libRDGeneral_static.a -lboost_thread-mt -lboost_system-mt -lpthread + +Build and test the csharp code: +------------------------------- +gmcs -out:RDKFuncs.dll -t:library swig_csharp/*.cs +gmcs -out:test.exe -addmodule:./RDKFuncs.dll test.cs +mono test.exe diff --git a/Code/JavaWrappers/csharp_wrapper/test.cs b/Code/JavaWrappers/csharp_wrapper/test.cs new file mode 100644 index 000000000..caded1007 --- /dev/null +++ b/Code/JavaWrappers/csharp_wrapper/test.cs @@ -0,0 +1,76 @@ +using System; +using GraphMolWrap; + +public class rdktest +{ + // static void rxnTest() { + // Console.WriteLine( "Reaction tests" ); + // var rxn = ChemicalReaction.ReactionFromSmarts("[N:1][C:2].[OH][C:3]=[O:4]>>[C:2][N:1][C:3]=[O:4]"); + // var amine = RWMol.MolFromSmiles("CCCN"); + // var acid = RWMol.MolFromSmiles("C1CC1CC(=O)O"); + // ROMol[] rs = {amine,acid}; + // ROMol_Vect rv = new ROMol_Vect(rs); + // for(var i=0;i<100000;i++){ + // var ps=rxn.runReactants(rv); + // if(i%100 == 0) { + // Console.WriteLine( "\t{0}", i ); + // } + // } + // Console.WriteLine( "Goodbye" ); + // } + // static void smiTest() { + // Console.WriteLine( "repeatedly from smiles" ); + // for(var i=0;i<1000000;i++){ + // ROMol m1=RDKFuncs.MolFromSmiles("c1ccccc1"); + // if(i%1000 == 0) { + // Console.WriteLine( "\t{0}", i ); + // } + // } + + // Console.WriteLine( "Goodbye" ); + // } + + static void morganTest() + { + // ----- Object creation ----- + + Console.WriteLine( "Creating some objects:" ); + + ROMol m1=RWMol.MolFromSmiles("c1ccccc1"); + Console.WriteLine(" mol: "+m1+" "+m1.getNumAtoms()); + ROMol m2=RWMol.MolFromSmiles("c1ccccn1"); + + var fp1=RDKFuncs.MorganFingerprintMol(m1,2); + var fp2=RDKFuncs.MorganFingerprintMol(m2,2); + + Console.WriteLine(" sim: "+RDKFuncs.DiceSimilarity(fp1,fp2)); + } + + static void Main() + { + // ----- Object creation ----- + + Console.WriteLine( "Creating some objects:" ); + + ROMol m1=RWMol.MolFromSmiles("c1ccccc1"); + Console.WriteLine(" mol: "+m1+" "+m1.getNumAtoms()); + ROMol m2=RWMol.MolFromSmiles("c1ccccn1"); + Console.WriteLine(" smi: "+m1+" "+m1.MolToSmiles()); + Console.WriteLine(" smi2: "+m2+" "+m2.MolToSmiles()); + + + ExplicitBitVect fp1=RDKFuncs.LayeredFingerprintMol(m1); + ExplicitBitVect fp2=RDKFuncs.LayeredFingerprintMol(m2); + + Console.WriteLine(" sim: "+RDKFuncs.TanimotoSimilarityEBV(fp1,fp2)); + + //rxnTest(); + //smiTest(); + morganTest(); + + ROMol m3=RWMol.MolFromSmiles("c1cccc1"); + + + Console.WriteLine( "Goodbye" ); + } +}