-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathREADME.Rmd
144 lines (101 loc) · 5.97 KB
/
README.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
---
output: github_document
---
<!-- README.md is generated from README.Rmd. Please edit that file -->
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%",
fig.width=10,
fig.height=10,
cache = TRUE
)
```
# raymolecule
<img src="man/figures/caff.gif" ></img>
<!-- badges: start -->
[](https://github.com/tylermorganwall/raymolecule/actions/workflows/R-CMD-check.yaml)
<!-- badges: end -->
`raymolecule` is an R package to parse and render molecules in 3D. Rendering is powered by two packages: [rayrender](https://www.rayrender.net/) package, a pathtracer for R, and [rayvertex](https://www.rayvertex.com/), a rasterizer for R. `raymolecule` currently supports and parses SDF (structure-data file) and PDB (Protein Data Bank) files and returns a `rayrender` scene, which we then pathtrace and visualize in R. This initial release of the package only supports visualizing atoms and bonds.
## Installation
You can install the released version of raymolecule from Github:
```{r eval=FALSE}
install.packages("remotes")
remotes::install_github("tylermorganwall/raymolecule")
```
## Examples
`raymolecule` includes several example SDF files for the following molecules: "benzene", "buckyball", "caffeine", "capsaicin", "cinnemaldehyde", "geraniol", "luciferin", "morphine", "penicillin", "pfoa", "skatole", "tubocurarine_chloride". You can get the file path to these example files using the `get_example_molecule()` function. We pass this path to the `read_sdf()` file to parse the file and extract the atom coordinates and bond information in a list. `raymolecule` also includes the ability to fetch molecules from PubChem using the `get_molecule()` function. The magrittr pipe is automatically imported in the package, so we will use it to pass the output of each function to the input of the next.
Here's the format of the data:
```{r}
library(raymolecule)
get_example_molecule("benzene") |>
read_sdf()
```
Alternatively, you can fetch any molecule from [PubChem](https://pubchem.ncbi.nlm.nih.gov) by passing either the molecule name. You can also fetch a molecule using the official compound ID (CID), in case you have a specific molecule with a long name or unique isoform:
```{r}
str(get_molecule("estradiol"))
str(get_molecule(5757)) #this is the CID for estradiol (aka estrogen)
```
We can then pass the list from `get_example_molecule() |> read_sdf()` or from `get_molecule()` to the `generate_full_scene()`, `generate_atom_scene()`, or `generate_bond_scene()` functions to convert this representation to a rayrender/rayvertex scene. This can then be passed on the `render_model()` function, which will call rayrender's `render_scene()` or rayvertex's `rasterize_scene()` functions to render it. This function automatically ensures the molecule is centered and in frame, and sets up lighting, and can accept arguments to rotate the molecule. For more rendering options, see `rayrender::render_scene()` and `rayvertex::rasterize_scene()`.
```{r}
#Specify a width, height, and number of samples for the image (more samples == less noise)
get_example_molecule("caffeine") |>
read_sdf() |>
generate_full_scene() |>
render_model(width=800,height=800,samples=1000, clamp_value=10)
#Light from both bottom and top
get_example_molecule("cinnemaldehyde") |>
read_sdf() |>
generate_full_scene() |>
render_model(lights="both",width=800,height=800,samples=1000,clamp_value=10)
#Rotate the molecule and add a non-zero aperture setting to get depth of field effect
get_example_molecule("penicillin") |>
read_sdf() |>
generate_full_scene() |>
render_model(lights="both",width=800,height=800,samples=1000,angle=c(0,30,0),aperture=3,
clamp_value=10)
```
We can use `rayvertex` to render images much more quickly and noise free, as well as include a toon cel-shading effect.
```{r}
library(rayvertex)
#Render a basic example with rayvertex
get_example_molecule("tubocurarine_chloride") |>
read_sdf() |>
generate_full_scene(pathtrace=FALSE) |>
render_model(width=800,height=800,background="grey66")
#Customize the material with toon shading
shiny_toon_material = material_list(type="toon_phong",
toon_levels=,
toon_outline_width=0.1)
get_example_molecule("morphine") |>
read_sdf() |>
generate_full_scene(pathtrace=FALSE, material_vertex = shiny_toon_material) |>
render_model(width=800,height=800,background="grey66")
#Customize the lights with rayvertex
get_example_molecule("skatole") |>
read_sdf() |>
generate_full_scene(pathtrace=FALSE) |>
render_model(width=800,height=800,angle=c(0,30,0), background="grey66",
lights = directional_light(c(0,1,1)) |>
add_light(directional_light(c(0,-1,0),color="red")))
```
You can turn off lighting in `render_model()` and customize the scene (adding different objects or lights) by using rayrender's `add_object()` function or rayvertex's `add_shape()` function. If you use `rayrender::render_scene()`/`rayvertex::rasterize_scene()` instead of `render_model()`, you have to set up the camera position and field of view yourself.
```{r}
library(rayrender)
buckyball = get_example_molecule("buckyball") |>
read_sdf() |>
generate_full_scene()
#Add custom lighting
buckyball |>
add_object(sphere(y=12,radius=3,material=light(color="white", intensity=50))) |>
add_object(sphere(y=-12,radius=3,material=light(color="red", intensity=50))) |>
render_model(lights="none",width=800,height=800,samples=1000, clamp_value=10)
#Generate ground underneath the model and use a light to cast a shadow
generate_ground(depth=-4,material=diffuse(sigma=90)) |>
add_object(buckyball) |>
add_object(sphere(y=8,material=light(intensity=100))) |>
render_scene(width=800,height=800,samples=1000,aperture=1,fov=30,lookfrom = c(0,1,30),
clamp_value = 10)
```