Advanced Structure Checker Button
/*
* Advanced Structure Checker Button
*
* Runs the structure checker against the currently selected row
* Runs in either <check> or <fix> mode
* Uses XML definition file which can be created with Structure Checker application
* see https://docs.chemaxon.com/display/structurechecker/Creating+a+Configuration+StrCh
* for more checkers see:
* https://docs.chemaxon.com/display/structurechecker/Checker+List
*
* Usage:
* 1. Edit the name of the Structure field
* 2. Set either <check> or <fix> mode
* 3. Provide the xmlConfigFilePath parameter
* 2. Run button script
*
* @author David Pech <[email protected]>
* @author Zsolt Mohacsi <[email protected]>
*/
import
com.im.df.api.*
import
com.im.df.api.support.SelectionDescription
import
com.im.ijc.core.api.util.IJCCoreUtils
import
chemaxon.checkers.*
import
chemaxon.struc.Molecule
import
com.im.df.api.chem.MarvinStructure
import
chemaxon.formats.MolImporter
import
chemaxon.checkers.FixMode;
import
chemaxon.checkers.logger.PropertyCheckerLogger;
import
chemaxon.checkers.runner.AdvancedCheckerRunner;
import
chemaxon.checkers.runner.configuration.reader.ActionStringBasedConfigurationReader;
import
chemaxon.checkers.runner.configuration.reader.ConfigurationReader;
import
chemaxon.checkers.runner.configuration.reader.XMLBasedConfigurationReader;
init = { widget ->
}
destroy = { widget ->
}
evaluate = { widget ->
def
ety = dataTree.rootVertex.entity
// assumes you have reference to the data tree
def
edp = ety.schema.dataProvider.getEntityDataProvider(ety)
def
molFld = ety.fields.items.
find
{ it.name ==
'Structure'
}
// find the structure field
def
rs = ety.schema.dataProvider.getDefaultResultSet(dataTree, false, DFEnvironmentRO.DEV_NULL)
// find the ResultSet
def
rootVS = rs.getVertexState(dataTree.rootVertex)
// obtain the VertexState
List ids = rootVS.getSelectedRowsIds()
// get the selected IDs
if
(ids.
size
==
1
) {
Map rows = rootVS.getData(ids, DFEnvironmentRO.DEV_NULL)
// get the data
Map row = rows[ids[
0
]]
// get the first and only row
MarvinStructure mol = row[molFld.id]
// Get the Structure. Its a com.im.df.api.chem.MarvinStructure instance
Molecule cxnMol = mol.getNative()
// obtain the chemaxon.struc.Molecule instance
// parameters for structure checker
String mode =
"fix"
// [check|fix] - in fix mode, the structure is rewritten in the database
String configSource =
"xml"
// [xml|actionstring]
String xmlConfigFilePath =
"/path/to/checkers.xml"
// [<xml config file path>|<action string>]
// actionString can be used instead of XML configuration
//String actionString = "" // for example something like "valence->fixvalence"
// read configuration
ConfigurationReader checkerConfigurationReader;
if
(configSource.equalsIgnoreCase(
"xml"
) && xmlConfigFilePath !=
null
) {
// XML configuration
File configFile =
new
File(xmlConfigFilePath);
checkerConfigurationReader =
new
XMLBasedConfigurationReader(
new
FileInputStream(configFile));
}
else
if
(configSource.equalsIgnoreCase(
"actionstring"
) && actionString !=
null
) {
// action string configuration
checkerConfigurationReader =
new
ActionStringBasedConfigurationReader(actionString);
}
else
{
println
"Cannot read configuration"
return
;
}
// create CheckerRunner
AdvancedCheckerRunner checkerRunner =
new
AdvancedCheckerRunner(checkerConfigurationReader);
// in a non-interactive environment ASK mode has no meaning, so we change it to fix mode
for (chemaxon.checkers.StructureChecker checker : checkerRunner.getCheckerConfiguration()) {
if
(FixMode.ASK.equals(checker.getDescriptor().getFixMode())) {
checker.getDescriptor().setFixMode(FixMode.FIX);
}
}
// set error logger
PropertyCheckerLogger logger =
new
PropertyCheckerLogger();
checkerRunner.setLogger(logger);
// set molecule
checkerRunner.setMolecule(cxnMol);
// run the checker+fixer
if
(mode.equalsIgnoreCase(
"fix"
)) {
checkerRunner.fix()
// rewrite structure in the database with the fixed one
// in case that fix mode is set
def
dataToUpdate = [(molFld.id):cxnMol.toFormat(
"sdf"
)]
def
lock = edp.lockable.withLock(
'Updating'
) { envRW ->
def
ud = DFUpdateDescription.create(ety, ids[
0
], dataToUpdate)
def
submitList = Collections.singletonList(ud)
edp.update(submitList, DFUndoConfig.OFF, envRW)
}
}
else
{
checkerRunner.checkAndWait()
}
// see report in molecule properties
println
cxnMol.toFormat(
"sdf"
)
}
else
{
println
"bad selection"
}
}
on_change = { widget, button ->
}
For example Structure Checker configuration see checkers.xml
Attached, you can also find a version of this script, where the fix|check mode is selected with a checkbox in a popup. StructureCheckerImproved.groovy