Displaying the three-dimensional structure of DNA and proteins in Ruby-in the case of GR.rb


Displaying the three-dimensional structure of proteins in Ruby has been a dream of humankind since ancient times, and various attempts have been made since before.

In this article, how to display 3D structures such as proteins using the graph drawing tool GR.rb that I maintain. explain.

View xyz files in GR.rb


I ran a script that displays a xyz file that describes the three-dimensional structure of DNA in GR.rb.

Get the xyz file

First save the file in xyz format. If you want to download from a browser here

wget https://raw.githubusercontent.com/red-data-tools/GR.rb/master/examples/assets/dna.xyz

Make a Ruby script

Next, create a Ruby script. Let's say mol.rb here.

Load the library.


require 'gr'
require 'gr3'
require 'numo/narray'
require 'optparse'

This time I tried to add command line options seriously.

#Command line options
options = { radius: 1.0, size: 500 }
OptionParser.new do |opt|
  opt.on('-o', '--output PATH', String) { |v| options[:save_path] = v }
  opt.on('-r', '--radius VALUE', Float) { |v| options[:radius] = v }
  opt.on('-s', '--size VALUE', Integer) { |v| options[:size] = v }
  opt.on('-t', '--title TITLE', String) { |v| options[:title] = v }
  options[:title] ||= ARGV[0]

Read the file. There's a disappointing news here, as is often the case with Ruby, that we couldn't find a parser for xyz. So read the data from the file yourself. However, it's super easy because the original file format is simple. As for the color and size for displaying atoms, the GR3 module stores default values in constants, so let's use that.

#Read file
data = readlines
nrows = data.shift.to_i
puts data.shift
data = data.take(nrows)
data.map! { |row| row.split(/\s+/) }

positions = data.map { |row| row[1..3].map(&:to_f) }
atoms     = data.map { |row| row[0] }.map { |a| GR3::ATOM_NUMBERS[a.upcase] }
colors    = atoms.map { |a| GR3::ATOM_COLORS[a] }
radii     = atoms.map { |a| GR3::ATOM_RADII[a] * options[:radius] }

This is the part that is actually displayed. I wrote this with reference to the GR.jl sample.

GR.setviewport(0, 1, 0, 1)

#Save video file
GR.beginprint(options[:save_path]) if options[:save_path]

360.times do |i|
  GR3.drawmolecule(positions, colors, radii, nil, nil, nil, 2, true, i, 45)
  GR3.drawimage(0, 1, 0, 1, options[:size], options[:size], GR3::DRAWABLE_GKS)
  GR.text(0.5, 1, options[:title])

#File save end
GR.endprint if options[:save_path]


that's all. The entire script is here gist.


I feel that the radius is a little small as it is, so try doubling the radius with -r 2.

ruby mol.rb -r2 dna.xyz


If you see a screen like this, you're successful!

Let's display the three-dimensional structure of hemoglobin

Let's display other molecules as well. Here, we will display the structure of hemoglobin as a famous protein.

Download a file that describes the structure of hemoglobin when oxygen is not bound from the Japan Protein Data Bank Japan (PDBj).

Here, download the file in PDB file format called pdb2hhb.ent. Convert this to a file in xyz format using a tool called Open Babel.

#Install Open Babel
sudo apt install openbabel

Convert pdb2hhb.ent to an xyz file.

obabel pdb2hhb.ent -O hb.xyz

Then display it as mol.rb.

ruby mol.rb hb.xyz -s 1000 -o hemoglobin.mp4 -t hemoglobin

In the process of converting to GIF animation, it got confused, but in reality, a slightly more beautiful video is saved. Raise the -s option to make the video cleaner.


On the other hand, if you make -s smaller, it will make the video taste like pixel art. Taking the example of DNA, it looks like this.


It's like a scene from a game of yesteryear. I'm sorry. There is no particular academic significance ...


Well, even in Ruby, there is actually a way to display the structure of the molecule ~

I talked about it. You may be wondering "Why Ruby?", But let's not ponder it.

Last but not least, I am happy to display the 3D structure data in this way, but I am not particularly familiar with the molecular structure and am a complete amateur. I also learned about the xyz format and PDF file format for the first time.

So, if you find something wrong, please feel free to point it out in the comments section **. I look forward to working with you.

This article is over

Recommended Posts

Displaying the three-dimensional structure of DNA and proteins in Ruby-in the case of GR.rb
[Rails] Difference in behavior between delegate and has_many-through in the case of one-to-one-to-many
[Swift] The process of registering the item selected in "UISegmentedControl" in Realm and displaying the registration data.
[For beginners] DI ~ The basics of DI and DI in Spring ~
Get the name of the test case in the JUnit test class
Create more Tabs and Fragments in the Fragment of BottomNavigationView
[Java] Get the dates of the past Monday and Sunday in order
Let's consider the meaning of "stream" and "collect" in Java's Stream API.
[jOOQ] How to CASE WHEN in the WHERE / AND / OR clause
Spring validation was important in the order of Form and BindingResult