chemdoodle icon indicating copy to clipboard operation
chemdoodle copied to clipboard

add a sketcher canvas

Open zachcp opened this issue 9 years ago • 18 comments
trafficstars

In response to https://github.com/ramnathv/htmlwidgets/issues/192, a sketcher canvas should be made.

I pencilled out a sketcher but for some reason the toolbar is not working. Not sure why. I need t olook under the hood a bit and see if we can figure out a fix.

Basic plan:

  1. fix toolbar to allow basic editing funcitonality.
  2. add a button that will convert the sketcher to Chemdoodle JSON
  3. Write an R function to receive the JSON and convert it it a CDK AtomContainer for downstream activity including SMILES/SMARTS/Molfile.

zachcp avatar Mar 14 '16 17:03 zachcp

For some reason, it appears chemdoodle wants the <script> to create the sketcher within the div in which you plan to create it. So, this is unworkable, but you can add something like this to chemdoodle_sketcher.R and rebuild. I need to dig a little to see how to bind the sketcher to another element. I'm not familiar with this design.

#' @import htmltools
chemdoodle_sketcher_html <- function(id, style, class, ...){
  tagList(
    tags$div(
      id = id,
      class = class,
      style = style,
      tags$script(
        "
  ChemDoodle.ELEMENT['H'].jmolColor = 'black';
  ChemDoodle.ELEMENT['S'].jmolColor = '#B9A130';
  var sketcher = new ChemDoodle.SketcherCanvas('sketcher', 350, 250,{useServices:true, oneMolecule:true});
  sketcher.specs.atoms_displayTerminalCarbonLabels_2D = true;
  sketcher.specs.atoms_useJMOLColors = true;
  sketcher.specs.bonds_clearOverlaps_2D = true;
  sketcher.specs.bonds_overlapClearWidth_2D = 2;
  sketcher.repaint();
  function alertMolecule(mol){
    var message = 'This molecule contains '+mol.atoms.length+' atoms and '+mol.bonds.length+' bonds.';
    alert(message);
  }
"        
      )
    )
  )
}

timelyportfolio avatar Mar 14 '16 21:03 timelyportfolio

@timelyportfolio excuse the basic question, but where would one put this new re-build function?

I checked out the repo as a new project in RStudio and added this function to the end of chemdoodle_sketcher.R. After saving the updated file, I used the devtools::install() command to install the library.

The toolbar still isn't visible.

Is there anywhere else I should've modified or copied the function to somewhere else?

Thanks!

iainmwallace avatar Mar 16 '16 02:03 iainmwallace

@iainmwallace I just pushed a version that applies @timelyportfolio 's helpful (and correct) addition. The sketcher launches. See if you can wire up the rest. I can help out too. But now it should be possible to copy/use the existing code!

thanks @timelyportfolio ! I would not have figured that out in any reasonable amount of time. Much obliged.

zachcp avatar Mar 16 '16 02:03 zachcp

@zachcp, @timelyportfolio Looks great! Not sure why what I was doing didn't work but I will learn :)

If you could figure out how to pass the molFile variable back to R, I can certainly wire the R code together.

var mol = sketcher.getMolecule(); var molFile = ChemDoodle.writeMOL(mol); alert(molFile);

iainmwallace avatar Mar 16 '16 14:03 iainmwallace

the latest commit should have a minimal working example:

#the following should open up a sketcher gadget
mol <- drawMolecule()

For this to work, you need to:

  1. draw something in the sketcher
  2. press on the "Get Molecule Data" button on the bottom (you will see an alert if successful)
  3. press "Done"
  4. the result will be stored as an R object.

A few things need to be improved:

  1. Can we get rid of the tow buttons and just press "Done". Something about the reactive handling was getting in my way. You can see i have commented out code to capture the values on pressing "Done". However,that does not work. I think the 'stopapp' precludes updating the input$moleculedata so nothing is returned. Any suggestions here @timelyportfolio ? One button with fewer clicks is definitely better.
  2. some GUI/layout love (but that is the fun part).
  3. The code to handle the JSON object (sorry @iainmwallace but I couldn't get R to properly handle the MoL file - I had to convert to JSON. But you should be good to go for writing a parse to handle molecule JSON)

zachcp avatar Mar 17 '16 03:03 zachcp

Thanks Zach!

I modified the script to return the MDL file as below, but unfortunately there is actually a bug in the chemdoodle MDL parser which means it doesn't return a correct MDL file that we can use with rcdk.

I have opened up a bug report and will let you know if they fix it. https://support.ichemlabs.com/tickets.php?id=331576

"tags$script(' document.getElementById("getdata").onclick = function() { var mol = sketcher.getMolecule(); var my_mdl = ChemDoodle.writeMOL(mol) var jsonmol = new ChemDoodle.io.JSONInterpreter().molTo(mol); alert(my_mdl); Shiny.onInputChange("moleculedata", my_mdl);};') )

I will try and figure out how to parse the chemdoodle json file.

iainmwallace avatar Mar 17 '16 15:03 iainmwallace

Ok, the latest pull adds parsing for the Chemdoodle JSON. That took longer than I thought as I had to grok rJAVA syntax a bit better and I run into a few issues at the R-Java interface. In any event we can now parse the Chemdoodle JSON and return a CDK AtomContianer. See the Readme.

@iainmwallace is there anything in particular you want to do with the molecule once parsed? It should now be possible to do just about anything you want within the capability of CDK. (the functions will need to be written of course.) SMILES writing? Molfile writing? Querying? It would be nice to have a handful of useful workflows. Then I could see writing a vignette and consider packaging this up.

zach cp

zachcp avatar Mar 18 '16 16:03 zachcp

@zachcp brilliant!

Two basic workflows (via shiny app) would be draw structure -> convert to molecule -> similarity search against large sdf file/database draw structure -> convert to molecule -> create inchikey -> query unichem to find all database references to molecule

The latest pull works after I explicitly load rcdk and rcklibs

I am however getting an error when I try to use the mol object. get.smiles(mol)

Error in get.smiles(mol) : Supplied object should be a Java reference to an IAtomContainer

iainmwallace avatar Mar 18 '16 16:03 iainmwallace

@iainmwallace i'll try to write some functions along these lines this weekend but we will need to write the functions to convert the AtomContainers to SMILES or INCHI. At that point your molecule has been reduced to a small string which can then be queried in many ways against many targets.

I think a reasonable scope for this package is to return a generically useful format for a molecule that has been sketched (SMILES, INCHI, AtomContainer) and leave the true chemoinformatics work for rCDK or some other package. That being said, having a "full-stack" working example would be a great idea. Are your databases local or in a webservice somewhere?

zach cp

zachcp avatar Mar 18 '16 17:03 zachcp

@zachcp That would be great!

I think you are right the about the scope - if it returns the rCDK molecule we can do all the cheminformatics work in rCDK, and full stack examples would be very useful.

The database could be local - a smiles file that we parse and convert to rCDK molecules But there are also web services that we could show nice examples of. For example, ChEMBL has a webservice, https://www.ebi.ac.uk/chembl/api/data/docs, that takes in a smiles string and a similarity threshold and returns the matches as a rest service.

Just as an FYI, when I load the library, there are lots of warnings like this Warning: replacing previous import by ‘shiny::HTML’ when loading ‘chemdoodle’

Also, there is another package that is also very nice for cheminfomatics in R, http://chemminetools.ucr.edu/about/, which might provide some more inspiration about workflows/use cases.

On Fri, Mar 18, 2016 at 1:39 PM, zachcp [email protected] wrote:

@iainmwallace https://github.com/iainmwallace i'll try to write some functions along these lines this weekend but we will need to write the functions to convert the AtomContainers to SMILES or INCHI. At that point your molecule has been reduced to a small string which can then be queried in many ways against many targets.

I think a reasonable scope for this package is to return a generically useful format for a molecule that has been sketched (SMILES, INCHI, AtomContainer) and leave the true chemoinformatics work for rCDK or some other package. That being said, having a "full-stack" working example would be a great idea. Are your databases local or in a webservice somewhere?

zach cp

— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/zachcp/chemdoodle/issues/1#issuecomment-198465884

iainmwallace avatar Mar 18 '16 18:03 iainmwallace

Looks like all the roxygen stuff is messed up, and that explains all the warnings. If we don't have time to document all the functions, maybe we should just remove all this to avoid the errors/warnings.

timelyportfolio avatar Mar 18 '16 19:03 timelyportfolio

@timelyportfolio this is probably my fault. When roxygen documents this package it generates a loooong list of imports that I thought were largely mistakes. My not-very-sophisticated way of handling this was to delete all non-packages. It looks like rCDk and rcdklibs don't use autogeneration. Maybe this is a general problem of imports with rJava? ( I'm actually not familiar with Roxygen internals - I just follow what others have done.)

# Generated by roxygen2: do not edit by hand
export(chemdoodle_sketcher)
export(chemdoodle_sketcherOutput)
export(chemdoodle_slideshow)
export(chemdoodle_slideshowOutput)
export(chemdoodle_transform)
export(chemdoodle_transformOutput)
export(chemdoodle_viewer)
export(chemdoodle_viewerOutput)
export(drawMolecule)
export(processChemDoodleJson)
export(renderChemdoodle)
export(smiles_to_json)
import("#:")
import("2D")
import("Values:")
import("[butt,")
import("always,")
import("atoms,")
import("canvas,")
import("computer;")
import("depiction;")
import("families,")
import("for")
import("if")
import("in")
import("instance;")
import("loaded,")
import("ring,")
import("round,")
import("see-through")
import("specification,")
import("square],")
import(Allowed)
import(Jmol)
import(PyMOL)
import(WebGL)
import(a)
import(after)
import(all)
import(also)
import(and)
import(are)
import(array)
import(atom)
import(atoms)
import(background)
import(be)
import(been)
import(between)
import(bond)
import(bonds)
import(bonds_colorGradient)
import(by)
import(canvas)
import(carbon)
import(carbons)
import(cascade)
import(center)
import(circles)
import(color)
import(colors)
import(connected)
import(constituent)
import(controlled)
import(controls)
import(create)
import(default)
import(depiction)
import(diameter)
import(double)
import(draw)
import(drawn)
import(end)
import(families)
import(fill)
import(font)
import(found)
import(gradient)
import(has)
import(htmltools)
import(htmlwidgets)
import(hydrogens)
import(implicit)
import(instead)
import(is)
import(italicized)
import(labels)
import(lines)
import(miniUI)
import(molecule)
import(not)
import(of)
import(on)
import(pointing)
import(primitive)
import(rather)
import(relative)
import(render)
import(rendered)
import(repaint)
import(saturation)
import(scale)
import(scenes)
import(set)
import(shiny)
import(show)
import(size)
import(specification)
import(split)
import(style)
import(symmetrically)
import(terminal)
import(text)
import(than)
import(that)
import(the)
import(then)
import(this)
import(through)
import(to)
import(towards)
import(triple)
import(true)
import(two)
import(type)
import(undefined)
import(use)
import(users)
import(using)
import(visible)
import(width)
import(will)
importFrom(dplyr,"%>%")
importFrom(rcdk,generate.2d.coordinates)
importFrom(rcdk,get.atoms)
importFrom(rcdk,get.bonds)
importFrom(rcdk,parse.smiles)

zachcp avatar Mar 18 '16 19:03 zachcp

@iainmwallace the basic smiles functionality is done; see the readme.. it may need a little more work but the plumbing is in place.

zachcp avatar Mar 19 '16 02:03 zachcp

@zachcp just installed the latest commit and updated the rcdk/rcklibs to the github latest per the requirements.

Am getting this error now when I draw a benzene ring mol <- processChemDoodleJson(moljson) Error in .jcall("RJavaTools", "Ljava/lang/Object;", "invokeMethod", cl, : org.openscience.cdk.exception.NoSuchAtomTypeException: The AtomType C.sp3 could not be found

Downgrading to the CRAN available version of rcdklibs 1.5.8 the commands worked.

However there is an issue with the smiles string generated after drawing a molecule. Drawing benzene results in an incorrect smiles string of "[CH2].[CH2].[CH2].[CH3].[CH3].[CH3]"

Chemdoodle_viewer can correctly display benzene. chemdoodle_viewer('c1ccccc1')

iainmwallace avatar Mar 20 '16 15:03 iainmwallace

@iainmwallace I fixed the incorrect smiles issues: i was parsing the bonds incorrectly. SMILES for benzene now gives "C=1C=CC=CC1"

As for the Java issue, I am not sure exactly the issue but I am going to try to get rdklibs upgraded to 1.5.12 as there are improved CDK features that have been introduced over the past years which include faster SMILES parsing and an excellent image generation API.

I added the ability to pass data into the sketcher so that you can provide a molecule to the sketcher if you like, edit it and get it back. The problem now is scaling: if you add a molecule its all scrunched up. Basically the molecules need to be appropriately scaled in CDK before conversion.

zach cp

zachcp avatar Mar 20 '16 23:03 zachcp

@zachcp looks great, thanks! I like the new feature to pass the molecule back to the sketcher!

Examples worked for me. I will give it a spin this week and let you know what type of workflows I come up with. (Java problem must be on my end, seem to be fine now)

iainmwallace avatar Mar 21 '16 01:03 iainmwallace

thanks @iainmwallace . I'm going to have to slow down on this during the week but will keep chipping away at it. Also, I will try to get CDK 1.5.12 onto CRAN https://github.com/rajarshi/cdkr/issues/31

zachcp avatar Mar 21 '16 01:03 zachcp

cdk 1.5.13 now on CRAN. This should facilitate installing and using the new CDK features as a backend for the sketcher canvas

zachcp avatar May 16 '16 14:05 zachcp