From: Egon W. <e.w...@sc...> - 2006-08-30 03:59:31
|
cc: cdk-devel On Tuesday 29 August 2006 18:31, Sam Adams wrote: > Within the jni-inchi project I've written classes to generate an InChI > from a CDK IAtomContainer, and to generate an IAtomContainer from an > InChI. They currently support all aspects of InChI apart from radicals > and atom parities. Great. > I'd like to move these classes into the CDK making it easier for CDK > users to produce InChIs. I've also written a patch for jChemPaint > allowing generation of InChIs in the same way that SMILES are currently > created, through the Report menu. Sounds really good. How does it deal with the JNI bits, that is platform dependencies, etc? What platforms did you test it on? (BTW, do you have JUnit tests?) > If you approve of these additions, could you grant me developer access > to the CDK - my sourceforge user name is sea36. It sounds good and just added you. But what we need to do first a bit, is discuss where we put this. To everyone, does it make sense to have jni somewhere in the package name, to indicate that a piece of code requires a JNI bridge? And how should we organize the platform dependen code? Suggestions please! Sam, maybe you can explain how you organize that now, as a starting (possibly final :) proposal? Egon -- e.w...@sc... Cologne University Bioinformatics Center (CUBIC) Blog: http://chem-bla-ics.blogspot.com/ GPG: 1024D/D6336BA6 |
From: peter murray-r. <pm...@ca...> - 2006-08-30 07:18:57
|
At 04:56 30/08/2006, Egon Willighagen wrote: >cc: cdk-devel > >On Tuesday 29 August 2006 18:31, Sam Adams wrote: > > Within the jni-inchi project I've written classes to generate an InChI > > from a CDK IAtomContainer, and to generate an IAtomContainer from an > > InChI. They currently support all aspects of InChI apart from radicals > > and atom parities. > >Great. > > > I'd like to move these classes into the CDK making it easier for CDK > > users to produce InChIs. I've also written a patch for jChemPaint > > allowing generation of InChIs in the same way that SMILES are currently > > created, through the Report menu. > >Sounds really good. How does it deal with the JNI bits, that is platform >dependencies, etc? What platforms did you test it on? > >(BTW, do you have JUnit tests?) > > > If you approve of these additions, could you grant me developer access > > to the CDK - my sourceforge user name is sea36. > >It sounds good and just added you. But what we need to do first a bit, is >discuss where we put this. > >To everyone, does it make sense to have jni somewhere in the package name, to >indicate that a piece of code requires a JNI bridge? And how should we >organize the platform dependen code? Suggestions please! Sam, maybe you can >explain how you organize that now, as a starting (possibly final :) proposal? Perhaps we could have a factory that generates a JNI-InChI. The user asks for a factory and if the system supports the platform it returns it, else fails. I am not sure how the system determines whether it can support InChI - maybe a lookup in the first instance? P. Peter Murray-Rust Unilever Centre for Molecular Sciences Informatics University of Cambridge, Lensfield Road, Cambridge CB2 1EW, UK +44-1223-763069 |
From: Egon W. <e.w...@sc...> - 2006-08-30 10:45:16
|
On Wednesday 30 August 2006 09:15, peter murray-rust wrote: > >To everyone, does it make sense to have jni somewhere in the package name, > > to indicate that a piece of code requires a JNI bridge? And how should we > > organize the platform dependen code? Suggestions please! Sam, maybe you > > can explain how you organize that now, as a starting (possibly final :) > > proposal? > > Perhaps we could have a factory that generates a JNI-InChI. The user > asks for a factory and if the system supports the platform it returns > it, else fails. I am not sure how the system determines whether it > can support InChI - maybe a lookup in the first instance? Yeah, that sounds like a good idea: an InChIGenerator which can only be instantiated via an InChiGeneratorFactory. Loading the C/C++ library is normally done via a System command (IIRC), and I think several locations etc can be tried to make things more system independent... Egon -- Radboud University Nijmegen http://www.cac.science.ru.nl/ blog: http://chem-bla-ics.blogspot.com/ |
From: Rajarshi G. <rg...@in...> - 2006-08-30 13:19:12
|
On Wed, 2006-08-30 at 12:47 +0200, Egon Willighagen wrote: > On Wednesday 30 August 2006 09:15, peter murray-rust wrote: > > >To everyone, does it make sense to have jni somewhere in the package name, > > > to indicate that a piece of code requires a JNI bridge? And how should we > > > organize the platform dependen code? Suggestions please! Sam, maybe you > > > can explain how you organize that now, as a starting (possibly final :) > > > proposal? > > > > Perhaps we could have a factory that generates a JNI-InChI. The user > > asks for a factory and if the system supports the platform it returns > > it, else fails. I am not sure how the system determines whether it > > can support InChI - maybe a lookup in the first instance? > > Yeah, that sounds like a good idea: an InChIGenerator which can only be > instantiated via an InChiGeneratorFactory. > > Loading the C/C++ library is normally done via a System command (IIRC), and I > think several locations etc can be tried to make things more system > independent... One question - what would the installation procedure look like? If I understand correctly, the JNI c++ code will be compiled via the ant build script. This will generate a set of jar's and an .so file. Will we have to copy the .so file by hand to a location that that the wrapper knows about (such as /usr/local/lib)? Also what happens when one wants to use the comprehensive jar file (from dist-large)? Would it be a good idea to have an 'install' target that simply dumps all the jars in dist/jar to a user specified directory (or keeps them there if no directory is psecified)? ------------------------------------------------------------------- Rajarshi Guha <rg...@in...> GPG Fingerprint: 0CCA 8EE2 2EEB 25E2 AB04 06F7 1BB9 E634 9B87 56EE ------------------------------------------------------------------- There's no problem so bad that you can't add some guilt to it to make it worse. -Calvin |
From: Sam A. <se...@ca...> - 2006-08-30 08:42:47
|
Hi, Here's a quick overview of how the JNI-InChI package is set up: The main part of the package consists of a small piece of C++ code that 'talks' directly to the InChI API, Java code to call these native methods, and pass data to/from them, and a set of Java classes that encapsulate the input and output data structures used by the InChI API, so there are: For Structure to InChI - * JniInchiInput: Holds options and the structure (JniInchiAtom, JniInchiStereo0D etc.) for InChI generation. * JniInchiOutput: Holds InChI, AuxInfo, Return status, Messages & Log For InChI to Structure - * JniInchiInputInchi: Holds options and the InChI string. * JniInchiOutputStructure: Holds return status, messages, warning flags and the structure (in the same format as before). Once the input data structure is set up, the JniInchiWrapper class is called, using either the getInchi(JniInchiInput) or getStructureFromInchi(JniInchiInputInchi) methods. These make sure that the native (C++) libraries are loaded, pass the data to them and have them make the appropriate calls to the InChI API. The results from this are fed back to JniInchiWrapper, which generates the appropriate output data structure, and returns it. The package also contains classes to interface between this core, and the CDK or CML. I think that taking these out of JNI-InChI and moving them to their respective projects would make them both easier to use, and to maintain - removing circular dependencies. Within the CDK part of the package there are two classes: * CDKInchiGenerator: takes an AtomContainer, generates the InChI input data structures from it, and calls JniInchiWrapper.getInchi(), and provides methods to access the results (getInchi(), getAuxInfo(), getReturnStatus() etc.) * InchiCDKGenerator: takes an InChI, generates the appropriate input structure, calls JniInchiWrapper.getStructureFromInchi(), generates an AtomContainer from the returned InChI formatted structure. The CML part of the package has classes with equivalent functionality - CMLInchiGenerator and InchiCMLGenerator. Here's an example of how these classes can be used: import net.sf.jniinchi.cdk.CDKInchiGenerator; import net.sf.jniinchi.INCHI_RET; [...] CDKInchiGenerator inchiGen = new CDKInchiGenerator(container, "-DoNotAddH"); INCHI_RET ret = inchiGen.getReturnStatus(); if (ret == INCHI_RET.WARNING) { // InChI generated, but with warning message System.out.println("InChI warning: " + inchiGen.getMessage()); } else if (ret != INCHI_RET.OKAY) { // InChI generation failed throw new CDKException("InChI failed: " + ret.toString() + " [" + inchiGen.getMessage() + "]"); } Platform dependencies / loading the native code: The native code is platform dependent. I have compiled and tested it on both Windows XP, and Linux (Fedora Core 5, and Suse 9). Precompiled binaries are included in the package (JniInchi.dll and libinchi.dll for Windows, and libJniInchi.so and libinchi.so for Linux). These have to be loaded by Java at runtime, and the JniInchiWrapper class takes care of this. When loading native code Java searches the directories found in the java.library.path system property. These are usually directories from the jdk or jre installation, and either the contents of the PATH environmental variable in Windows, or the contents of LD_LIBRARY_PATH in Linux. Therefore, in order to use the JNI InChI wrapper the native library files must be placed in one of these directories. If, however, you use the jniInChI.jar file and it fails to load the native code it attempts to extract the copies of the libraries contained in the jar and place them into '.' and try loading the native code again automatically. So long as the current user has write access to the appropriate directory, and either PATH or LD_LIBRARY_PATH contains '.', this will work. If this fails it throws a JniInchiException. So, in summary: this has all been a very long way of saying that I suggest the CDKInchiGenerator and InchiCDKGenerator classes are moved from the JNI-InChI project, and into the CDK (perhaps to org.openscience.cdk.io.inchi.jni ?), and jniInChI.jar is added to the project! I await your comments... Sam P.S. Egon - I'm in the process of adding JUnit tests at the moment - some classes currently have them, and some don't. -- Unilever Centre for Molecular Science Informatics Cambridge University Chemical Laboratories Tel: 01223 763073 Lensfield Road email: se...@ca... Cambridge CB2 1EW |
From: Egon W. <e.w...@sc...> - 2006-08-30 10:57:44
|
On Wednesday 30 August 2006 10:42, Sam Adams wrote: > Here's a quick overview of how the JNI-InChI package is set up: Thanx. > The main part of the package consists of a small piece of C++ code that > 'talks' directly to the InChI API, Java code to call these native > methods, and pass data to/from them, and a set of Java classes that > encapsulate the input and output data structures used by the InChI API, > so there are: Yes, same for the CDK-Ghemical bridge in Bioclipse (post 1.0). > For Structure to InChI - > * JniInchiInput: Holds options and the structure (JniInchiAtom, > JniInchiStereo0D etc.) for InChI generation. > * JniInchiOutput: Holds InChI, AuxInfo, Return status, Messages & Log OK. > For InChI to Structure - > * JniInchiInputInchi: Holds options and the InChI string. > * JniInchiOutputStructure: Holds return status, messages, warning flags > and the structure (in the same format as before). Good, though I have more difficulties understand the naming scheme for these classes... > Once the input data structure is set up, the JniInchiWrapper class is > called, using either the getInchi(JniInchiInput) or > getStructureFromInchi(JniInchiInputInchi) methods. These make sure that > the native (C++) libraries are loaded, pass the data to them and have > them make the appropriate calls to the InChI API. The results from this > are fed back to JniInchiWrapper, which generates the appropriate output > data structure, and returns it. Sound good. > The package also contains classes to interface between this core, and > the CDK or CML. I think that taking these out of JNI-InChI and moving > them to their respective projects would make them both easier to use, > and to maintain - removing circular dependencies. Removing circular dependencies are important. > Within the CDK part of the package there are two classes: > > * CDKInchiGenerator: takes an AtomContainer, generates the InChI input > data structures from it, and calls JniInchiWrapper.getInchi(), and > provides methods to access the results (getInchi(), getAuxInfo(), > getReturnStatus() etc.) > * InchiCDKGenerator: takes an InChI, generates the appropriate input > structure, calls JniInchiWrapper.getStructureFromInchi(), generates an > AtomContainer from the returned InChI formatted structure. OK. Does it uses cdk.interfaces only, or does it hard code use of cdk.AtomContainer? > The CML part of the package has classes with equivalent functionality - > CMLInchiGenerator and InchiCMLGenerator. > > Here's an example of how these classes can be used: > > import net.sf.jniinchi.cdk.CDKInchiGenerator; > import net.sf.jniinchi.INCHI_RET; > > [...] > > CDKInchiGenerator inchiGen = > new CDKInchiGenerator(container, "-DoNotAddH"); > INCHI_RET ret = inchiGen.getReturnStatus(); > if (ret == INCHI_RET.WARNING) { > // InChI generated, but with warning message > System.out.println("InChI warning: " + inchiGen.getMessage()); > } else if (ret != INCHI_RET.OKAY) { > // InChI generation failed > throw new CDKException("InChI failed: " + ret.toString() > + " [" + inchiGen.getMessage() + "]"); > } OK. > Platform dependencies / loading the native code: > > The native code is platform dependent. I have compiled and tested it on > both Windows XP, and Linux (Fedora Core 5, and Suse 9). Precompiled > binaries are included in the package (JniInchi.dll and libinchi.dll for > Windows, and libJniInchi.so and libinchi.so for Linux). Well... it's even more complex. Linux .so files are ABI dependent, i.e. depend on the systems standard C/C++ libraries, and on the architecture... a amd64 .so is different from a i386 .so ... Rob Schellhorn took the approach to compile the glue code when compiling the rest of the Bioclipse plugin. With the amount of different .so files I expect this would be better. He has an Ant script to do this in bioclipse SVN. > These have to > be loaded by Java at runtime, and the JniInchiWrapper class takes care > of this. Good. That would match Peter's factory idea... > When loading native code Java searches the directories found > in the java.library.path system property. These are usually directories > from the jdk or jre installation, and either the contents of the PATH > environmental variable in Windows, or the contents of LD_LIBRARY_PATH in > Linux. Therefore, in order to use the JNI InChI wrapper the native > library files must be placed in one of these directories. If, however, > you use the jniInChI.jar file and it fails to load the native code it > attempts to extract the copies of the libraries contained in the jar and > place them into '.' and try loading the native code again automatically. > So long as the current user has write access to the appropriate > directory, and either PATH or LD_LIBRARY_PATH contains '.', this will > work. If this fails it throws a JniInchiException. OK, we'll have to see how this would work out. > So, in summary: this has all been a very long way of saying that I > suggest the CDKInchiGenerator and InchiCDKGenerator classes are moved > from the JNI-InChI project, and into the CDK (perhaps to > org.openscience.cdk.io.inchi.jni ?), and jniInChI.jar is added to the > project! I suggest not to put it in cdk.io, as I things are not read from and save to file. Better cdk.inchi. About the .jni, I was more thinking of where to put the JNI glue code... > P.S. Egon - I'm in the process of adding JUnit tests at the moment - > some classes currently have them, and some don't. Good. Egon -- Radboud University Nijmegen http://www.cac.science.ru.nl/ blog: http://chem-bla-ics.blogspot.com/ |
From: Sam A. <se...@ca...> - 2006-08-31 15:14:01
|
I've just committed the glue code between CDK and JNI-InChI to the CDK and removed it from the JNI-InChI project, and added the latest JNI-InChI jar file to CDK. There are three classes, all in the org.openscience.cdk.inchi package: * InChIGenerator - for generating InChIs from structures * InChIToStructure - for generating structures from InChIs * InChIGeneratorFactory - for creating instances of the other classes Users must first construct an InChIGeneratorFactory, which checks that the native code is available on their system. If the native code cannot be loaded then a CDKException is thrown. Once constructed, the factory can be used to construct InChIGenerators and InChIToStructures. The currently distributed JNI-InChI jar contains the inchi and jni native binaries for Windows and Linux. The Linux binaries were compiled on an x86 system, with GCC 3.3.5. They work fine on all the test systems I have access to (fairly recent Fedora Core, Debian, and Suse systems). Some users, espcially those with different architectures, will have to compile their own version of the JNI InChI project. Java searches the contents of the PATH (Windows) or LD_LIBRARY_PATH (Linux) for the native code. Users can either extract the native libraries and place them where they wish, or, so long as either the location of the current working directory or '.' are included in the PATH or LD_LIBRARY_PATH environmental variable, the appropriate native libraries should be automatically extracted from the jar and placed in that location. If the native libraries cannot be loaded then suggestions as to what needs to be done are printed to System.err. I have also added code for JChemPaint to generate InChIs, in the same way it does SMILES. I have only added this to the experimental, not the stable, GUI. Sam |