]> git.donarmstrong.com Git - biopieces.git/blob - bp_bin/plot_nucleotide_distribution
ea9b0db2513c9ca662788728ebbe60acbe6e9efa
[biopieces.git] / bp_bin / plot_nucleotide_distribution
1 #!/usr/bin/env ruby
2
3 # Copyright (C) 2007-2012 Martin A. Hansen.
4
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
9
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
19 # http://www.gnu.org/copyleft/gpl.html
20
21 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
22
23 # Plot the nucleotide distribution in percent of sequences in the stream.
24
25 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
26
27 require 'maasha/biopieces'
28 require 'gnuplot'
29 require 'narray'
30 require 'pp'
31
32 VEC_MAX   = 10_000
33 Y_MAX     = 100
34
35 terminals = "dumb,x11,aqua,post,pdf,png,svg"
36 title     = "Nucleotide Distribution"
37 xlabel    = "Sequence position"
38 ylabel    = "Nucleotide distribution (%)"
39
40 casts = []
41 casts << {:long=>'no_stream', :short=>'x', :type=>'flag',   :mandatory=>false, :default=>nil,    :allowed=>nil,       :disallowed=>nil}
42 casts << {:long=>'count',     :short=>'c', :type=>'flag',   :mandatory=>false, :default=>nil,    :allowed=>nil,       :disallowed=>nil}
43 casts << {:long=>'data_out',  :short=>'o', :type=>'file',   :mandatory=>false, :default=>nil,    :allowed=>nil,       :disallowed=>nil}
44 casts << {:long=>'terminal',  :short=>'t', :type=>'string', :mandatory=>false, :default=>'dumb', :allowed=>terminals, :disallowed=>nil}
45 casts << {:long=>'title',     :short=>'T', :type=>'string', :mandatory=>false, :default=>title,  :allowed=>nil,       :disallowed=>nil}
46 casts << {:long=>'xlabel',    :short=>'X', :type=>'string', :mandatory=>false, :default=>xlabel, :allowed=>nil,       :disallowed=>nil}
47 casts << {:long=>'ylabel',    :short=>'Y', :type=>'string', :mandatory=>false, :default=>ylabel, :allowed=>nil,       :disallowed=>nil}
48
49 options = Biopieces.options_parse(ARGV, casts)
50
51 max_len = 0 
52
53 vec_a   = NArray.int(VEC_MAX)
54 vec_t   = NArray.int(VEC_MAX)
55 vec_c   = NArray.int(VEC_MAX)
56 vec_g   = NArray.int(VEC_MAX)
57 vec_n   = NArray.int(VEC_MAX)
58 vec_tot = NArray.float(VEC_MAX)
59
60 Biopieces.open(options[:stream_in], options[:stream_out]) do |input, output|
61   input.each_record do |record|
62     if record[:SEQ]
63       seq = record[:SEQ].upcase
64
65       raise BiopiecesError, "sequence too long: #{seq.length} > #{VEC_MAX}" if seq.length > VEC_MAX
66
67       vec_seq = NArray.to_na(seq, "byte")
68
69       vec_a[0 ... seq.length]   += vec_seq.eq('A'.ord)
70       vec_t[0 ... seq.length]   += vec_seq.eq('T'.ord)
71       vec_c[0 ... seq.length]   += vec_seq.eq('C'.ord)
72       vec_g[0 ... seq.length]   += vec_seq.eq('G'.ord)
73       vec_n[0 ... seq.length]   += vec_seq.eq('N'.ord)
74       vec_tot[0 ... seq.length] += 1
75
76       max_len = seq.length if seq.length > max_len
77     end
78
79     output.puts record unless options[:no_stream]
80   end
81 end
82
83 x = (1 .. max_len).to_a
84 a = ((vec_a / vec_tot) * 100)[0 ... max_len].to_a
85 t = ((vec_t / vec_tot) * 100)[0 ... max_len].to_a
86 c = ((vec_c / vec_tot) * 100)[0 ... max_len].to_a
87 g = ((vec_g / vec_tot) * 100)[0 ... max_len].to_a
88 n = ((vec_n / vec_tot) * 100)[0 ... max_len].to_a
89
90 vec_tot *= (Y_MAX / vec_tot.max(0).to_f)
91 y = vec_tot.to_a
92
93 a.unshift 0.0
94 t.unshift 0.0
95 c.unshift 0.0
96 g.unshift 0.0
97 n.unshift 0.0
98
99 Gnuplot.open do |gp|
100   Gnuplot::Plot.new(gp) do |plot|
101     plot.terminal options[:terminal]
102     plot.title    options[:title]
103     plot.xlabel   options[:xlabel]
104     plot.ylabel   options[:ylabel]
105     plot.output   options[:data_out] if options[:data_out]
106     plot.ytics    "out"
107     plot.xtics    "out"
108     plot.yrange   "[0:#{Y_MAX}]"
109     plot.xrange   "[0:#{max_len}]"
110     plot.auto     "fix"
111     plot.offsets  "1"
112     plot.key      "outside right top vertical Left reverse enhanced autotitles columnhead nobox"
113     plot.key      "invert samplen 4 spacing 1 width 0 height 0"
114     plot.style    "fill solid 0.5 border"
115     plot.style    "histogram rowstacked"
116     plot.style    "data histograms"
117     plot.boxwidth "0.75 absolute"
118
119     plot.data << Gnuplot::DataSet.new(n) do |ds|
120       ds.using = "1"
121       ds.with  = "histogram lt rgb \"black\""
122       ds.title = "N"
123     end
124
125     plot.data << Gnuplot::DataSet.new(g) do |ds|
126       ds.using = "1"
127       ds.with  = "histogram lt rgb \"yellow\""
128       ds.title = "G"
129     end
130
131     plot.data << Gnuplot::DataSet.new(c) do |ds|
132       ds.using = "1"
133       ds.with  = "histogram lt rgb \"blue\""
134       ds.title = "C"
135     end
136
137     plot.data << Gnuplot::DataSet.new(t) do |ds|
138       ds.using = "1"
139       ds.with  = "histogram lt rgb \"green\""
140       ds.title = "T"
141     end
142
143     plot.data << Gnuplot::DataSet.new(a) do |ds|
144       ds.using = "1"
145       ds.with  = "histogram lt rgb \"red\""
146       ds.title = "A"
147     end
148
149     if options[:count]
150       plot.data << Gnuplot::DataSet.new([x, y]) do |ds|
151         ds.with  = "lines lt rgb \"black\""
152         ds.title = "relative count"
153       end
154     end
155   end
156 end
157
158
159 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
160
161
162 __END__