RNA Folding simulation
main.cpp
Go to the documentation of this file.
1 
9 #include <GL/glew.h>
10 #include <GL/freeglut.h>
11 
12 #include "rna_folding.hh"
13 #include "herrlog.hh"
14 
15 #define STB_IMAGE_IMPLEMENTATION
16 #include "stb_image.h"
17 
19 std::string rna_name =
20  // "Homo sapiens (human) RNA, U5D small nuclear 1 (RNU5D-1)";
21  "ACA box 91 (SNORA91)";
22 // "Homo sapiens (human) small nucleolar RNA (SNORD43)";
23 // "Homo sapiens (human) microRNA hsa-mir-921 precursor";
24 // "Homo sapiens U7 small nuclear RNA";
25 // "Homo sapiens (human) small nucleolar RNA (SNORA81)";
26 // "Murari";
27 // "Vansh";
28 
33 
34 void drawText(const char* text, float x, float y) {
35  glRasterPos2f(x, y);
36  for (const char* c = text; *c != '\0'; c++) {
37  glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *c);
38  }
39 }
40 
42 GLuint texture;
43 
48 
54 void loadTexture(const char* filename) {
55  Logger::trace("Loading the image ...");
56  GLint maxTextureSize;
57  glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
58 
59  glGenTextures(1, &texture);
60  glBindTexture(GL_TEXTURE_2D, texture);
61 
62  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
63  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
64 
65  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
66  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
67 
68  int width, height, nrChannels;
69  unsigned char* data = stbi_load(filename, &width, &height, &nrChannels, 0);
70  textureWidth = width;
71  textureHeight = height;
72  Logger::trace("Trying to load texture of size: {}x{}", width, height);
73  if (data) {
74  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
75  GL_UNSIGNED_BYTE, data);
76  glGenerateMipmap(GL_TEXTURE_2D);
77  } else {
78  Logger::warn("Failed to load texture: {}", filename);
79  }
80  stbi_image_free(data);
81 }
82 
84 float pan_x = 0.0f;
86 float pan_y = 0.0f;
88 float zoom = 1.0f;
89 
96  glPushMatrix();
97 
98  glTranslatef(pan_x, pan_y, 0.0f);
99  glScalef(zoom, zoom, 1.0f);
100 
101  float aspectRatio =
102  static_cast<float>(textureWidth) / static_cast<float>(textureHeight);
103  float halfWidth = aspectRatio / 2.0f;
104 
105  glBegin(GL_QUADS);
106  glTexCoord2f(0.0f, 1.0f);
107  glVertex2f(-halfWidth, -0.5f);
108  glTexCoord2f(1.0f, 1.0f);
109  glVertex2f(halfWidth, -0.5f);
110  glTexCoord2f(1.0f, 0.0f);
111  glVertex2f(halfWidth, 0.5f);
112  glTexCoord2f(0.0f, 0.0f);
113  glVertex2f(-halfWidth, 0.5f);
114  glEnd();
115 
116  glPopMatrix();
117 }
118 
120 bool keys[256] = {false};
121 
129 void keyboardDown(unsigned char key, int x, int y) { keys[key] = true; }
130 
138 void keyboardUp(unsigned char key, int x, int y) { keys[key] = false; }
139 
144 void update() {
145  if (keys['w']) pan_y -= 0.05f;
146  if (keys['s']) pan_y += 0.05f;
147  if (keys['a']) pan_x += 0.05f;
148  if (keys['d']) pan_x -= 0.05f;
149  if (keys['e']) zoom *= 1.1f;
150  if (keys['q']) zoom *= 0.9f;
151  if (keys[27]) glutLeaveMainLoop();
152 
153  glutPostRedisplay();
154 }
155 
162 void reshape(int width, int height) {
163  glViewport(0, 0, width, height);
164 
165  float aspect = (float)width / (float)height;
166 
167  glMatrixMode(GL_PROJECTION);
168  glLoadIdentity();
169  if (width >= height) {
170  gluOrtho2D(-1.0 * aspect, 1.0 * aspect, -1.0, 1.0);
171  } else {
172  gluOrtho2D(-1.0, 1.0, -1.0 / aspect, 1.0 / aspect);
173  }
174 
175  glMatrixMode(GL_MODELVIEW);
176 }
177 
182 void display() {
183  glClear(GL_COLOR_BUFFER_BIT);
184  glEnable(GL_TEXTURE_2D);
185  glBindTexture(GL_TEXTURE_2D, texture);
186 
188 
189  glDisable(GL_TEXTURE_2D);
190  glColor3f(1.0f, 1.0f, 1.0f);
191  drawText(("Current RNA: " + rna_name).c_str(), -1.0f, 0.9f);
192  drawText(("Number of nucleotides: " + std::to_string(number_of_nucleotides))
193  .c_str(),
194  -1.0f, 0.85f);
195  drawText(("Number of bonds: " + std::to_string(number_of_bonds)).c_str(),
196  -1.0f, 0.8f);
197 
198  drawText("Controls:", -1.0f, 0.7f);
199  drawText(("(x, y): " + std::to_string(pan_x) + ", " + std::to_string(pan_y))
200  .c_str(),
201  -1.0f, 0.65f);
202  drawText(("Zoom: " + std::to_string(zoom)).c_str(), -1.0f, 0.6f);
203 
204  glDisable(GL_TEXTURE_2D);
205  glutSwapBuffers();
206 }
207 
208 int main(int argc, char** argv) {
209  std::ifstream file;
210  if (argc >= 1) {
211  rna_name = std::string(argv[1]);
212  file.open(rna_name);
213  } else {
214  file.open("rna/" + rna_name + ".rna");
215  }
216 
217  if (!file) {
218  Logger::error("Failed to open the file.");
219  }
220 
221  std::string rna_sequence;
222  std::getline(file, rna_sequence);
223  number_of_nucleotides = rna_sequence.size();
224  const int minimal_loop_length = 5;
225 
226  std::vector<std::pair<int, int>> fold;
227  traceback(create_matrix(rna_sequence, minimal_loop_length), rna_sequence,
228  fold, 0, rna_sequence.size() - 1);
229 
230  std::string dot_notation = dot_write(rna_sequence, fold);
231 
232  number_of_bonds = rna_score(rna_sequence, minimal_loop_length);
233  Logger::info("Input RNA sequence: {}", rna_sequence);
234  Logger::info("Dot-bracket notation: {}", dot_notation);
235  Logger::info("Total number of nucleotides: {}", rna_sequence.size());
236  Logger::info("Total number of bonds: {}", number_of_bonds);
237  Logger::trace("Creating the image ...");
238  dot_bracket_to_dot(rna_sequence, dot_notation);
239  Logger::trace("Image created successfully.");
240  Logger::trace("Creating graphics ...");
241 
242  glutInit(&argc, argv);
243  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
244  glutInitWindowSize(800, 600);
245  glutCreateWindow("OpenGL Image Display");
246  glutFullScreen();
247 
248  GLenum err = glewInit();
249  if (err != GLEW_OK) {
250  Logger::error("Failed to initialize GLEW: {}", glewGetErrorString(err));
251  return -1;
252  }
253 
254  loadTexture("rna.png");
255 
256  glutKeyboardFunc(keyboardDown);
257  glutKeyboardUpFunc(keyboardUp);
258  glutIdleFunc(update);
259  glutDisplayFunc(display);
260  glutReshapeFunc(reshape);
261 
262  glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
263  glClear(GL_COLOR_BUFFER_BIT);
264  glutSwapBuffers();
265 
266  glutMainLoop();
267 
268  Logger::trace("Exiting program");
269  return 0;
270 }
static void info(const char *format, Args... args)
Logs messages of type info.
Definition: herrlog.hh:309
static void trace(const char *format, Args... args)
Logs messages of type trace.
Definition: herrlog.hh:277
static void error(const char *format, Args... args)
Logs messages of type error. Furthermore closes the output file and exits the program.
Definition: herrlog.hh:326
static void warn(const char *format, Args... args)
Logs messages of type warning. Doesn't exit the program, just notifies the issue.
Definition: herrlog.hh:342
Header file logging library.
GLuint texture
OpenGL reference to the RNA structure image.
Definition: main.cpp:42
float pan_x
Pan along the x-axis.
Definition: main.cpp:84
float zoom
Zoom factor.
Definition: main.cpp:88
void display()
Callback function for displaying the image and the text.
Definition: main.cpp:182
bool keys[256]
Keeps track of which key was pressed on the keyboard.
Definition: main.cpp:120
int textureHeight
Global variables to keep track of RNA structure image width.
Definition: main.cpp:47
int number_of_bonds
Number of bonds in input.
Definition: main.cpp:32
float pan_y
Pan along the y-axis.
Definition: main.cpp:86
int textureWidth
Global variables to keep track of RNA structure image width.
Definition: main.cpp:45
void loadTexture(const char *filename)
Loads an RGBA image.
Definition: main.cpp:54
void keyboardUp(unsigned char key, int x, int y)
Callback function for keyboard events (Up press)
Definition: main.cpp:138
void reshape(int width, int height)
Callback function called when reshaping window.
Definition: main.cpp:162
std::string rna_name
Global variable to store rna name.
Definition: main.cpp:19
void drawTexturedQuad()
Draws a textured quad on the screen. Keeps the aspect ratio of the image intact.
Definition: main.cpp:95
int number_of_nucleotides
Number of nucleotides in input.
Definition: main.cpp:30
void update()
Callback function for updating the keyboard input.
Definition: main.cpp:144
void keyboardDown(unsigned char key, int x, int y)
Callback function for keyboard events (Down press)
Definition: main.cpp:129
RNA folding algorithm implementation.
std::vector< std::vector< int > > create_matrix(const std::string &rna_sequence, const int &minimal_loop_length=0)
Function to create the DP matrix for RNA folding.
Definition: rna_folding.hh:22
std::string dot_write(const std::string &rna, const std::vector< std::pair< int, int >> &fold)
Function to create the dot-bracket notation from the bonds.
Definition: rna_folding.hh:111
void traceback(const std::vector< std::vector< int >> &nm, const std::string &rna, std::vector< std::pair< int, int >> &fold, int i, int j)
Function to traceback DP and get the bonds structure.
Definition: rna_folding.hh:77
void dot_bracket_to_dot(const std::string &sequence, const std::string &structure)
Creates a DOT script from the RNA sequence and structure and calls graphviz.
Definition: rna_folding.hh:129
int rna_score(const std::string &rna_sequence, const int &minimal_loop_length=0)
Function to calculate number of bonds (theoretical) in the RNA.
Definition: rna_folding.hh:61