ChemAxon's concurrent framework is based on the Java 5.0 java.util.concurrent API. Below there are three examples which show code samples using ChemAxon's concurrent framework. The common code is written using a ConcurrentPluginApplication class: it starts a ConcurrentProcessor with a specified InputProducer and WorkUnitFactory. The InputProducer is supposed to produce the plugin inputs: the input molecules and possibly the plugin objects performing the calculation. The WorkUnit objects produced by the WorkUnitFactory are run concurrently by the ConcurrentProcessor and are supposed to execute the plugin calculation (the CalculatorPlugin.run() method). Finally, the results are collected by ConcurrentPluginApplication.consume(Object result) in the main thread. It is important to process the results in a single thread so that the order of the results will be the same as the order of the input molecules.
Our examples show different ways to provide the inputs and outputs for the concurrent processor. Input molecules are read from System.in if the molecule file is omitted. The following API is used to do this:
the Marvin specific API in chemaxon.util.concurrent.marvin
the plugin specific API in chemaxon.marvin.plugin.concurrent
In the following examples we use the test.smiles input file:
The logDPluginApplication is a simple application that shows a concurrent logD calculation. The input is the molecule; the output is the logD value at a given pH (the default pH is 7.4).
java logDPluginApplication [pH] [molFile]
java logDPluginApplication 5.2 test.smiles
The pKaPluginApplication is an application that shows concurrent a pKa calculation. The input is the molecule, the output is a result record storing that number of thestrongest pKa values (or all, if this number is omitted).
java pKaPluginApplication [count] [molFile]
java pKaPluginApplication 2 test.smiles
TautomerizationPluginApplication shows an example of concurrent tautomer generation. This example is more complex since the result may be a huge molecule array (with even several thousand molecules). Therefore we do not store the result in memory. Instead, we use the plugin object itself as result object, which generates the tautomers on-the-fly.
Here we face the problem of reusing the plugin objects: it would be too much overhead to create a new plugin for each input molecule. We have to fetch all results from the plugin before we can start the next computation using the same plugin object, therefore the work unit returns the plugin object as calculation result, as well as gets the plugin object to work with from the input producer together with the input molecule. The consume(Object result) (in the main thread) gets the tautomers from the plugin and writes the tautomer with minimal logD. Finally, it returns the plugin object for reuse to the input producer.
The input is the plugin object together with the molecule, the output is the plugin object. The application writes the tautomer with minimal logD to the output. The number of plugin objects to be generated initially can be specified (10 if omitted).
java TautomerizationPluginApplication [pluginCount] [molFile]
java TautomerizationPluginApplication 16 test.smiles