Skip to content

Commit

Permalink
SVG and (#17)
Browse files Browse the repository at this point in the history
* move from magrittr to base r

* fix imports and add url

* update docs and Description

* style pkgdown

* add orcid

* rename

* update depict for rxn check

* add rxn smiles test

* style pass

* update allowable classes

* add a get_svg_string function

* add icon

* update to use SVG strings directly

* use cat to get cleaner vignette

---------

Co-authored-by: Zachary Charlop-Powers <[email protected]>
  • Loading branch information
zachcp and Zachary Charlop-Powers authored Mar 3, 2024
1 parent 1801a98 commit 5c2b5e0
Show file tree
Hide file tree
Showing 24 changed files with 320 additions and 267 deletions.
18 changes: 11 additions & 7 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
Package: depict
Type: Package
Title: Draw Beautiful Molecular Structures
Version: 0.3.1
Authors@R: c(person('Zachary', 'Charlop-Powers', role=c('cre','aut',"cph"), email='[email protected]'))
Version: 0.4.0
Authors@R: c(
person('Zachary', 'Charlop-Powers', ,'[email protected]',role=c('cre'),
comment = c(ORCID = "0000-0001-8816-4680")))
Description: Generate images of molecules using the Depiction API of the 'Chemistry Development Kit'.
CDK's Depict Api
License: LGPL
LazyData: TRUE
Depends:
rJava (>= 1.0-6),
rJava (>= 1.0-11),
rcdk (>= 3.7),
rcdklibs (>= 2.8)
Imports:
png,
magrittr
RoxygenNote: 7.2.2
png
RoxygenNote: 7.3.1
Encoding: UTF-8
URL: https://cdk-r.github.io/depict/
Suggests:
knitr,
magrittr,
rmarkdown,
testthat
testthat,
VignetteBuilder: knitr
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export(color_atoms)
export(depict)
export(depiction)
export(get_image)
export(get_svg_string)
export(highlight_atoms)
export(match_smarts)
export(outerglow)
Expand Down
19 changes: 7 additions & 12 deletions R/IO.R
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,25 @@
#' @param kekulise Optional. Boolean. Default \code{TRUE}
#' @export
#'
parse_smiles <- function(smi, generatecoords=TRUE, kekulise=TRUE) {

parse_smiles <- function(smi, generatecoords = TRUE, kekulise = TRUE) {
SmilesParser <- J("org.openscience.cdk.smiles.SmilesParser")
SChemObjectBuilder <- J("org.openscience.cdk.silent.SilentChemObjectBuilder")
StructureDiagramGenerator <- J("org.openscience.cdk.layout.StructureDiagramGenerator")

sinst <- SChemObjectBuilder$getInstance()
sp <- new(SmilesParser, sinst)
sp <- new(SmilesParser, sinst)
sp$kekulise(kekulise)
mol <- sp$parseSmiles(smi)

mol <- sp$parseSmiles(smi)

if (generatecoords) {
sdg <- new(StructureDiagramGenerator)
sdg <- new(StructureDiagramGenerator)
sdg$setMolecule(mol)
sdg$generateCoordinates()
mol <- sdg$getMolecule()
}

mol

}

#' read_mol
Expand All @@ -39,16 +37,13 @@ parse_smiles <- function(smi, generatecoords=TRUE, kekulise=TRUE) {
#' @return an AtomContainer
#' @export
read_mol <- function(molfile) {

jAtomContainer <- J("org.openscience.cdk.AtomContainer")

jfileobj <- .jnew("java.io.File", molfile)
jfileobj <- .jnew("java.io.File", molfile)
jreaderobj <- .jnew("java.io.FileReader", jfileobj)
jmolreader <- .jnew("org.openscience.cdk.io.MDLV2000Reader")
AC <- .jnew("org.openscience.cdk.AtomContainer")
AC <- .jnew("org.openscience.cdk.AtomContainer")

jmolreader$setReader(jreaderobj)
jmolreader$read(AC)

}

79 changes: 58 additions & 21 deletions R/depict.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ depiction <- function() {
#' color atoms
#'
#' set the atom color
#'
#'
#' @param dg a CDK DepictionGenerator
#' @seealso \url{https://cdk.github.io/cdk/latest/docs/api/org/openscience/cdk/depict/DepictionGenerator.html}
#' @export
Expand Down Expand Up @@ -45,7 +45,7 @@ set_size <- function(dg, width, height) {
stop("set_size requires a Depiction Generator")
}

dg$withSize(width,height)
dg$withSize(width, height)
}

#' add_title
Expand All @@ -54,7 +54,6 @@ set_size <- function(dg, width, height) {
#' @seealso \url{https://cdk.github.io/cdk/latest/docs/api/org/openscience/cdk/depict/DepictionGenerator.html}
#' @export
add_title <- function(dg) {

if (!checkJavaClass(dg, "org/openscience/cdk/depict/DepictionGenerator")) {
stop("add_title requires a Depiction Generator")
}
Expand Down Expand Up @@ -86,24 +85,30 @@ add_terminal_carbons <- function(dg) {
#' @param mol Required. An AtomContainer
#' @seealso \url{https://cdk.github.io/cdk/latest/docs/api/org/openscience/cdk/depict/DepictionGenerator.html}
#' @seealso \url{https://cdk.github.io/cdk/latest/docs/api/org/openscience/cdk/AtomContainer.html}
#'
#'
#' @export
depict <- function(dg, mol) {
if (!checkJavaClass(dg, "org/openscience/cdk/depict/DepictionGenerator")) {
print(.jclass(dg))
stop("depict requires a Depiction Generator")
}

if (!checkJavaClass(mol, c("org/openscience/cdk/AtomContainer",
"org/openscience/cdk/AtomContainer2",
"org/openscience/cdk/silent/AtomContainer",
"org/openscience/cdk/silent/AtomContainer2",
"org/openscience/cdk/silent/IAtomContainer",
"java/util/ArrayList"
))) {
stop("depict requires an AtomContainer or an ArrayList of them")
}

#.jcall(dg, "Lorg/openscience/cdk/depict/Depiction;", "depict", mol)
if (!checkJavaClass(mol, c(
"org/openscience/cdk/AtomContainer",
"org/openscience/cdk/AtomContainer2",
"org/openscience/cdk/Reaction",
"org/openscience/cdk/ReactionSet",
"org/openscience/cdk/silent/AtomContainer",
"org/openscience/cdk/silent/AtomContainer2",
"org/openscience/cdk/silent/IAtomContainer",
"org/openscience/cdk/silent/Reaction",
"org/openscience/cdk/silent/ReactionSet",
"java/util/ArrayList"
))) {
stop("depict requires an AtomContainer, Reaction, ReactionSet, or an ArrayList of them")
}

# .jcall(dg, "Lorg/openscience/cdk/depict/Depiction;", "depict", mol)
dg$depict(mol)
}

Expand Down Expand Up @@ -131,7 +136,10 @@ highlight_atoms <- function(dg, atoms, color) {
#' @param outfile Required. Filepath to the output
#' @export
save_image <- function(molgrid, filepath) {
if (!checkJavaClass(molgrid, "org/openscience/cdk/depict/MolGridDepiction")) {
if (!checkJavaClass(molgrid, c(
"org/openscience/cdk/depict/MolGridDepiction",
"org/openscience/cdk/depict/ReactionDepiction"
))) {
stop("highlight_atoms requires a Depiction Generator")
}
molgrid$writeTo(filepath)
Expand All @@ -148,13 +156,17 @@ save_image <- function(molgrid, filepath) {
#' @export
#'
get_image <- function(molgrid) {
if (!checkJavaClass(molgrid, "org/openscience/cdk/depict/MolGridDepiction")) {
stop("highlight_atoms requires a Depiction Generator")
if (!checkJavaClass(molgrid, c(
"org/openscience/cdk/depict/MolGridDepiction",
"org/openscience/cdk/depict/ReactionDepiction"
))) {
print(.jclass(molgrid))
stop("get_image requires a Depiction")
}

# CDK apends a ".png" to the name
output <- paste(tempfile(),"png")
output1 <- paste0(output,".png")
output <- paste(tempfile(), "png")
output1 <- paste0(output, ".png")

molgrid$writeTo("png", output)
img <- readPNG(output1)
Expand All @@ -165,6 +177,31 @@ get_image <- function(molgrid) {
img
}

#' get_svg_string
#'
#' @param molgrid Required. A MolGridDepiction. Usually obtained from
#' the \code{depict} function.
#' @returns an SVG string literal
#' @export
get_svg_string <- function(molgrid) {
if (!checkJavaClass(molgrid, c(
"org/openscience/cdk/depict/MolGridDepiction",
"org/openscience/cdk/depict/ReactionDepiction"
))) {
print(.jclass(molgrid))
stop("get_image requires a Depiction")
}

# svg_str <- grid$toSvgStr()
svg_str <- .jcall(molgrid, 'S' ,'toSvgStr')

svg_list <- strsplit(svg_str, "\n")[[1]]

# return the svg without the two header lines
paste(svg_list[3:length(svg_list)], collapse="\n")
}


#' set_zoom
#'
#' set_zoom
Expand All @@ -173,7 +210,7 @@ get_image <- function(molgrid) {
#' @param zoom Optional. Default \code{1}
#' @export
#'
set_zoom <- function(dg, zoom=1) {
set_zoom <- function(dg, zoom = 1) {
if (!checkJavaClass(dg, "org/openscience/cdk/depict/DepictionGenerator")) {
stop("highlight_atoms requires a Depiction Generator")
}
Expand Down
34 changes: 15 additions & 19 deletions R/selection_functions.R
Original file line number Diff line number Diff line change
@@ -1,58 +1,54 @@
#' match_smarts
#'
#'
#' Find matches to a given molecule using a SMARTs pattern.
#'
#' @param smarts a SMARTS string
#' @param mol a CDK IAtomContainer or a java.util.Arraylist of them
#' @param limit limit of the number of matches
#'
#'
#' @seealso \url{https://cdk.github.io/cdk/latest/docs/api/org/openscience/cdk/isomorphism/Mappings.html}
#' @seealso \url{https://cdk.github.io/cdk/latest/docs/api/org/openscience/cdk/smiles/smarts/SmartsPattern.html}
#'
#'
#' @return a hashset of atoms and bonds
#' @export
#'
#'
match_smarts <- function(smarts, mol, limit=10) {


hashset <- J("java/util/HashSet")
#'
match_smarts <- function(smarts, mol, limit = 10) {
hashset <- J("java/util/HashSet")
smartspattern <- J("org/openscience/cdk/smiles/smarts/SmartsPattern")
spattern <- smartspattern$create(smarts, NULL)
spattern <- smartspattern$create(smarts, NULL)

# handle the base case first
if (!.jclass(mol) == "java.util.ArrayList") {

matches <- spattern$matchAll(mol)
matches <- matches$limit(as.integer(limit))
# Note: switching below to chemobjects due to reflection access with the atom-bond map
# atombondmap <- matches$uniqueAtoms()$toAtomBondMap()
atombonds <- matches$uniqueAtoms()$toChemObjects()
atombonds <- matches$uniqueAtoms()$toChemObjects()

# somewhat convoluted code to get all of the matching atoms
highlight <- new(hashset)

for (l in as.list(atombonds)) {
highlight$add(l)
}
# then handle the array list of atom containers

# then handle the array list of atom containers
} else {

# somewhat convoluted code to get all of the matching atoms
highlight <- new(hashset)

for (atmcont in as.list(mol)) {
matches <- spattern$matchAll(atmcont)
matches <- matches$limit(as.integer(limit))
# Note: switching below to chemobjects due to reflection access with the atom-bond map
# atombondmap <- matches$uniqueAtoms()$toAtomBondMap()
atombonds <- matches$uniqueAtoms()$toChemObjects()
atombonds <- matches$uniqueAtoms()$toChemObjects()
for (l in as.list(atombonds)) {
highlight$add(l)
}
}
}

highlight
}
20 changes: 9 additions & 11 deletions R/smarts.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,20 @@
#' @seealso \url{http://www.daylight.com/dayhtml/doc/theory/theory.smarts.html}
#' @seealso \url{http://www.daylight.com/dayhtml_tutorials/languages/smarts/index.html}
#' @export
#'
#'
#'
amino_acids <- function() {
list(
# Generic amino acid: low specificity.
amino_acids="[NX3,NX4+][CX4H]([*])[CX3](=[OX1])[O,N]", #For use w/ non-standard a.a. search. hits pro but not gly. Hits acids and conjugate bases. Hits single a.a.s and specific residues w/in polypeptides (internal, or terminal).
amino_acids = "[NX3,NX4+][CX4H]([*])[CX3](=[OX1])[O,N]", # For use w/ non-standard a.a. search. hits pro but not gly. Hits acids and conjugate bases. Hits single a.a.s and specific residues w/in polypeptides (internal, or terminal).

# A.A. Template for 20 standard a.a.s
amino_acids20="[$([$([NX3H,NX4H2+]),$([NX3](C)(C)(C))]1[CX4H]([CH2][CH2][CH2]1)[CX3](=[OX1])[OX2H,OX1-,N]),
amino_acids20 = "[$([$([NX3H,NX4H2+]),$([NX3](C)(C)(C))]1[CX4H]([CH2][CH2][CH2]1)[CX3](=[OX1])[OX2H,OX1-,N]),
$([$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX4H2][CX3](=[OX1])[OX2H,OX1-,N]),$([$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX4H]([*])[CX3](=[OX1])[OX2H,OX1-,N])]",

proline="[$([NX3H,NX4H2+]),$([NX3](C)(C)(C))]1[CX4H]([CH2][CH2][CH2]1)[CX3](=[OX1])[OX2H,OX1-,N]",
glycine="[$([$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX4H2][CX3](=[OX1])[OX2H,OX1-,N])]",
amino_acids18="[$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX4H]([*])[CX3](=[OX1])[OX2H,OX1-,N]",

alanine="[$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX4H]([CH3X4])[CX3](=[OX1])[OX2H,OX1-,N]",
proline = "[$([NX3H,NX4H2+]),$([NX3](C)(C)(C))]1[CX4H]([CH2][CH2][CH2]1)[CX3](=[OX1])[OX2H,OX1-,N]",
glycine = "[$([$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX4H2][CX3](=[OX1])[OX2H,OX1-,N])]",
amino_acids18 = "[$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX4H]([*])[CX3](=[OX1])[OX2H,OX1-,N]",
alanine = "[$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX4H]([CH3X4])[CX3](=[OX1])[OX2H,OX1-,N]",

# $([CH2X4][CX3](=[OX1])[NX3H2]),
# $([CH2X4][CX3](=[OX1])[OH0-,OH]),
Expand All @@ -38,6 +36,6 @@ amino_acids <- function() {
# $([CH2X4][cX3]1[cX3H][nX3H][cX3]2[cX3H][cX3H][cX3H][cX3H][cX3]12),
# $([CH2X4][cX3]1[cX3H][cX3H][cX3]([OHX2,OH0X1-])[cX3H][cX3H]1),
# $([CHX4]([CH3X4])[CH3X4])
amino_acids18="[$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX4H]([*])[CX3](=[OX1])[OX2H,OX1-,N]"
)
amino_acids18 = "[$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX4H]([*])[CX3](=[OX1])[OX2H,OX1-,N]"
)
}
9 changes: 4 additions & 5 deletions R/utilities.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
#' @param jobj Required. A Java Object
#' @param klass Required. A string defining a java class
#' @return Boolean
checkJavaClass <- function(jobj, klass ) {
checkJavaClass <- function(jobj, klass) {
if (is.null(attr(jobj, 'jclass'))) stop("this is not a Java Object")

for (k in klass ) {
if (attr(jobj, "jclass") == k) {
for (kl in klass) {
if (attr(jobj, "jclass") == kl) {
return(TRUE)
}
}
Expand Down Expand Up @@ -40,8 +40,7 @@ checkJavaClass <- function(jobj, klass ) {
atomcontainer_list_to_jarray <- function(atomcontainers) {

new_array <- .jnew('java.util.ArrayList')

for (atmcntnr in atomcontainers) {
for (atmcntnr in as.list(atomcontainers)) {
new_array$add(atmcntnr)
}

Expand Down
4 changes: 0 additions & 4 deletions _pkgdown.yml

This file was deleted.

Binary file added man/figures/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions man/get_svg_string.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 5c2b5e0

Please sign in to comment.