sequence_logo 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,114 +1,114 @@
1
- require_relative 'ytilib'
2
- require 'RMagick'
3
-
4
- module SequenceLogo
5
- def self.draw_threshold_lines(i_logo, ppm)
6
- x_size = i_logo.columns
7
- y_size = i_logo.rows
8
-
9
- line2of4 = y_size - ppm.get_line(ppm.icd2of4) * y_size
10
- lineThc = y_size - ppm.get_line(ppm.icdThc) * y_size
11
- lineTlc = y_size - ppm.get_line(ppm.icdTlc) * y_size
12
-
13
- dr = Magick::Draw.new
14
- dr.fill('transparent')
15
-
16
- dr.stroke_width(y_size / 200.0)
17
- dr.stroke_dasharray(7,7)
18
-
19
- dr.stroke('silver')
20
- dr.line(0, line2of4, x_size, line2of4)
21
- dr.line(0, lineThc, x_size, lineThc)
22
- dr.line(0, lineTlc, x_size, lineTlc)
23
-
24
- dr.draw(i_logo)
25
- end
26
-
27
- def self.create_canvas(ppm, options)
28
- x_size = options[:x_unit] * ppm.length
29
- y_size = options[:y_unit]
30
-
31
- i_logo = Magick::ImageList.new
32
- if options[:icd_mode] == :discrete
33
- i_logo.new_image(x_size, y_size, Magick::HatchFill.new('white', 'white'))
34
- draw_threshold_lines(i_logo, ppm) if options[:threshold_lines]
35
- else
36
- i_logo.new_image(x_size, y_size, Magick::HatchFill.new('white', 'bisque'))
37
- end
38
-
39
- i_logo
40
- end
41
-
42
- def self.letter_images(scheme_dir)
43
- if File.exist?(File.join(scheme_dir,'a.png'))
44
- extension = 'png'
45
- elsif File.exist?(File.join(scheme_dir,'a.gif'))
46
- extension = 'gif'
47
- else
48
- raise "Scheme not exists in folder #{scheme_dir}"
49
- end
50
-
51
- letter_files = %w[a c g t].collect{|letter| File.join(scheme_dir, "#{letter}.#{extension}") }
52
- Magick::ImageList.new(*letter_files)
53
- end
54
-
55
- def self.draw_letters_on_canvas(i_logo, i_letters, ppm, options)
56
- y_unit = options[:y_unit]
57
- x_unit = options[:x_unit]
58
- matrix = ppm.get_logo(options[:icd_mode])
59
- matrix['A'].each_index { |i|
60
- y_pos = 0
61
- sorted_letters = ['A', 'C', 'G', 'T'].collect { |letter| {:score => matrix[letter][i], :letter => letter} }.sort_by { |pair| pair[:score] }.collect { |pair| pair[:letter] }.reverse
62
- sorted_letters.each { |letter|
63
- next if y_unit * matrix[letter][i] <= 1
64
- letter_index = {'A' => 0, 'C' => 1, 'G' => 2, 'T' => 3}[letter]
65
- y_block = (y_unit * matrix[letter][i]).round
66
- i_logo << i_letters[letter_index].dup.resize(x_unit, y_block)
67
- y_pos += y_block
68
- i_logo.cur_image.page = Magick::Rectangle.new(0, 0, i * x_unit, y_unit - y_pos )
69
- }
70
- }
71
- end
72
-
73
- def self.draw_logo(ppm, options = {})
74
- ppm.words_count = options[:words_count] if options[:words_count]
75
- unless ppm.words_count
76
- report "words count for PPM is undefined, assuming weblogo mode"
77
- options[:icd_mode] = :weblogo
78
- end
79
- i_logo = create_canvas(ppm, options)
80
- scheme_dir = File.join(AssetsPath, options[:scheme])
81
- draw_letters_on_canvas(i_logo, letter_images(scheme_dir), ppm, options)
82
- i_logo = i_logo.flatten_images
83
- end
84
-
85
- # logos = { filename => {shift: ..., length: ..., name: ...} }
86
- def self.glue_files(logos, output_file, options)
87
- logo_shift = options[:logo_shift] || 300
88
- x_unit = options[:x_unit] || 30
89
- y_unit = options[:y_unit] || 60
90
- text_size = options[:text_size] || 24
91
-
92
- leftmost_shift = logos.map{|file,infos| infos[:shift] }.min
93
- logos.each{|file, infos| infos[:shift] -= leftmost_shift}
94
- full_alignment_size = logos.map{|file,infos| infos[:length] + infos[:shift] }.max
95
-
96
- x_size = logo_shift + full_alignment_size * x_unit
97
- y_size = logos.size * y_unit
98
- command_string = "convert -size #{ x_size }x#{ y_size } -pointsize #{text_size} xc:white "
99
- logos.each_with_index do |(logo_filename,infos), idx|
100
- logo_x_start = logo_shift + infos[:shift] * x_unit
101
- logo_y_start = y_unit * idx
102
- command_string << "\"#{ logo_filename }\" -geometry +#{ logo_x_start }+#{ logo_y_start } -composite "
103
- end
104
-
105
- command_draw_names = ""
106
- logos.each_with_index do |(logo_filename,infos), idx|
107
- text_x_start = 10
108
- text_y_start = y_unit * (idx + 0.5)
109
- command_draw_names << "-draw \"text #{ text_x_start },#{ text_y_start } '#{infos[:name]}'\" "
110
- end
111
-
112
- system(command_string + command_draw_names + "\"#{output_file}\"")
113
- end
1
+ require_relative 'ytilib'
2
+ require 'RMagick'
3
+
4
+ module SequenceLogo
5
+ def self.draw_threshold_lines(i_logo, ppm)
6
+ x_size = i_logo.columns
7
+ y_size = i_logo.rows
8
+
9
+ line2of4 = y_size - ppm.get_line(ppm.icd2of4) * y_size
10
+ lineThc = y_size - ppm.get_line(ppm.icdThc) * y_size
11
+ lineTlc = y_size - ppm.get_line(ppm.icdTlc) * y_size
12
+
13
+ dr = Magick::Draw.new
14
+ dr.fill('transparent')
15
+
16
+ dr.stroke_width(y_size / 200.0)
17
+ dr.stroke_dasharray(7,7)
18
+
19
+ dr.stroke('silver')
20
+ dr.line(0, line2of4, x_size, line2of4)
21
+ dr.line(0, lineThc, x_size, lineThc)
22
+ dr.line(0, lineTlc, x_size, lineTlc)
23
+
24
+ dr.draw(i_logo)
25
+ end
26
+
27
+ def self.create_canvas(ppm, options)
28
+ x_size = options[:x_unit] * ppm.length
29
+ y_size = options[:y_unit]
30
+
31
+ i_logo = Magick::ImageList.new
32
+ if options[:icd_mode] == :discrete
33
+ i_logo.new_image(x_size, y_size, Magick::HatchFill.new('white', 'white'))
34
+ draw_threshold_lines(i_logo, ppm) if options[:threshold_lines]
35
+ else
36
+ i_logo.new_image(x_size, y_size, Magick::HatchFill.new('white', 'bisque'))
37
+ end
38
+
39
+ i_logo
40
+ end
41
+
42
+ def self.letter_images(scheme_dir)
43
+ if File.exist?(File.join(scheme_dir,'a.png'))
44
+ extension = 'png'
45
+ elsif File.exist?(File.join(scheme_dir,'a.gif'))
46
+ extension = 'gif'
47
+ else
48
+ raise "Scheme not exists in folder #{scheme_dir}"
49
+ end
50
+
51
+ letter_files = %w[a c g t].collect{|letter| File.join(scheme_dir, "#{letter}.#{extension}") }
52
+ Magick::ImageList.new(*letter_files)
53
+ end
54
+
55
+ def self.draw_letters_on_canvas(i_logo, i_letters, ppm, options)
56
+ y_unit = options[:y_unit]
57
+ x_unit = options[:x_unit]
58
+ matrix = ppm.get_logo(options[:icd_mode])
59
+ matrix['A'].each_index { |i|
60
+ y_pos = 0
61
+ sorted_letters = ['A', 'C', 'G', 'T'].collect { |letter| {:score => matrix[letter][i], :letter => letter} }.sort_by { |pair| pair[:score] }.collect { |pair| pair[:letter] }.reverse
62
+ sorted_letters.each { |letter|
63
+ next if y_unit * matrix[letter][i] <= 1
64
+ letter_index = {'A' => 0, 'C' => 1, 'G' => 2, 'T' => 3}[letter]
65
+ y_block = (y_unit * matrix[letter][i]).round
66
+ i_logo << i_letters[letter_index].dup.resize(x_unit, y_block)
67
+ y_pos += y_block
68
+ i_logo.cur_image.page = Magick::Rectangle.new(0, 0, i * x_unit, y_unit - y_pos )
69
+ }
70
+ }
71
+ end
72
+
73
+ def self.draw_logo(ppm, options = {})
74
+ ppm.words_count = options[:words_count] if options[:words_count]
75
+ unless ppm.words_count
76
+ report "words count for PPM is undefined, assuming weblogo mode"
77
+ options[:icd_mode] = :weblogo
78
+ end
79
+ i_logo = create_canvas(ppm, options)
80
+ scheme_dir = File.join(AssetsPath, options[:scheme])
81
+ draw_letters_on_canvas(i_logo, letter_images(scheme_dir), ppm, options)
82
+ i_logo = i_logo.flatten_images
83
+ end
84
+
85
+ # logos = { filename => {shift: ..., length: ..., name: ...} }
86
+ def self.glue_files(logos, output_file, options)
87
+ logo_shift = options[:logo_shift] || 300
88
+ x_unit = options[:x_unit] || 30
89
+ y_unit = options[:y_unit] || 60
90
+ text_size = options[:text_size] || 24
91
+
92
+ leftmost_shift = logos.map{|file,infos| infos[:shift] }.min
93
+ logos.each{|file, infos| infos[:shift] -= leftmost_shift}
94
+ full_alignment_size = logos.map{|file,infos| infos[:length] + infos[:shift] }.max
95
+
96
+ x_size = logo_shift + full_alignment_size * x_unit
97
+ y_size = logos.size * y_unit
98
+ command_string = "convert -size #{ x_size }x#{ y_size } -pointsize #{text_size} xc:white "
99
+ logos.each_with_index do |(logo_filename,infos), idx|
100
+ logo_x_start = logo_shift + infos[:shift] * x_unit
101
+ logo_y_start = y_unit * idx
102
+ command_string << "\"#{ logo_filename }\" -geometry +#{ logo_x_start }+#{ logo_y_start } -composite "
103
+ end
104
+
105
+ command_draw_names = ""
106
+ logos.each_with_index do |(logo_filename,infos), idx|
107
+ text_x_start = 10
108
+ text_y_start = y_unit * (idx + 0.5)
109
+ command_draw_names << "-draw \"text #{ text_x_start },#{ text_y_start } '#{infos[:name]}'\" "
110
+ end
111
+
112
+ system(command_string + command_draw_names + "\"#{output_file}\"")
113
+ end
114
114
  end
@@ -1,3 +1,3 @@
1
- module SequenceLogo
2
- VERSION = "1.0.3"
3
- end
1
+ module SequenceLogo
2
+ VERSION = "1.0.4"
3
+ end