Module: SequenceLogo

Defined in:
lib/sequence_logo.rb,
lib/sequence_logo/cli.rb,
lib/sequence_logo/version.rb,
lib/sequence_logo/pmflogo_lib.rb

Defined Under Namespace

Classes: CLI

Constant Summary collapse

AssetsPath =
File.join(File.dirname(__FILE__), 'sequence_logo', 'assets')
VERSION =
"1.0.6"

Class Method Summary collapse

Class Method Details

.create_canvas(ppm, options) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/sequence_logo/pmflogo_lib.rb', line 27

def self.create_canvas(ppm, options)
  x_size = options[:x_unit] * ppm.length
  y_size = options[:y_unit]

   = Magick::ImageList.new
  if options[:icd_mode] == :discrete
    .new_image(x_size, y_size, Magick::HatchFill.new('white', 'white'))
    draw_threshold_lines(, ppm)  if options[:threshold_lines]
  else
    .new_image(x_size, y_size, Magick::HatchFill.new('white', 'bisque'))
  end

  
end

.draw_letters_on_canvas(i_logo, i_letters, ppm, options) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/sequence_logo/pmflogo_lib.rb', line 55

def self.draw_letters_on_canvas(, i_letters, ppm, options)
  y_unit = options[:y_unit]
  x_unit = options[:x_unit]
  matrix = ppm.(options[:icd_mode])
  matrix['A'].each_index { |i|
    y_pos = 0
    sorted_letters = ['A', 'C', 'G', 'T'].collect { |letter| {:score => matrix[letter][i], :letter => letter} }.sort_by { |pair| pair[:score] }.collect { |pair| pair[:letter] }.reverse
    sorted_letters.each { |letter|
      next if y_unit * matrix[letter][i] <= 1
      letter_index = {'A' => 0, 'C' => 1, 'G' => 2, 'T' => 3}[letter]
      y_block = (y_unit * matrix[letter][i]).round
       << i_letters[letter_index].dup.resize(x_unit, y_block)
      y_pos += y_block
      .cur_image.page = Magick::Rectangle.new(0, 0, i * x_unit, y_unit - y_pos )
    }
  }
end

.draw_logo(ppm, options = {}) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
# File 'lib/sequence_logo/pmflogo_lib.rb', line 73

def self.(ppm, options = {})
  ppm.words_count = options[:words_count]  if options[:words_count]
  unless ppm.words_count
    report "words count for PPM is undefined, assuming weblogo mode"
    options[:icd_mode] = :weblogo
  end
   = create_canvas(ppm, options)
  scheme_dir = File.join(AssetsPath, options[:scheme])
  draw_letters_on_canvas(, letter_images(scheme_dir), ppm, options)
   = .flatten_images
end

.draw_threshold_lines(i_logo, ppm) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/sequence_logo/pmflogo_lib.rb', line 5

def self.draw_threshold_lines(, ppm)
  x_size = .columns
  y_size = .rows

  line2of4 = y_size - ppm.get_line(ppm.icd2of4) * y_size
  lineThc = y_size - ppm.get_line(ppm.icdThc) * y_size
  lineTlc = y_size - ppm.get_line(ppm.icdTlc) * y_size

  dr = Magick::Draw.new
  dr.fill('transparent')

  dr.stroke_width(y_size / 200.0)
  dr.stroke_dasharray(7,7)

  dr.stroke('silver')
  dr.line(0, line2of4, x_size, line2of4)
  dr.line(0, lineThc, x_size, lineThc)
  dr.line(0, lineTlc, x_size, lineTlc)

  dr.draw()
end

.glue_files(logos, output_file, options) ⇒ Object

logos = { filename => …, length: …, name: … }



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/sequence_logo/pmflogo_lib.rb', line 86

def self.glue_files(logos, output_file, options)
  logo_shift = options[:logo_shift] || 300
  x_unit = options[:x_unit] || 30
  y_unit = options[:y_unit] || 60
  text_size = options[:text_size] || 24

  leftmost_shift = logos.map{|file,infos| infos[:shift] }.min
  logos.each{|file, infos| infos[:shift] -= leftmost_shift}
  full_alignment_size = logos.map{|file,infos| infos[:length] + infos[:shift] }.max

  x_size = logo_shift + full_alignment_size * x_unit
  y_size = logos.size * y_unit
  command_string = "convert -size #{ x_size }x#{ y_size } -pointsize #{text_size} xc:white "
  logos.each_with_index do |(logo_filename,infos), idx|
    logo_x_start = logo_shift + infos[:shift] * x_unit
    logo_y_start = y_unit * idx
    command_string << "\"#{ logo_filename }\" -geometry +#{ logo_x_start }+#{ logo_y_start } -composite "
  end

  command_draw_names = ""
  logos.each_with_index do |(logo_filename,infos), idx|
    text_x_start = 10
    text_y_start = y_unit * (idx + 0.5)
    command_draw_names << "-draw \"text #{ text_x_start },#{ text_y_start } '#{infos[:name]}'\" "
  end

  system(command_string + command_draw_names + "\"#{output_file}\"")
end

.letter_images(scheme_dir) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/sequence_logo/pmflogo_lib.rb', line 42

def self.letter_images(scheme_dir)
  if File.exist?(File.join(scheme_dir,'a.png'))
    extension = 'png'
  elsif File.exist?(File.join(scheme_dir,'a.gif'))
    extension = 'gif'
  else
    raise "Scheme not exists in folder #{scheme_dir}"
  end

  letter_files = %w[a c g t].collect{|letter| File.join(scheme_dir, "#{letter}.#{extension}") }
  Magick::ImageList.new(*letter_files)
end