ulla 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. data/.git/COMMIT_EDITMSG +13 -0
  2. data/.git/HEAD +1 -0
  3. data/.git/config +11 -0
  4. data/.git/description +1 -0
  5. data/.git/hooks/applypatch-msg.sample +15 -0
  6. data/.git/hooks/commit-msg.sample +24 -0
  7. data/.git/hooks/post-commit.sample +8 -0
  8. data/.git/hooks/post-receive.sample +15 -0
  9. data/.git/hooks/post-update.sample +8 -0
  10. data/.git/hooks/pre-applypatch.sample +14 -0
  11. data/.git/hooks/pre-commit.sample +18 -0
  12. data/.git/hooks/pre-rebase.sample +169 -0
  13. data/.git/hooks/prepare-commit-msg.sample +36 -0
  14. data/.git/hooks/update.sample +107 -0
  15. data/.git/index +0 -0
  16. data/.git/info/exclude +6 -0
  17. data/.git/logs/HEAD +3 -0
  18. data/.git/logs/refs/heads/master +3 -0
  19. data/.git/logs/refs/remotes/origin/HEAD +1 -0
  20. data/.git/objects/06/9494e479f28b5751fb135b8e55e8fef3d3a02e +0 -0
  21. data/.git/objects/22/0df784191ad94983ca1d943e49fe482c9d1069 +0 -0
  22. data/.git/objects/3b/b6f2b7f563175a13a0ccd723aab761552f448b +0 -0
  23. data/.git/objects/41/f48aefb4d7a6a87eb423eaae77ae1e8a58dd6c +0 -0
  24. data/.git/objects/44/d1f1782e3ea1d9fd2f9054784b53e8e810a8ca +0 -0
  25. data/.git/objects/4f/364c2eac29f5c7fcbf06419c4f58074cd32ace +2 -0
  26. data/.git/objects/57/1326145a7a4b3e58f3d3008ba343135f213b05 +4 -0
  27. data/.git/objects/6c/4f0844f62b7345f0651b0fb2829a8f157469fb +3 -0
  28. data/.git/objects/73/8dc79450de050f12d48a32602f2ddbe6807029 +0 -0
  29. data/.git/objects/7b/4acb3aee6616d80e295ee21fe8bb7ee93ebe96 +2 -0
  30. data/.git/objects/9e/0a9235b0d70a8029098070007fb414cb52504e +2 -0
  31. data/.git/objects/9e/bfcad2906aac4a23a7c9689a47b76723f5d152 +0 -0
  32. data/.git/objects/a6/578c95f2f474303464b572e9dac716432472b2 +0 -0
  33. data/.git/objects/a8/65ef5700ff04601c6fc40fa5ede3cc25534723 +0 -0
  34. data/.git/objects/aa/285cb176668c5e49c54c6e1d3cc27bd47fd4f4 +0 -0
  35. data/.git/objects/b8/e3828a1082137c4aa4595386bdfb73e3c75b9d +0 -0
  36. data/.git/objects/c2/fb6afc000952b56354fe195682645000d2aea2 +0 -0
  37. data/.git/objects/c4/a0553ca0e3c4628e688ecb5e3304a8a8ac0c28 +2 -0
  38. data/.git/objects/c8/d49f83c4a32cff2d87dd4aa5f83eb7aac3a753 +5 -0
  39. data/.git/objects/ca/c25e8049075ed4bff993705acb4750b2b62ba9 +0 -0
  40. data/.git/objects/d2/ff2e939339eb3fb776e064c258e71dfa1cf396 +0 -0
  41. data/.git/objects/d7/cedf9e2a8ff35b5d7dafdc0f20daed9c65ce44 +0 -0
  42. data/.git/objects/e2/e81af59e3a6c4aa8daac62add62860ae776ba4 +0 -0
  43. data/.git/objects/e5/7c47d183ce5dda1a944c7ee1c19c8a0c4bb278 +0 -0
  44. data/.git/objects/eb/f4a4e1e50bb30731597f776e56b0ccb0c9959f +0 -0
  45. data/.git/objects/f6/39d6f6cf883fde4b9052012919c1df3288c7da +0 -0
  46. data/.git/objects/f8/2346f308f49053df108b7c31ac3089e8b4b4ac +0 -0
  47. data/.git/objects/fb/4b193bb1cbe9041d2f00176f6caa6acfb1fc12 +0 -0
  48. data/.git/objects/pack/pack-aebf617a0b8e016433238d2f21f542bc5b21bd15.idx +0 -0
  49. data/.git/objects/pack/pack-aebf617a0b8e016433238d2f21f542bc5b21bd15.pack +0 -0
  50. data/.git/packed-refs +8 -0
  51. data/.git/refs/heads/master +1 -0
  52. data/.git/refs/remotes/origin/HEAD +1 -0
  53. data/.gitignore +8 -0
  54. data/History.txt +42 -0
  55. data/Manifest.txt +90 -0
  56. data/PostInstall.txt +5 -0
  57. data/README.rdoc +259 -0
  58. data/Rakefile +32 -0
  59. data/bin/ulla +10 -0
  60. data/config/website.yml +2 -0
  61. data/config/website.yml.sample +2 -0
  62. data/lib/math_extensions.rb +7 -0
  63. data/lib/narray_extensions.rb +22 -0
  64. data/lib/nmatrix_extensions.rb +245 -0
  65. data/lib/string_extensions.rb +17 -0
  66. data/lib/ulla/cli.rb +1742 -0
  67. data/lib/ulla/environment.rb +34 -0
  68. data/lib/ulla/environment_class_hash.rb +20 -0
  69. data/lib/ulla/environment_feature.rb +26 -0
  70. data/lib/ulla/environment_feature_array.rb +12 -0
  71. data/lib/ulla/heatmap_array.rb +111 -0
  72. data/lib/ulla.rb +6 -0
  73. data/script/console +10 -0
  74. data/script/destroy +14 -0
  75. data/script/generate +14 -0
  76. data/script/txt2html +71 -0
  77. data/test/test_helper.rb +2 -0
  78. data/test/test_math_extensions.rb +11 -0
  79. data/test/test_narray_extensions.rb +14 -0
  80. data/test/test_nmatrix_extensions.rb +16 -0
  81. data/test/test_string_extensions.rb +11 -0
  82. data/test/test_ulla.rb +11 -0
  83. data/test/ulla/test_cli.rb +9 -0
  84. data/test/ulla/test_environment_class_hash.rb +25 -0
  85. data/test/ulla/test_environment_feature.rb +29 -0
  86. data/website/index.html +16 -0
  87. data/website/index.txt +217 -0
  88. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  89. data/website/stylesheets/screen.css +158 -0
  90. data/website/template.html.erb +57 -0
  91. metadata +215 -0
@@ -0,0 +1,245 @@
1
+ require 'rubygems'
2
+ require 'narray'
3
+ require 'facets'
4
+
5
+ begin
6
+ require 'rvg/rvg'
7
+ include Magick
8
+ rescue
9
+ $logger.warn "A RubyGems package, 'rmagick' is not found, so heat maps cannot be generated."
10
+ $no_rmagick = true
11
+ end
12
+
13
+ module NMatrixExtensions
14
+
15
+ def pretty_string(options={})
16
+ opts = {:col_header => nil,
17
+ :row_header => nil }.merge(options)
18
+
19
+ ("%-3s" % "#") + opts[:col_header].inject("") { |s, a|
20
+ s + ("%7s" % a)
21
+ } + "\n" + self.to_a.map_with_index { |a, i|
22
+ ("%-3s" % opts[:row_header][i]) + a.inject("") { |s, v|
23
+ if v.is_a? Float
24
+ s + ("%7.2f" % v)
25
+ else
26
+ s + ("%7d" % v)
27
+ end
28
+ }
29
+ }.join("\n")
30
+ end
31
+
32
+ def heatmap(options={})
33
+ if $no_rmagick
34
+ return nil
35
+ end
36
+
37
+ opts = {:col_header => 'ACDEFGHIKLMNPQRSTVWYJ'.split(''),
38
+ :row_header => 'ACDEFGHIKLMNPQRSTVWYJ'.split(''),
39
+ :max_val => self.max,
40
+ :mid_val => (self.max - self.min) / 2.0,
41
+ :min_val => self.min,
42
+ :dpi => 100,
43
+ :margin_width => 30,
44
+ :rvg_width => nil,
45
+ :rvg_height => nil,
46
+ :canvas_width => nil,
47
+ :canvas_height => nil,
48
+ :cell_width => 20,
49
+ :cell_height => 20,
50
+ :cell_border_color => '#888888',
51
+ :cell_border_width => 1,
52
+ :table_border_color => '#000000',
53
+ :table_border_width => 2,
54
+ :header_height => 100,
55
+ :footer_height => 50,
56
+ :print_gradient => true,
57
+ :gradient_width => 300,
58
+ :gradient_height => 30,
59
+ :gradient_beg_color => '#FFFFFF',
60
+ :gradient_mid_color => nil,
61
+ :gradient_end_color => '#FF0000',
62
+ :gradient_border_width => 1,
63
+ :gradient_border_color => '#000000',
64
+ :font_scale => 0.9,
65
+ :font_family => 'san serif',
66
+ :small_gap_width => 2,
67
+ :title? => true,
68
+ :title => '',
69
+ :title_font_size => 35,
70
+ :print_value => false,
71
+ :key_font_size => 15,
72
+ :value_font_size => 8,
73
+ :background => '#FFFFFF'}.merge(options)
74
+
75
+ RVG::dpi = opts[:dpi]
76
+
77
+ rvg = RVG.new(opts[:rvg_width], opts[:rvg_height]) do |canvas|
78
+ title_x = (opts[:canvas_width] - opts[:title].length * opts[:title_font_size] * 0.6) / 2.0
79
+ title_y = opts[:header_height] - opts[:title_font_size] * 0.7
80
+
81
+ canvas.viewbox(0, 0, opts[:canvas_width], opts[:canvas_height])
82
+ canvas.background_fill = opts[:background]
83
+ canvas.desc = opts[:title]
84
+
85
+ if opts[:title?]
86
+ canvas.text(title_x, title_y, opts[:title]).styles(:font_size => opts[:title_font_size])
87
+ end
88
+
89
+ # border for whole matrix
90
+ table_x = (opts[:canvas_width] - opts[:cell_width] * self.shape[0]) / 2.0
91
+ table_y = opts[:header_height] + opts[:cell_height]
92
+
93
+ canvas.rect(self.shape[0] * opts[:cell_width],
94
+ self.shape[1] * opts[:cell_height],
95
+ table_x,
96
+ table_y).styles(:stroke => opts[:table_border_color],
97
+ :stroke_width => opts[:table_border_width])
98
+
99
+ # drawing column and row labels
100
+ 0.upto(self.shape[0] - 1) do |col|
101
+ canvas.text(table_x + col * opts[:cell_width] + opts[:small_gap_width],
102
+ opts[:cell_height] + opts[:header_height] - opts[:small_gap_width],
103
+ opts[:col_header][col]).styles( :font_family => opts[:font_family],
104
+ :font_size => opts[:cell_width] * opts[:font_scale])
105
+ end
106
+
107
+ 0.upto(self.shape[1] - 1) do |row|
108
+ canvas.text(table_x - opts[:cell_width],
109
+ table_y + (row + 1) * opts[:cell_height],
110
+ opts[:row_header][row]).styles( :font_family => opts[:font_family],
111
+ :font_size => opts[:cell_height] * opts[:font_scale])
112
+ end
113
+
114
+ # drawing cells
115
+
116
+ # calculating a unit of RGB color in a decimal number
117
+ r_beg = (opts[:gradient_beg_color].rgb_to_integer & 0xFF0000) >> 16
118
+ g_beg = (opts[:gradient_beg_color].rgb_to_integer & 0x00FF00) >> 8
119
+ b_beg = (opts[:gradient_beg_color].rgb_to_integer & 0x0000FF) >> 0
120
+ r_end = (opts[:gradient_end_color].rgb_to_integer & 0xFF0000) >> 16
121
+ g_end = (opts[:gradient_end_color].rgb_to_integer & 0x00FF00) >> 8
122
+ b_end = (opts[:gradient_end_color].rgb_to_integer & 0x0000FF) >> 0
123
+ gap = opts[:max_val] - opts[:min_val]
124
+
125
+ if opts[:gradient_mid_color]
126
+ r_mid = (opts[:gradient_mid_color].rgb_to_integer & 0xFF0000) >> 16
127
+ g_mid = (opts[:gradient_mid_color].rgb_to_integer & 0x00FF00) >> 8
128
+ b_mid = (opts[:gradient_mid_color].rgb_to_integer & 0x0000FF) >> 0
129
+ gap1 = opts[:mid_val] - opts[:min_val]
130
+ gap2 = opts[:max_val] - opts[:mid_val]
131
+ end
132
+
133
+ 0.upto(self.shape[0] - 1) do |col|
134
+ 0.upto(self.shape[1] - 1) do |row|
135
+ if opts[:gradient_mid_color]
136
+ if self[col, row] <= opts[:mid_val]
137
+ r = interpolate(r_beg, r_mid, self[col, row] - opts[:min_val], gap1)
138
+ g = interpolate(g_beg, g_mid, self[col, row] - opts[:min_val], gap1)
139
+ b = interpolate(b_beg, b_mid, self[col, row] - opts[:min_val], gap1)
140
+ else
141
+ r = interpolate(r_mid, r_end, self[col, row] - opts[:mid_val], gap2)
142
+ g = interpolate(g_mid, g_end, self[col, row] - opts[:mid_val], gap2)
143
+ b = interpolate(b_mid, b_end, self[col, row] - opts[:mid_val], gap2)
144
+ end
145
+ else
146
+ r = interpolate(r_beg, r_end, self[col, row] - opts[:min_val], gap)
147
+ g = interpolate(g_beg, g_end, self[col, row] - opts[:min_val], gap)
148
+ b = interpolate(b_beg, b_end, self[col, row] - opts[:min_val], gap)
149
+ end
150
+
151
+ color = ("#%6X" % ((((r << 8) | g) << 8) | b)).gsub(" ", "0")
152
+
153
+ canvas.rect(opts[:cell_width],
154
+ opts[:cell_height],
155
+ table_x + col * opts[:cell_width],
156
+ table_y + row * opts[:cell_height]).styles( :fill => color,
157
+ :stroke => opts[:cell_border_color],
158
+ :stroke_width => opts[:cell_border_width])
159
+
160
+ if opts[:print_value]
161
+ canvas.text(table_x + col * opts[:cell_width] + opts[:cell_border_width],
162
+ table_y + (row + 1) * opts[:cell_height],
163
+ "#{'%.1f' % self[col, row]}").styles(:font_size => opts[:value_font_size])
164
+ end
165
+ end
166
+ end
167
+
168
+ # gradient key
169
+ if opts[:print_gradient]
170
+ if opts[:gradient_mid_color]
171
+ img1 = Image.new(opts[:gradient_height],
172
+ opts[:gradient_width] / 2,
173
+ GradientFill.new(0,
174
+ opts[:gradient_width] / 2,
175
+ opts[:gradient_height],
176
+ opts[:gradient_width] / 2,
177
+ opts[:gradient_beg_color],
178
+ opts[:gradient_mid_color])).rotate(90)
179
+
180
+ img2 = Image.new(opts[:gradient_height],
181
+ opts[:gradient_width] / 2,
182
+ GradientFill.new(0,
183
+ opts[:gradient_width] / 2,
184
+ opts[:gradient_height],
185
+ opts[:gradient_width] / 2,
186
+ opts[:gradient_mid_color],
187
+ opts[:gradient_end_color])).rotate(90)
188
+ img3 = ImageList.new
189
+ img3 << img1 << img2
190
+ img = img3.append(false)
191
+ else
192
+ img = Image.new(opts[:gradient_height],
193
+ opts[:gradient_width],
194
+ GradientFill.new(0,
195
+ opts[:gradient_width],
196
+ opts[:gradient_height],
197
+ opts[:gradient_width],
198
+ opts[:gradient_beg_color],
199
+ opts[:gradient_end_color])).rotate(90)
200
+ end
201
+
202
+ img.border!(opts[:gradient_border_width],
203
+ opts[:gradient_border_width],
204
+ opts[:gradient_border_color])
205
+
206
+ gradient_x = (opts[:canvas_width] - opts[:gradient_width]) / 2
207
+ gradient_y = opts[:header_height] + opts[:cell_height] * opts[:row_header].count + opts[:margin_width]
208
+
209
+ canvas.image(img,
210
+ opts[:gradient_width],
211
+ opts[:gradient_height] + opts[:margin_width],
212
+ gradient_x,
213
+ gradient_y)
214
+
215
+ canvas.text(gradient_x,
216
+ gradient_y + opts[:gradient_height] + opts[:key_font_size] * 2,
217
+ "#{'%.1f' % opts[:min_val]}").styles(:font_size => opts[:key_font_size])
218
+
219
+ canvas.text(gradient_x + opts[:gradient_width],
220
+ gradient_y + opts[:gradient_height] + opts[:key_font_size] * 2,
221
+ "#{'%.1f' % opts[:max_val]}").styles(:font_size => opts[:key_font_size])
222
+ end
223
+ end
224
+
225
+ rvg.draw
226
+ end
227
+
228
+
229
+ private
230
+
231
+ def interpolate(start_val, end_val, step, no_steps)
232
+ begin
233
+ if (start_val < end_val)
234
+ ((end_val - start_val) / no_steps.to_f) * step + start_val
235
+ else
236
+ start_val - ((start_val - end_val) / no_steps.to_f) * step
237
+ end.round
238
+ rescue FloatDomainError
239
+ start_val
240
+ end
241
+ end
242
+
243
+ end
244
+
245
+ NMatrix.send(:include, NMatrixExtensions)
@@ -0,0 +1,17 @@
1
+ module StringExtensions
2
+
3
+ def remove_internal_spaces
4
+ gsub(/[\n|\r|\s]+/, '')
5
+ end
6
+
7
+ def rgb_to_integer
8
+ if self.length == 7 # '#FF00FF'
9
+ Integer(self.gsub('#', '0x'))
10
+ else
11
+ raise "#{self} doesn't seem to be a proper RGB code."
12
+ end
13
+ end
14
+ end
15
+
16
+ String.send :include, StringExtensions
17
+