Skip to content

Commit

Permalink
Added embedding mouse detection
Browse files Browse the repository at this point in the history
  • Loading branch information
kiwijuice56 committed Jan 25, 2024
1 parent 5f7d5c3 commit 1bfe3ca
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 11 deletions.
10 changes: 6 additions & 4 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ <h1>protein-visualizer</h1>
through deep learning.</p>
<img src="demo_run.png" alt="Demonstration of running the visualizer"/>
<h2>How does it work?</h2>
<p>This interactive visualizer uses a deep learning model to identify functional and structural clusters within
<p>This interactive visualizer uses a neural network to identify functional and structural clusters within
a protein by calculating embeddings, numerical expressions of each amino acid. The high-dimensional
data is then transformed into 2D in order to easily interpret the possible functional components of a
protein. Next, a different deep learning model uses both the 3D structure and amino acid sequence to predict
protein. Next, a graph convolutional network uses both the 3D structure and amino acid sequence to predict
Gene Ontology (GO) annotations that describe the molecular function of the protein. Through
Gradient-weighted Class Activation Mapping (GradCAM), the program can calculate how much each amino
acid contributed to each GO prediction and subsequently allow for the identification of functional residues.</p>
<p><b>Note:</b> All of the data (except for 3D structure) shown in this program is generated through machine
<p>This program was written entirely with Python, using Pyglet as an OpenGL interface.</p>
<p><b>Disclaimer:</b> All of the data (except for 3D structure) shown in this program is generated through machine
learning and thus cannot be verified to be completely accurate. It is recommended to double-check
the predicted functions through experimental sources </p>

Expand Down Expand Up @@ -75,7 +76,8 @@ <h2>Controls</h2>
</section>
<section id="Code">
<h1>Code</h1>
All of the code is available under the MIT license on the <a href="https://github.com/kiwijuice56/protein-visualizer">protein-visualizer GitHub repository.</a>
<p>All of the code is available under the MIT license on the <a href="https://github.com/kiwijuice56/protein-visualizer">protein-visualizer GitHub repository.</a>
Feel free to take any part of the code to expand or transform, just make sure you keep the attributions to ProSE and DeepFRI!
</section>
<section id="Attribution">
<h1>Attribution</h1>
Expand Down
4 changes: 3 additions & 1 deletion gui/user_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ def on_mouse_scroll(self, x, y, scroll_x, scroll_y):

def on_mouse_motion(self, x, y, dx, dy):
prev_hl_idx = self.hl_idx
self.hl_idx = self.pdb_renderer.hovered_residue
self.hl_idx = self.embedding_renderer.hovered_residue
if self.hl_idx == -1:
self.hl_idx = self.pdb_renderer.hovered_residue

if not prev_hl_idx == -1:
self.protein.residues[prev_hl_idx].highlighted = False
Expand Down
3 changes: 3 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@

@window.event
def on_draw():
embedding_renderer.detect_mouse()
pdb_renderer.detect_mouse()

# Draw the 3D protein
pdb_renderer.draw()

Expand Down
41 changes: 41 additions & 0 deletions renderers/embedding_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ def __init__(self, protein, window, bounding_box=None, point_size=8):
# Define the pyglet vertex list
self.vertices = None
self.outline_vertices = None
self.id_vertices = None

self.hovered_residue = -1

# Default to full-screen render
self.bounding_box = []
Expand Down Expand Up @@ -148,10 +151,15 @@ def set_bounding_box(self, bounding_box):
('c4B', self.GRID_LINE_COLOR * (len(grid_points) // 2))
)

rgb_id = [[(i >> 16) & 255, (i >> 8) & 255, i & 255] for i in range(1, len(self.scaled_points) // 2 + 1)]
self.vertices = pyglet.graphics.vertex_list(
len(self.protein.embedding_points) // 2,
('v2f', self.scaled_points),
('c4B', np.zeros(len(self.protein.embedding_points) // 2 * 4, dtype=np.byte)))
self.id_vertices = pyglet.graphics.vertex_list(
len(self.protein.embedding_points) // 2,
('v2f', self.scaled_points),
('c3B', [x for xs in rgb_id for x in xs]))
self.update_colors()

def update_colors(self, start=0, end=-1):
Expand All @@ -166,6 +174,39 @@ def update_colors(self, start=0, end=-1):
self.vertices.colors[i * 4: i * 4 + 3] = self.protein.residues[i].color
self.vertices.colors[i * 4 + 3] = self.POINT_OPACITY

def detect_mouse(self):
glClearColor(*[0] * 4)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glEnable(GL_SCISSOR_TEST)
glDisable(GL_POINT_SMOOTH)

glScissor(*self.bounding_box)

glLoadIdentity()
glDisable(GL_DEPTH_TEST)
glEnable(GL_BLEND)
glOrtho(0, self.window.width, 0, self.window.height, 0, 1000)

if self.camera.updated:
self.set_bounding_box(self.bounding_box)
self.camera.updated = False

glPointSize(int(self.point_size * 2.0))
self.id_vertices.draw(pyglet.gl.GL_POINTS)

read = (GLubyte * 3)(0)
glReadPixels(self.camera.input_handler.x, self.camera.input_handler.y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, read)
selected_id = sum([read[i] << (8 * (2 - i)) for i in range(3)])
if not selected_id == 0:
self.hovered_residue = selected_id - 1
else:
self.hovered_residue = -1

# Clean up
glDisable(GL_SCISSOR_TEST)
glDisable(GL_DEPTH_TEST)
glDisable(GL_BLEND)

def draw(self):
glEnable(GL_SCISSOR_TEST)
glEnable(GL_POINT_SMOOTH)
Expand Down
13 changes: 7 additions & 6 deletions renderers/pdb_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,17 +191,13 @@ def set_bounding_box(self, bounding_box):
self.bounding_box = bounding_box
self.camera.input_handler.bounding_box = bounding_box

def draw(self):
def detect_mouse(self):
glClearColor(*[0] * 4)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glEnable(GL_POINT_SMOOTH)
glEnable(GL_SCISSOR_TEST)

glLoadIdentity()
glMatrixMode(GL_PROJECTION)
gluPerspective(self.FOV, self.window.width / float(self.window.height), self.Z_NEAR, self.Z_FAR)
self.camera.draw()

glScissor(*self.bounding_box)

glPointSize(int(1.5 * self.point_size))
Expand All @@ -217,9 +213,14 @@ def draw(self):
else:
self.hovered_residue = -1

glClearColor(*[c / 255.0 for c in self.BACKGROUND_COLOR])
def draw(self):
glClearColor(*[0] * 4)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glEnable(GL_POINT_SMOOTH)
glEnable(GL_SCISSOR_TEST)
glEnable(GL_LINE_SMOOTH)
glEnable(GL_BLEND)
glScissor(*self.bounding_box)

glLoadIdentity()
glMatrixMode(GL_PROJECTION)
Expand Down

0 comments on commit 1bfe3ca

Please sign in to comment.