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.
I ran a script that displays a xyz file that describes the three-dimensional structure of DNA in GR.rb.
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
Next, create a Ruby script. Let's say mol.rb
here.
Load the library.
mol.rb
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 }
opt.parse!(ARGV)
options[:title] ||= ARGV[0]
end
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.initgr
GR.setviewport(0, 1, 0, 1)
#Save video file
GR.beginprint(options[:save_path]) if options[:save_path]
360.times do |i|
GR.clearws
GR3.clear
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.settextcolorind(0)
GR.settextalign(GR::TEXT_HALIGN_CENTER, GR::TEXT_VALIGN_TOP)
GR.text(0.5, 1, options[:title])
GR.updatews
end
#File save end
GR.endprint if options[:save_path]
GR3.terminate
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 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