This script takes a tables of structures and applies a pre-defined standardizer XML. The resulting structures are output into a new BLOB column, as well as the index and name of standardizer tasks into two new columns. However, the user must change the new BLOB column to be a structure rendered after the script has completed. Doing this automatically from within a script requires calling the column XML file and performing a complicated replacement. This is currently in development. However, there is a pop up window at the end of the script which prompts the user to do so.
/** Table Standardizer
*
* @author Erin Bolstad (ebolstad@chemaxon.com)
* Dec 2011
*/
import chemaxon.formats.MolExporter
import chemaxon.reaction.Standardizer
import com.im.commons.db.ddl.DBDatabaseInfo.ColumnSQLType;
import com.im.commons.progress.*
import com.im.df.api.capabilities.*
import com.im.df.api.support.*
import com.im.df.api.util.DIFUtilities
import groovy.swing.SwingBuilder
import java.awt.*
import javax.swing.*
def ety = dataTree.rootVertex.entity
def edp = ety.schema.dataProvider.getEntityDataProvider(ety)
def rows = edp.getRowCount(env)
def rs = ety.schema.dataProvider.getDefaultResultSet(dataTree, false, DFEnvironmentRO.DEV_NULL)
def parentVS = rs.getVertexState(dataTree.rootVertex)
def ids = parentVS.ids
println "Entity has $rows rows"
// Prompt for name of structure column and output column
def colInputs = new SwingBuilder()
colInputs.setVariable('properties',[:])
def vars = colInputs.variables
def frame = colInputs.dialog(title:'Column Constructor', modal:true) {
panel () {
gridBagLayout()
label(text:"Use this window to build or specify the input and output columns of the standardizing script.", constraints:gbc(
gridy:0,
gridwidth:2,
insets:[20,10,0,10]))
label(text:"You will then be prompted for a standardization configuration XML", constraints:gbc(
gridy:1,
gridwidth:2,
insets:[5,10,30,10]))
label(text:"Input existing structure column name", constraints:gbc(
gridx:0,
gridy:2,
insets:[2,10,2,10]))
textField(id:'origStruc', text:"Structure", name:"Original Structure", constraints:gbc(
gridx:1,
gridy:2,
fill:GridBagConstraints.HORIZONTAL,
insets:[2,10,2,10]))
label(text:"Check the box if the column needs to be created, otherwise, enter the existing name", constraints:gbc(
gridwidth:2,
gridy:5,
insets:[28,10,5,10]))
checkBox(id:'ssCheck', text:"Standardized Structures",
horizontalTextPosition: SwingConstants.LEFT, constraints:gbc(
gridx:0,
gridy:6,
anchor:LINE_END,
insets:[2,10,2,10]))
textField(id:'ssName', text:"Standardized Structure", constraints:gbc(
gridx:1,
gridy:6,
fill:GridBagConstraints.HORIZONTAL,
insets:[2,10,2,10]))
checkBox(id:'apTaskIndexCheck', text:"Applied Task Indices",
horizontalTextPosition: SwingConstants.LEFT, constraints:gbc(
gridx:0,
gridy:7,
anchor:LINE_END,
insets:[2,10,2,10]))
textField(id:'apTaskIndexName', text:"Applied Task Indicies", constraints:gbc(
gridx:1,
gridy:7,
fill:GridBagConstraints.HORIZONTAL,
insets:[2,10,2,10]))
checkBox(id:'apTaskCheck', text:"Applied Tasks",
horizontalTextPosition: SwingConstants.LEFT, constraints:gbc(
gridx:0,
gridy:8,
anchor:LINE_END,
insets:[2,10,2,10]))
textField(id:'apTaskName', text:"Applied Tasks", constraints:gbc(
gridx:1,
gridy:8,
fill:GridBagConstraints.HORIZONTAL,
insets:[2,10,2,10]))
button(id:'run', label: "Standardize!", constraints:gbc(
gridx:0,
gridy:9,
anchor:LINE_END,
insets:[10,0,10,0]),
actionPerformed: {
vars.buttonResults = 'ok'
dispose()})
button(id:'cancel', label: "Cancel", constraints:gbc(
gridx:1,
gridy:9,
anchor:LINE_START,
insets:[10,0,10,0]),
actionPerformed: {
vars.buttonResults = 'quit'
dispose()})
}
}
frame.pack()
frame.setLocationRelativeTo(null)
frame.show()
def chosenAction = vars.buttonResults
if (chosenAction == 'quit') {
return
}
if (chosenAction == 'ok') {
origStrucCol = vars.origStruc.text
ssColCheck = vars.ssCheck.selected
ssColName = vars.ssName.text
apTaskIndxCheck = vars.apTaskIndexCheck.selected
apTaskIndexColName = vars.apTaskIndexName.text
apTaskColCheck = vars.apTaskCheck.selected
apTaskColName = vars.apTaskName.text
}
// Create the fields if need be
def lock = DIFUtilities.getLockable(dataTree).obtainLock('Standardizing')
def envRW = EnvUtils.createDefaultEnvironmentRW(lock, 'Standardizing', true)
def fldMol = ety.fields.items.find { it.name == origStrucCol }
try {
if (!ssColCheck) {
FLDSTSTRUC = ety.fields.items.find { it.name == ssColName }
if (FLDSTSTRUC == null) {
print "Column $ssColName not found! Quitting...\n"
return
}
} else {
def Class[] req1 = [ DBFieldCapability.class, DFFieldTextCapability.class ]
def nt = DIFUtilities.findFirstAppropriateNewType(ety.getFields().getNewTypes(), false, req1, new Class[0]);
nt.options.newDFItemNameSafe = ssColName
def col = nt.options.columns[0];
def nativeTypeBlob = null;
// search for BLOB native type
for (def nativeType : col.allNativeTypeDefinitions) {
if (nativeType.columnType == ColumnSQLType.BLOB) {
nativeTypeBlob = nativeType;
}
}
if (nativeTypeBlob != null) {
// resize default BLOB native type and assign it to column type definition
col.nativeTypeDefinition = nativeTypeBlob.reSize(20000);
}
def newBinField = nt.create(envRW).iterator().next()
FLDSTSTRUC = ety.fields.items.find { it.name == ssColName }
}
if (!apTaskColCheck) {
FLDAPTASKS = ety.fields.items.find { it.name == apTaskColName }
if (FLDAPTASKS == null) {
print "Column $apTaskColName not found! Quitting... \n"
return
}
} else {
def Class[] req = [ DFFieldTextCapability.class ]
nt = DIFUtilities.findFirstAppropriateNewType(ety.getFields().getNewTypes(), false, req, new Class[0]);
nt.options.newDFItemNameSafe = apTaskColName
assert nt.options.valid : 'Error: ' + nt.options.errorMessage
def appliedTasksField = nt.create(envRW).iterator().next()
FLDAPTASKS = ety.fields.items.find { it.name == apTaskColName }
}
if (!apTaskIndxCheck) {
FLDAPTASKINDEX = ety.fields.items.find { it.name == apTaskIndexColName }
if (FLDAPTASKINDEX == null) {
Print "Column $apTaskIndexColName not found! Quitting... \n"
return
}
} else {
def Class[] req2 = [ DFFieldTextCapability.class ]
nt = DIFUtilities.findFirstAppropriateNewType(ety.getFields().getNewTypes(), false, req2, new Class[0]);
nt.options.newDFItemNameSafe = apTaskIndexColName
assert nt.options.valid : 'Error: ' + nt.options.errorMessage
def appliedTaskIndex = nt.create(envRW).iterator().next()
FLDAPTASKINDEX = ety.fields.items.find { it.name == apTaskIndexColName }
}
// Input the standardizer XML
def chooser = new JFileChooser()
chooser.setDialogTitle('Select XML file containing the standardization rules')
if (chooser.showOpenDialog(null)==JFileChooser.APPROVE_OPTION) {
File fileName = chooser.getSelectedFile()
FILENAME = fileName
NAME = fileName.getCanonicalPath()
} else {
return }
def standFile = FILENAME
print "Standardization file is $standFile \n"
}finally{
lock?.release()
envRW?.feedback.finish()
}
def lock2 = edp.lockable.obtainLock('inserting data')
def envRW2 = EnvUtils.createDefaultEnvironmentRW(lock2, 'Standardizing', true)
try {
def standFile = FILENAME
def fldStStruc = FLDSTSTRUC
def fldApTasks = FLDAPTASKS
def fldApTaskIndex = FLDAPTASKINDEX
ids.each { id ->
// Get mol from table
def molData = parentVS.getData([id], DFEnvironmentRO.DEV_NULL)
getMol = molData[id][fldMol.id]
nativeMol = getMol.getNative()
Standardizer standardizer = new Standardizer(standFile)
standardizer.setFinalClean()
def molStr = MolExporter.exportToFormat(nativeMol, "mol")
vals = [(fldStStruc.id):molStr]
String [] stanIDs = standardizer.getAppliedTaskIDs()
String results
n=0
for (String item: stanIDs) {
if (n==0) {
results = item
n++
} else{
results = results + ', ' + item
}}
vals.putAt(fldApTasks.id, results)
String [] stanIndex = standardizer.getAppliedTaskIndexes()
String resultsidx
m=0
for (String item: stanIndex) {
if (m==0) {
resultsidx = item
m++
} else {
resultsidx = resultsidx + ', ' + item
}}
vals.putAt(fldApTaskIndex.id, resultsidx)
DFUpdateDescription ud = DFUpdateDescription.create(ety, id, vals)
submitList = new Collections ()
submitList = submitList.singletonList(ud)
edp.update(submitList, DFUndoConfig.OFF, envRW2)
print "Finished standardizing ID $id \n"
}
}finally{
lock2?.release()
envRW2?.feedback.finish()
}
def message = "Standardization of table is complete! \n \n You will need to convert the standardized structure column to a structure renderer: \n Right click on the column title and select Customize Widget Settings. \n In the table that pops up, Column Properties will be open. Change 'Cell Renderer' to 'Structure Renderer' \n \n For ease of reading, you may want to change the Applied Tasks/ID columns to a multi-line renderer."
JOptionPane.showMessageDialog(null, message, "Finished!", JOptionPane.INFORMATION_MESSAGE)