Plugins are used in general to add dynamically loaded modules to an application based on user defined configuration.
Different users may have their own set of plugins and this specific set is loaded to the application either when the application is loaded or when the user first uses the plugin. This dynamical loading is important when the program is an applet and plugins are dynamically loaded from the internet.
Our chemical calculator plugin structure is added to JChem for two main reasons:
plugin in the following way:
plugin wrapper module has to be written
for the calculation that implements the methods that JChem uses to set the
input molecule, run the calculation, get the results, etc.
cxcalc tool to run the plugin from the command line
cxcalc command line tool can be customized
by subclassing chemaxon.marvin.plugin.CalculatorOutput (optional)
JChem utilizes plugins in two ways:
cxcalc enables the user to run the
calculation from the command line; cxcalc provides general options
available for all plugins (such as saving the calculatiuon results together with the input molecule
in an SDF file) together with calculation specific options that are
configured in the configuration file;
evaluator or as an
integrated part of the Pharmacophore Mapper module that determines
pharmacophoric properties of atoms based on chemical properties (e.g. pKa, charge) and/or
functional groups containing the given atom.
cxcalc performs plugin calculations in a uniform way: it processes
general parameters referring to input, output, and SDF file tag names for storing calculation result
as well as plugin specific parameters that are different for each plugin. The available plugins
are defined in the configuration file.
cxcalc [<general options>] [input files] <plugin> [<plugin options>] [input_files] cxcalc [<general options>] [input files] <plugin1> [<plugin1 options>] [input_files] <plugin2> [<plugin2 options>] [input_files] ...
Prepare the usage of the cxcalc script or batch file
as described in Preparing the Usage of JChem
Batch Files and Shell Scripts.
Alternatively, the Calculator class can be directly invoked:
Win32 / Java 2 (assuming that JChem is installed in c:\jchem):
java -cp "c:\jchem\lib\jchem.jar;%CLASSPATH%" \
chemaxon.marvin.Calculator
[<general options>] [input files]
<plugin> [<plugin options>] [input_files]
java -cp "c:\jchem\lib\jchem.jar;%CLASSPATH%" \
chemaxon.marvin.Calculator
[<general options>] [input files]
<plugin1> [<plugin1 options>] [input_files]
<plugin2> [<plugin2 options>] [input_files]
...
Unix / Java 2 (assuming that JChem is installed in /usr/local/jchem):
java -cp "/usr/local/jchem/lib/jchem.jar:$CLASSPATH" \
chemaxon.marvin.Calculator
[<general options>] [input files]
<plugin> [<plugin options>] [input_files]
java -cp "/usr/local/jchem/lib/jchem.jar:$CLASSPATH" \
chemaxon.marvin.Calculator
[<general options>] [input files]
<plugin1> [<plugin1 options>] [input_files]
<plugin2> [<plugin2 options>] [input_files]
...
cxcalc -h, --help this help message
cxcalc <plugin> -h, --help plugin specific help message
-o, --output <filepath> output file path (default: stdout)
-t, --tag name of the SDFile tag to store the
calculation results
default tag name: see plugin help
-i, --id SDFile tag that stores the molecule ID
in the input SDF (default: molecule index)
-S, --sdf-output SDF output (otherwise only plugin result)
-g, --ignore-error continue with next molecule on error
-v, --verbose print calculation warnings to the console
Input files can be given both on the general option side and on the plugin specific option side, in either case these input files give the input molecules for the calculation. If more plugins are given then all plugin calculations are performed for all input molecules.
The available plugins are configured in one or more configuration files.
First the chemaxon/marvin/calculations/calc.properties configuration file is read and its
rcfiles property determines the other configuration files that
contain plugin specifications. Also, user defined plugins may just as well be configured right away
in this file. The built-in plugin configuration file is
chemaxon/marvin/calculations/calc.properties
which contains data for the built-in plugins that can be purchased from
ChemAxon Ltd.. This file path is the default value of the
rcfiles property.
The configuration file path is taken relative to the directories specified in the
CLASSPATH environment variable.
A detailed description of the configuration file is given below.
The command line parameter --tag specifies the SDF file tag name to be used
when storing the calculation results in an SDF file.
If the --sdf-output parameter is given, then the input molecules are
written in SDF format and the calculation result is added as an SDF file tag, otherwise
only the calculation result is shown in table form.
The parameter --id parameter specifies the input SDF file tag that stores the
molecule ID to be written in the output table. This parameter is only used if output is in
table form (--sdf-output parameter is not given). If not specified then the input
file index of the molecule is used as molecule ID.
cxcalc <plugin> -h
Here plugin is the plugin key from the configuration file.
Example
Typing
cxcalc logp -h
produces the help string
Calculator plugin: logp.
logP calculation
Usage:
cxcalc [general options] [input files] logp
[logp options] [input files]
logp options:
-h, --help this help message
-p, --precision <floating point precision as number of
fractional digits: 0-8 or inf> (default: 2)
-t, --type [increments|implh|logP] (default: logP)
-i, --implh [true|false] implicit H logP sum shown in brackets
(for incremental logP only) (default: false)
Multiple parameter values should be separated by ',' characters.
The command line parameter --precision specifies the required floating point
precision, that is, the number of required decimal digits in the output.
The command line parameter --type specifies the result type:
increments gives the atomic logp increment values for each atom in the molecule
while molecule gives the overal logp value for the molecule. Both results can be
queried by specifying both types separated by a comma: -t increments,implh,logP.
The released version of Calculator does not yet support database input/output.
The software may take molecules from a text file. Most molecular file formats are accepted (for instance MDL molfile, Compressed molfile, SDfile, Compressed SDfile, SMILES).
If no input file name is given in the command line the standard input is read.
Calculator writes calculation results as a single number if the result is a number
referring to the molecule, or it writes results as a list of numbers separated by semicolons
if the calculation gives a separate number for each atom in the molecule. The order of the results
corresponds to the order of the atoms determined by their atom indices. Other output formats
may be available for certain plugins, see the plugin specific options
for the specific plugin. Calculation results can be written in an SDF file as an SDF tag
if the --sdf-output parameter is specified or can be written without the input
molecule in a table form (this is the default).
The available plugins are configured in a java property file for the command line tool
cxcalc. The use of calculator plugins in the
Evaluator or in the Pharmacophore Mapper
does not require this configuration file because plugins for expression evaluation are
configured in the corresponding XML configuration files.
See Evaluator Configuration and
Pharmacophore Mapper Configuration for details.
The main calculator configuration file is chemaxon/marvin/calculations/calc.properties
whose path is taken relative to the directories in the CLASSPATH
environment variable. The configuration for user plugins can either be added to this file or
can be put in separate ones. In the latter case the value of the
rcfiles property
has to be modified to include the additional configuration file names (again, relative to the
CLASSPATH). By default, the rcfiles property
value contains only the configuration file path for the built-in plugins that can be purchased
from ChemAxon which is
chemaxon/marvin/calculations/calc.properties.
The configuration file is a java property file. The format of the configuration file is best shown by an example:
rcfiles=chemaxon/marvin/calculations/calc.properties,pluginconf/plugins.properties chg=org.charge.ChargePlugin\ $p=precision:2;t=type:total;i=implh:false\ $CHARGE\ $partial charge calculation\ $-p, --precision=<floating point precision as number of\n\ fractional digits: 0-8 or inf> (default: 2);\ -t, --type=[sigma|pi|total|implh] (default: total);\ -i, --implh=[true|false] implicit H charge sum shown in brackets\n\ (for sigma and total charge only) (default: false)\ $cxcalc -S -o result.sdf -t myCHARGE charge -t pi,total -p 3 test.mol
The property rcfiles specifies the additional configuration files that contain
plugin configurations as a comma-separated file path list, each item is taken relative to
directories in the CLASSPATH environment variable. In this example it contains the
built-in plugin configuration file and a user defined plugin configuration file.
The key chg is the plugin name that the plugin is
referenced by in the calc command line tool.
The value contains the configuration for a custom (user defined) charge plugin:
configuration items are separated by '$' characters. The '\' characters allows property values
to be expanded to multiple lines: the '\' character itself as well as leading white spaces in
the next line are ignored.
The configuration items:
<short name>=<long name>:<default value>separated by semicolons
Important: the long parameter names in the "plugin specific parameters" section have to be
the parameter property keys used in the plugin class in the
setParameters(Properties params) method to get the parameters!
cxcalc mols.sdf pka
ID tag of the input SDF file,
writing three significant values from each pKa type:
cxcalc mols.sdf -i ID pka -a 3 -b 3
-5,
maximum acidic pKa to 15:
cxcalc mols.sdf -i ID pka -a 3 -b 3 -i -5 -m 15
mols.sdf file,
uses the default configuraion file, writes results to the standard output in SDF format
using the default SDF charge tag for storing the calculation results:
cxcalc -S charge mols.sdf
molcharges.sdf file to be created in the
same directory:
cxcalc -S -o molcharges.sdf charge mols.sdf
cxcalc mols.sdf -S -o molcharges.sdf charge
cxcalc -S mols.sdf -o molcharges.sdf charge -t sigma,pi,total mview molcharges.sdfBy setting the
Table / Show Fields option in MarvinView the SDF file tags
will be shown in the table cells and in this way the charge values can be seen.
cxcalc -S mols.sdf -t LOGP_BOTH logp -t increments,logP | mview -
Note, that such piping does not work in Windows.
ID tag of the input SDF file,
output written to text file elemanal.txt:
cxcalc -o elemanal.txt -i ID elemanal mols.sdf
mols.smiles and output written as SDF
to elemanal.sdf with ELEMANAL tag name:
cxcalc -S -t ELEMANAL -o elemanal.sdf elemanal mols.smiles
A chemical calculation that is not currently available as a built-in plugin may also be used
in the calc command line tool, as well as in the
Evaluator or Pharmacophore Mapper
modules. There are three main step to achieve this:
calc as described in part
Configuration File of this manual.
calc command line tool by subclassing
chemaxon.marvin.plugin.CalculatorOutput (optional).
The first step is self-explanatory: go to the internet and download some code or write your own. The calculation code is assumed to work on one input molecule at a time, perform the calculation and then return various results of the calculation. The plugin wrapper will first set the input molecule, then run the calculation and finally query the results, so it is a good idea to follow roughly the same implementation style in the calculation module: the more the calculation code follows this model, the easier your work will be when you write the plugin wrapper.
The second step needs a bit more explanation: writing a plugin wrapper is nothing else but
extending the abstract base plugin class chemaxon.marvin.plugin.CalculatorPlugin.
Here is the list of methods that have to be implemented:
protected String getLicenseKey()
Implement this only if you want to sell your plugin and protect it with a license key.
The default implementation returns null which means that the plugin is free:
no license key is required.
A license key is an 8-character string that is hard-coded in your plugin and sold to your clients
in the license key file chemaxon/licenses.txt located in the
CLASSPATH or in the .chemaxon/licenses.txt (Unix) or
chemaxon/licenses.txt (Windows) file under the user's home directory.
In the license key file, the plugin name with full package name is paired with the
license key: chemaxon.marvin.calculations.YourPlugin=56TYAD12The license key returned by this method will be checked against the license key loaded from the
licenses.txt file. If they are equal then the plugin can be run without
restriction, otherwise it will run in demo mode: only one calculation can be performed without
restarting the application (e.g. calc will be run only for the first molecule of
the input SDF file).
The fact that this method has protected accessibility level may result in a
security problem: someone might add a java class to the same package, instantiate your plugin
and fetch the license key:
CalculatorPlugin plugin = new YourPlugin(); System.out.println(plugin.getLicenseKey());There is a trick to prevent this: instead of simply returning your license key, implement this method in the following way:
protected final String getLicenseKey() {
if (check()) {
return "56TYAD12"; // return your license key here
}
else {
return ""; // return the empty string which is the invalid key
}
}
First note that the method is declared final to prevent the intruder from
subclassing your plugin and replacing your license key by overwriting this method.
Next note that you return your license key only if the check() method
implemented in CalculatorPlugin returns true. Otherwise you
return the empty string which is the invalid key. Do not return null
which would mean that the plugin has no license key - if you return null then
your plugin will be freely used without any license key.
The mysterious check() method checks whether your plugin has been
validated. Validation is a simple process that checks whether the caller knows the
license key. This is done by a call to the validate(String license) method.
Hence with the above implementation the intruder would simply print out the empty
string while a programmer who has bought your license key and would like to use your plugin
can do that by proving that he/she knows your license key:
CalculatorPlugin plugin = new YourPlugin();
System.out.println(plugin.getLicenseKey()); // prints the empty string
plugin.validate("56TYAD12"); // supposing your license key is"56TYAD12"
System.out.println(plugin.getLicenseKey()); // now prints the real license key
public void setParameters(Properties params) throws PluginException
This method sets the plugin specific parameters: the params argument contains the
plugin parameters as long parameter name -> parameter value pairs.
(The long parameter name here is without the -- prefix: e.g. if you
have --type as a command line parameter then it will be present with key
type in this property table.) Your task is to
convert the parameter values from string to the required format and set the parameter
in the calculation module or store it in the plugin for later use. Throw a
PluginException on any error (unexpected format, unexpected value). All possible
plugin parameters have a default value so a missing parameter should not cause any error: use
its default value instead.
public void checkMolecule(Molecule mol) throws PluginException
Checks the input molecule. Throws a PluginException if the plugin calculation
result is not defined for the given molecule (e.g. molecule is a reaction molecule or a
molecule with R-groups). The exception message will be formed to an error message to the
user and the molecule will not be processed if a PluginException is thrown.
Do nothing if the molecule is accepted. The default implementation accepts
all molecules (simply returns).
public void setMolecule(Molecule mol) throws PluginException
This sets the input molecule. Again, throw a PluginException on any error.
public void run() throws PluginException
This method performs the calculation and stores the results. Include those tasks
that must be run once for each molecule and produce the calculation results in the end.
Throw a PluginException on any error.
public Molecule getMolecule()
This simply returns the input molecule.
public Object[] getResultTypes()
This method returns the queried result types. For example, the charge
calculation may have three result types: sigma, pi and total,
the logp calculation may have two result types: increments and
molecule. The built-in plugins charge, logp and
pka have the --type command line parameter that specifies the required
result types: this method returns those that are specified in this parameter. However, it is
possible to return all available result types and not provide this choice.
public int getResultDomain(Object type)
This returns the domain that the calculation result for the specified result type refers to:
currently it can be ATOM or MOLECULE. For example, the
logPPlugin returns ATOM if key is "increments"
and returns MOLECULE if key is "molecule".
public int getResultCount(Object type)
This returns the number of result items for the specified result type. For ATOM result
domain this is usually the number of atoms in the molecule, for MOLECULE domain this
is usually 1.
public Object getResult(Object type, int index) throws PluginException
This returns the result for the specified result type and the specified result index: this index
must be at least 0 and less than the result count returned by
getResultCount(Object type) for this result type. In our case the result is a number:
it must be wrapped into the derived class of java.lang.Number corresponding to its
primitive type (e.g. double must be wrapped into java.lang.Double).
PluginException can be thrown on any error.
public String getResultAsString(Object type, int index, Object result) throws PluginException
This returns a string representation of the result. The result type and index are also given:
in some cases the string representation may include these or depend on these as well. The
protected String format(double x) can be used to double -> String
conversion with a given number of fractional digits. If you intend to use this formatting then
protected void setDoublePrecision(int precision) has to be called once beforehand
to set the maximum number of decimal digits allowed in the fractional portion of a number.
PluginException can be thrown on any error.
public String getResultAsRGB(Object type, int index, Object result) throws PluginException
Returns the color to be used when displaying the result. This method is used when acidic pKa values are displayed
in red while basic pKa values are displayed in blue. The color is returned as a single int (see the
java.awt.Color API for a
definition of encoding a color into a single int). The default implementation returns 0
which means that the result will be displayed using the current foreground color.
PluginException can be thrown on any error.
protected void standardize(Molecule mol)
This method is used to bring the molecule to a standardized form. Some calculations require a certain
standardization preprocess, such as aromatization or a common form of certain functional groups
(one prescribed tautomer or mezomer form). The current implementation performs only aromatization
and the nitro group conversion [O-]-[N+]=O >> O=N=O. If any other transformation is
needed or no such transformation is necessary then you must implement this method. Be careful with
transformations that change the atom set of the molecule since these change the atom indices as
well: if the result domain is ATOM then after querying the results with
getResult(Object key, int index) and
getResultAsString(Object key, int index, Object result)
the program will output the returned result for the specified atom index
in the original molecule and not in the transformed one.
If the standardization procedure changes the atom indices then the index given in these result
query methods must be transformed to the corresponding atom index in the transformed molecule
and the result for that atom index must be returned.
Remark: This local standardization will be replaced by the invokation of the Standardizer module.
public String getOutputClassName()
This method is called by chemaxon.marvin.Calculator to get the class name of the
table form output provider class corresponding to your plugin. The default implementation
returns "chemaxon.marvin.plugin.CalculatorOutput" which is the class name of
the default table form output provider (outputs the molecule ID and the result strings for each
required result type). Implement this method by returning to your specific output provider
class name only if it is different from chemaxon.marvin.plugin.CalculatorOutput.
For the third step you should edit the configuration file and add your plugin data as described above in the Configuration File section of this manual.
The fourth step is optional: the default table output is implemented in
chemaxon.marvin.plugin.CalculatorOutput. This implementation outputs
the molecule ID and the results for all required result types in a table row. To provide a
different output table form you should subclass
chemaxon.marvin.plugin.CalculatorOutput and return the full class name
of your output class in public String getOutputClassName() implemented in your
plugin class. You should implement the following methods in your output class:
public String getHeader()
Returns the table header string.
public String getResult(Molecule target)
Returns the result table row for the given target molecule.
protected member variables of
chemaxon.marvin.plugin.CalculatorOutput:
CalculatorPlugin plugin is your plugin object
Properties params stores your plugin parameters
String separator is the separator string between result items