Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SMARTSviewer #235

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ Imports:
dplyr,
purrr
Suggests:
testthat,
testthat (>= 2.1.0),
rcdk
RoxygenNote: 7.1.0
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export(pp_query)
export(ppdb)
export(ppdb_parse)
export(ppdb_query)
export(smarts_viewer)
export(smiles)
export(srs_query)
export(wd_ident)
Expand Down
19 changes: 1 addition & 18 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,28 +1,11 @@
webchem 0.6.0
======================

NEW FEATURES

MINOR IMPROVEMENTS

BUG FIXES

* get_csid() now returns all csids when queried from formula
* get_csid() returned an error when query was NA [PR #226, fixed by stitam]
* get_chebiid() and chebi_comp_entity() fixed for invalid queries [PR #225, fixed by stitam]
* get_cid() returned the PubChem ID of sodium when the query was NA [PR #223, fixed by stitam]
* aw_query() returned a list for successful queries, NA for unsuccessful queries [PR #222, fixed by stitam]

DEPRECATED FUNCTIONS

DEFUNCT FUNCTIONS

webchem 0.5.0
======================
Comment on lines -4 to -21
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible that you didn't update your branch before making changes? Our contributing guide contains more information about tracking upstream progress.


NEW FEATURES

* Retrieve data from ChEBI (https://www.ebi.ac.uk/chebi/) webservice with get_chebiid() and chebi_comp_entity(). ChEBI comprises a rich data base on chemicals with bilogical interest [contributed by @andschar].
* Submit a query to the ZBH Center for Bioinformatics' SMARTS viewer webservice at (https://smartsview.zbh.uni-hamburg.de) with smarts_viewer(). Retrieves images for plotting in R or downloads image in specified format [contributed by @gjgetzinger].
* Retrieve retention indices from NIST (https://webbook.nist.gov) with nist_ri() [PR #154, contributed by @Aariq]
* Get record details from US EPA Substance Registry Services (https://cdxnodengn.epa.gov/cdx-srs-rest/) with srs_query() [PR #179]
* "first" argument in cts_convert() and cir_query() and "interactive" argument in pc_synonyms() deprecated. Use "choices" instead to return either a list of all results, only the first result, or an interactive menu to choose a result to return. [contributed by @Aariq]
Expand Down
100 changes: 100 additions & 0 deletions R/smarts_viewer.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#' Query SMARTS Viewer
#'
#' Submit a query to the SMARTS viewer webservice at
#' \url{http://smartsview.zbh.uni-hamburg.de}, ZBH Center for Bioinformatics,
#' University of Hamburg
#'
#' @param smarts A SMARTS string to visualize
#' @param output The type of response generated (image or download). See
#' description for details.
#' @param image_format Image file format (pdf, png, or svg)
#' @param visualization_modus 1 or 2 (1 = Complete Visualization, 2 = Element
#' Symbols)
#' @param legend_option both, none, static, dynamic
#' @param filename Filename to use if output is to be downloaded
#'
#' @return Either a raster object (output = image) suitable for adding to an
#' R plot using \code{rasterImage} or the image is downloaded in the specified
#' format to the indicated filename.
#' @export
#'
#' @examples
#' \dontrun{
#' img <- smarts_viewer(
#' "[CX3](=[OX1])[OX2][CX3](=[OX1])",
#' "image", "png", 1, "both"
#' )
#' plot(0:1,0:1, 'n')
#' rasterImage(img[[1]],0,0,1,1)
Comment on lines +27 to +28
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just based on the name, I was expecting smarts_viewer() to automatically plot something when output = "image". It might be nice to have a default plot show up (maybe controlled by a view = TRUE argument) by including this plotting code in the function itself.

#'
#' smarts <- c("[CX3](=[OX1])[OX2][CX3](=[OX1])",
#' "[$([nr5]:[nr5,or5,sr5]),$([nr5]:[cr5]:[nr5,or5,sr5])]",
#' "[#6][$([NX2]=O),$(N=C=O),$(OC#N),$(SC#N)]"
#' )
#' img <- smarts_viewer(smarts, "image", "png", 1, "both")
#' par(mfcol = c(1,length(smarts)))
#' sapply(img, function(i){
#' plot(0:1,0:1, 'n')
#' rasterImage(i,0,0,1,1)
#' })
#'
#' smarts_viewer(
#' smarts, output = "download",
#' image_format = "pdf",
#' visualization_modus = 1,
#' legend_option = "both", filename = "test.pdf")
#' }
#'
smarts_viewer <-
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a function name like sv_view() would be more consistent with our guidelines for naming webchem functions. What do you think?

function(smarts,
output = c('image', 'download'),
image_format = c('pdf', 'png', 'svg'),
visualization_modus = c(1, 2),
legend_option = c('both', 'none', 'static', 'dynamic'),
filename = NULL) {
Comment on lines +49 to +54
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have some suggestion that might help streamline the API and address some of @stitam's concerns about downloading. Also, I was confused for a while because I couldn't get the download to work, and then I realized it was because I had output = "image" and supplied an image_format and filename (there's no warning for this situation).

Suggested change
function(smarts,
output = c('image', 'download'),
image_format = c('pdf', 'png', 'svg'),
visualization_modus = c(1, 2),
legend_option = c('both', 'none', 'static', 'dynamic'),
filename = NULL) {
function(smarts,
visualization_modus = c(1, 2),
legend_option = c('both', 'none', 'static', 'dynamic'),
filename = NULL) {

If filename = NULL (default) then only the png data is downloaded and returned as an R object (same as output = 'image'). If filename is anything else, the function can attempt to write a file. The file type can be taken from the file extension in filename as is done in cowplot::save_plot().

entity_url <- "https://smartsview.zbh.uni-hamburg.de/auto"
if(output == 'download' & is.null(filename)){
stop("Must provide a filename for output type 'download'.")
}
if (length(smarts) > 1 &
output == 'download') {
message(
paste(
"Warning:",
"Multiple SMARTS strings entered with output option = download.",
"One file per SMARTS string will be downloaded automatically.",
sep = '\n'
)
)
resp <- NA
while (!resp %in% c("Y", "N", "y", "n")) {
resp <- readline(prompt = "Do you wish to continue? (Y/N)")
}
stopifnot(tolower(resp) == 'y')
}

lapply(seq(along = smarts), function(x) {
entity_query <-
paste(entity_url,
image_format,
visualization_modus,
legend_option,
utils::URLencode(smarts[x], T),
sep = '/')
response <- httr::GET(entity_query)
if (response$status_code == 200) {
if (output == 'image') {
httr::content(response, as = 'parsed', type = 'Image/png')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I try to run the first example with image_format = "svg" or "pdf" the function returns

 Error in png::readPNG(x) : libpng error: Not a PNG file

and Traceback points to httr::content() and httr::GET(). Could this be related to type = "image/png"?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also get this error.

} else {
utils::download.file(url = response$url,
destfile = gsub(
pattern = paste0('.', image_format),
paste0('_', x, '.', image_format),
filename
))
Comment on lines +89 to +94
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While being able to export the image from R is a very good idea, I am not sure if this should be handled by the smarts_viewer() function. Alternatively, smarts_viewer() could query the url and always return a plot or a list of plots, and then these plots could be exported by standard R functions. What do you think?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this would work, as I think only the PNG version can be stored as an R object. If you were to implement this, you'd probably want to have one function that outputs the image data as a matrix with class smarts (for example) and store the query info as attributes. Then, when you run the hypothetical smarts_save() function on a smarts object, it would save the PNG or re-query the database if filetype was .pdf or .svg.

}
} else {
stop(httr::http_status(response)$message)
}
})
}
7 changes: 7 additions & 0 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,14 @@ smiles(wi)
# smiles(etox_basic(5564))
```

#### SMARTS Viewer
Render a depiction of a SMARTS string (\url{https://www.daylight.com/dayhtml/doc/theory/theory.smarts.html}) by submitting a query to the SMARTS viewer web service at \url{http://smartsview.zbh.uni-hamburg.de}, ZBH Center for Bioinformatics, University of Hamburg.

```{r smartsviewer}
smarts_viewer("[CX3](=[OX1])[OX2][CX3](=[OX1])","image", "png", 1, "both")
plot(0:1,0:1, 'n')
rasterImage(img[[1]],0,0,1,1)
```

#### Misc functions

Expand Down
68 changes: 68 additions & 0 deletions man/smarts_viewer.Rd

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

13 changes: 13 additions & 0 deletions tests/testthat/test-smartsview.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
context("smartsview")

a <- smarts_viewer("[CX3](=[OX1])[OX2][CX3](=[OX1])", "image", "png", 1, "both" )
b <- smarts_viewer("[CX3](=[OX1])[OX2][CX3](=[OX1])", "download", "png", 1, "both", "smartsview_test.png" )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is CRAN policy that "packages should not write in the user’s home filespace (including clipboards), nor anywhere else on the file system apart from the R session’s temporary directory". You can use the cross-platform tempdir() function to access the R sessions's temporary directory.


test_that("nist returns correct results", {
skip_on_cran()

expect_is(a[[1]], 'array')
expect_equal(b[[1]], 0)
expect_true(file.exists('smartsview_test.png'))
expect_error(smarts_viewer("[CX3](=[OX1])[OX2][CX3](=[OX1])", "download", "png", 1, "both"))
})
3 changes: 3 additions & 0 deletions tests/testthat/test-test_smartsview.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
test_that("multiplication works", {
expect_equal(2 * 2, 4)
})
Comment on lines +1 to +3
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this second test file was pushed accidentally:)