bio-graphics 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/doc/classes/Bio.html +135 -0
  2. data/doc/classes/Bio/Graphics.html +247 -0
  3. data/doc/classes/Bio/Graphics/Panel.html +344 -0
  4. data/doc/classes/Bio/Graphics/Panel.src/M000005.html +29 -0
  5. data/doc/classes/Bio/Graphics/Panel.src/M000006.html +19 -0
  6. data/doc/classes/Bio/Graphics/Panel.src/M000007.html +67 -0
  7. data/doc/classes/Bio/Graphics/Panel/Ruler.html +238 -0
  8. data/doc/classes/Bio/Graphics/Panel/Ruler.src/M000008.html +20 -0
  9. data/doc/classes/Bio/Graphics/Panel/Ruler.src/M000009.html +28 -0
  10. data/doc/classes/Bio/Graphics/Panel/Ruler.src/M000010.html +54 -0
  11. data/doc/classes/Bio/Graphics/Panel/Ruler.src/M000013.html +20 -0
  12. data/doc/classes/Bio/Graphics/Panel/Ruler.src/M000014.html +28 -0
  13. data/doc/classes/Bio/Graphics/Panel/Ruler.src/M000015.html +59 -0
  14. data/doc/classes/Bio/Graphics/Panel/Track.html +342 -0
  15. data/doc/classes/Bio/Graphics/Panel/Track.src/M000008.html +23 -0
  16. data/doc/classes/Bio/Graphics/Panel/Track.src/M000009.html +42 -0
  17. data/doc/classes/Bio/Graphics/Panel/Track.src/M000010.html +285 -0
  18. data/doc/classes/Bio/Graphics/Panel/Track.src/M000011.html +23 -0
  19. data/doc/classes/Bio/Graphics/Panel/Track.src/M000012.html +43 -0
  20. data/doc/classes/Bio/Graphics/Panel/Track.src/M000013.html +259 -0
  21. data/doc/classes/Bio/Graphics/Panel/Track/Feature.html +292 -0
  22. data/doc/classes/Bio/Graphics/Panel/Track/Feature.src/M000011.html +65 -0
  23. data/doc/classes/Bio/Graphics/Panel/Track/Feature.src/M000014.html +65 -0
  24. data/doc/classes/Bio/Graphics/Panel/Track/Feature/PixelRange.html +155 -0
  25. data/doc/classes/Bio/Graphics/Panel/Track/Feature/PixelRange.src/M000012.html +18 -0
  26. data/doc/classes/Bio/Graphics/Panel/Track/Feature/PixelRange.src/M000015.html +18 -0
  27. data/doc/classes/ImageMap.html +185 -0
  28. data/doc/classes/ImageMap.src/M000001.html +18 -0
  29. data/doc/classes/ImageMap.src/M000002.html +24 -0
  30. data/doc/classes/ImageMap/ImageMapElement.html +187 -0
  31. data/doc/classes/ImageMap/ImageMapElement.src/M000003.html +19 -0
  32. data/doc/classes/ImageMap/ImageMapElement.src/M000004.html +20 -0
  33. data/doc/created.rid +1 -0
  34. data/doc/files/README_DEV.html +432 -0
  35. data/doc/files/TUTORIAL.html +358 -0
  36. data/doc/files/lib/bio-graphics_rb.html +121 -0
  37. data/doc/files/lib/bio/graphics/feature_rb.html +113 -0
  38. data/doc/files/lib/bio/graphics/image_map_rb.html +113 -0
  39. data/doc/files/lib/bio/graphics/panel_rb.html +113 -0
  40. data/doc/files/lib/bio/graphics/ruler_rb.html +113 -0
  41. data/doc/files/lib/bio/graphics/track_rb.html +113 -0
  42. data/doc/fr_class_index.html +35 -0
  43. data/doc/fr_file_index.html +34 -0
  44. data/doc/fr_method_index.html +41 -0
  45. data/doc/images/example.png +0 -0
  46. data/doc/images/glyph_showcase.png +0 -0
  47. data/doc/images/terms.png +0 -0
  48. data/doc/images/terms.svg +166 -0
  49. data/doc/index.html +24 -0
  50. data/images/example.png +0 -0
  51. data/images/glyph_showcase.png +0 -0
  52. data/images/terms.png +0 -0
  53. data/images/terms.svg +166 -0
  54. data/lib/bio-graphics.rb +18 -0
  55. data/lib/bio/graphics/feature.rb +136 -0
  56. data/lib/bio/graphics/image_map.rb +37 -0
  57. data/lib/bio/graphics/panel.rb +205 -0
  58. data/lib/bio/graphics/ruler.rb +96 -0
  59. data/lib/bio/graphics/track.rb +387 -0
  60. data/samples/arkdb_features.rb +37 -0
  61. data/samples/data.txt +32 -0
  62. data/samples/glyph_showcase.rb +29 -0
  63. metadata +137 -0
@@ -0,0 +1,387 @@
1
+ #
2
+ # = bio/graphics/track - track class
3
+ #
4
+ # Copyright:: Copyright (C) 2007
5
+ # Jan Aerts <jan.aerts@bbsrc.ac.uk>
6
+ # License:: The Ruby License
7
+ #
8
+ module Bio
9
+ module Graphics
10
+ class Panel
11
+ # The Bio::Graphics::Track class describes the container for features of
12
+ # the same type. See Bio::Graphics documentation for explanation of
13
+ # interplay between different classes.
14
+ class Track
15
+ # !!Not to be used directly. Use Bio::Graphics::Panel.add_track instead!!
16
+ # A track can not exist except within the confines of a
17
+ # Bio::Graphics::Panel object.
18
+ #
19
+ #--
20
+ # This is necessary because the track needs to know the rescale_factor
21
+ # and width of the picture, both of which are defined within the panel.
22
+ #++
23
+ #
24
+ # ---
25
+ # *Arguments*:
26
+ # * _panel_ (required) :: Bio::Graphics::Panel object that this track
27
+ # belongs to
28
+ # * _name_ (required) :: Name of the track to be displayed (e.g. 'genes')
29
+ # * _colour_ :: Colour to be used to draw the features within the track.
30
+ # Default = 'blue'
31
+ # * _glyph_ :: Glyph to use for drawing the features. Options are:
32
+ # 'generic', 'directed_generic', 'spliced, 'directed_spliced' and
33
+ # 'triangle'. Triangles can be used
34
+ # for features whose start and stop positions are the same (e.g. SNPs).
35
+ # If you try to draw a feature that is longer with triangles, an error
36
+ # will be shown.
37
+ # *Returns*:: Bio::Graphics::Track object
38
+ def initialize(panel, name, feature_colour = [0,0,1], feature_glyph = 'generic')
39
+ @panel = panel
40
+ @name = name
41
+ @feature_colour = feature_colour
42
+ @feature_glyph = feature_glyph
43
+ @features = Array.new
44
+ @number_of_times_bumped = 0
45
+ end
46
+ attr_accessor :panel, :name, :feature_colour, :feature_glyph, :features, :number_of_times_bumped, :height
47
+
48
+ # Adds a Bio::Graphics::Panel::Track::Feature to this track. A track contains
49
+ # features of the same type, e.g. (for sequence annotation:) genes,
50
+ # polymorphisms, ESTs, etc.
51
+ #
52
+ # est_track.add_feature('EST1','50..60')
53
+ # est_track.add_feature('EST2','52..73')
54
+ # est_track.add_feature('EST3','41..69')
55
+ # gene_track.add_feature('gene2','39..73')
56
+ #
57
+ # For spliced features:
58
+ # est_track.add_feature('EST4','join(34..53,153..191)')
59
+ #
60
+ # Or on the complement strand:
61
+ # est_track.add_feature('EST5','complement(join(34..53,153..191))')
62
+ #
63
+ # See the documentation in Bio::Locations for a full description of
64
+ # how locations can be defined.
65
+ #
66
+ # Features are only added if they are at least partly in the displayed
67
+ # region. If a feature is completely outside of the region, it's not
68
+ # added. If it should be only partly visible, it is added completely.
69
+ #
70
+ # ---
71
+ # *Arguments*:
72
+ # * _name_ (required) :: Name of the feature
73
+ # * _location_ :: String. Default: whole of panel, forward strand.
74
+ # * _link_ :: URL to link to for this glyph
75
+ # *Returns*:: Bio::Graphics::Track::Feature object that was created or nil
76
+ def add_feature(name, location_string = '1..' + @panel.length.to_s, link = nil)
77
+ if link == ''
78
+ link = nil
79
+ end
80
+
81
+ # Calculate the ultimate start and stop of the feature: the start
82
+ # of the first subfeature (e.g. exon) and the stop of the last one.
83
+ # The only reason we want to know these positions, is because we want
84
+ # to determine if the feature falls within the view of the image or
85
+ # not (see below).
86
+ location_object = Bio::Locations.new(location_string)
87
+ start = location_object.collect{|l| l.from}.min.to_i
88
+ stop = location_object.collect{|l| l.to}.max.to_i
89
+
90
+ # If the feature wouldn't show because it's not in the region we're
91
+ # looking at, don't bother storing the stuff. I think this makes huge
92
+ # speed and memory differences if you've got a chromosome with
93
+ # thousands of features.
94
+ if stop <= panel.display_start or start >= panel.display_stop
95
+ return nil
96
+ else #elsif start >= panel.display_start and stop <= panel.display_stop
97
+ @features.push(Bio::Graphics::Panel::Track::Feature.new(self, name, location_object, link))
98
+ return @features[-1]
99
+ end
100
+
101
+ return self
102
+ end
103
+
104
+
105
+ # Adds the track to a cairo drawing. This method should not be used
106
+ # directly by the user, but is called by Bio::Graphics::Panel.draw
107
+ # ---
108
+ # *Arguments*:
109
+ # * _paneldrawing_ (required) :: the panel cairo object
110
+ # * _verticaloffset_ (required) :: number of pixels to offset the track downwards,
111
+ # based on the height of other tracks that were drawn above it
112
+ # *Returns*:: FIXME: I don't know
113
+ def draw(panel_drawing, vertical_offset)
114
+ track_drawing = Cairo::Context.new(panel_drawing)
115
+
116
+ # Draw thin line above title
117
+ track_drawing.set_source_rgb(0.75,0.75,0.75)
118
+ track_drawing.move_to(0, vertical_offset)
119
+ track_drawing.line_to(panel.width, vertical_offset)
120
+ track_drawing.stroke
121
+
122
+ # Draw track title
123
+ track_drawing.set_source_rgb(0,0,0)
124
+ track_drawing.select_font_face('Georgia',1,1)
125
+ track_drawing.set_font_size(TRACK_HEADER_HEIGHT)
126
+ track_drawing.move_to(0,TRACK_HEADER_HEIGHT + vertical_offset + 10)
127
+ track_drawing.show_text(self.name)
128
+
129
+ # Draw the features
130
+ grid = Hash.new
131
+
132
+ track_drawing.save do
133
+ track_drawing.translate(0, vertical_offset + TRACK_HEADER_HEIGHT)
134
+ track_drawing.set_source_rgb(@feature_colour)
135
+
136
+ # Now draw the features
137
+ # These are the basic steps:
138
+ # A. find out what row to draw it on
139
+ # B. see if we want to change the glyph type from directed to
140
+ # undirected
141
+ # C. draw the thing
142
+ @features.each do |feature|
143
+ # Don't even bother if the feature is not in the view
144
+ if feature.stop <= self.panel.display_start or feature.start >= self.panel.display_stop
145
+ next
146
+ else
147
+ feature_drawn = false
148
+
149
+ # A. find out what row to draw it on
150
+ feature_range = (feature.start.floor..feature.stop.ceil)
151
+ row = 1
152
+ row_available = true
153
+ until feature_drawn
154
+ if ! grid[row].nil?
155
+ grid[row].each do |covered|
156
+ if feature_range.include?(covered.first) or covered.include?(feature_range.first)
157
+ row_available = false
158
+ end
159
+ end
160
+ end
161
+
162
+ if ! row_available
163
+ row += 1
164
+ row_available = true
165
+ else
166
+ if grid[row].nil?
167
+ grid[row] = Array.new
168
+ end
169
+ grid[row].push(feature_range)
170
+
171
+ # B. see if we want to change the glyph type from directed to
172
+ # undirected
173
+ # There are 2 cases where we don't want to draw arrows on
174
+ # features:
175
+ # (a) when the picture is really zoomed out, features are
176
+ # so small that the arrow itself is too big
177
+ # (b) if a directed feature on the fw strand extends beyond
178
+ # the end of the picture, the arrow is out of view. This
179
+ # is the same as considering the feature as undirected.
180
+ # The same obviously goes for features on the reverse
181
+ # strand that extend beyond the left side of the image.
182
+ #
183
+ # (a) Zoomed out
184
+ replace_directed_with_undirected = false
185
+ if (feature.stop - feature.start).to_f/panel.rescale_factor.to_f < 2
186
+ replace_directed_with_undirected = true
187
+ end
188
+ # (b) Extending beyond borders picture
189
+ if ( feature.chopped_at_stop and feature.strand = 1 ) or ( feature.chopped_at_start and feature.strand = -1 )
190
+ replace_directed_with_undirected = true
191
+ end
192
+
193
+ local_feature_glyph = nil
194
+ if feature_glyph == 'directed_generic' and replace_directed_with_undirected
195
+ local_feature_glyph = 'generic'
196
+ elsif feature_glyph == 'directed_spliced' and replace_directed_with_undirected
197
+ local_feature_glyph = 'spliced'
198
+ else
199
+ local_feature_glyph = feature_glyph
200
+ end
201
+
202
+ # C. And draw the thing.
203
+ top_pixel_of_feature = FEATURE_V_DISTANCE + (FEATURE_HEIGHT+FEATURE_V_DISTANCE)*row
204
+ bottom_pixel_of_feature = top_pixel_of_feature + FEATURE_HEIGHT
205
+
206
+ case local_feature_glyph
207
+ # triangles are typical for features which have a 1 bp position (start == stop)
208
+ when 'triangle'
209
+ raise "Start and stop are not the same (necessary if you want triangle glyphs)" if feature.start != feature.stop
210
+
211
+ # Need to get this for the imagemap
212
+ left_pixel_of_feature = feature.pixel_range_collection[0].start_pixel - 3
213
+ right_pixel_of_feature = feature.pixel_range_collection[0].stop_pixel + 3
214
+ track_drawing.move_to(left_pixel_of_feature + 3, top_pixel_of_feature)
215
+ track_drawing.rel_line_to(-3, FEATURE_HEIGHT)
216
+ track_drawing.rel_line_to(6, 0)
217
+ track_drawing.close_path.fill
218
+
219
+ when 'directed_generic'
220
+ # Need to get this for the imagemap
221
+ left_pixel_of_feature = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}[0].start_pixel
222
+ right_pixel_of_feature = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}[-1].stop_pixel
223
+ if feature.strand == -1 # Reverse strand
224
+ # Draw main box
225
+ track_drawing.rectangle(left_pixel_of_feature+FEATURE_ARROW_LENGTH, top_pixel_of_feature, right_pixel_of_feature - left_pixel_of_feature - FEATURE_ARROW_LENGTH, FEATURE_HEIGHT).fill
226
+
227
+ # Draw arrow
228
+ track_drawing.move_to(left_pixel_of_feature+FEATURE_ARROW_LENGTH, top_pixel_of_feature)
229
+ track_drawing.rel_line_to(-FEATURE_ARROW_LENGTH, FEATURE_HEIGHT/2)
230
+ track_drawing.rel_line_to(FEATURE_ARROW_LENGTH, FEATURE_HEIGHT/2)
231
+ track_drawing.close_path.fill
232
+
233
+ else #default is forward strand
234
+ track_drawing.rectangle(left_pixel_of_feature, top_pixel_of_feature, right_pixel_of_feature - left_pixel_of_feature - FEATURE_ARROW_LENGTH, FEATURE_HEIGHT).fill
235
+ track_drawing.move_to(right_pixel_of_feature - FEATURE_ARROW_LENGTH, top_pixel_of_feature)
236
+ track_drawing.rel_line_to(FEATURE_ARROW_LENGTH, FEATURE_HEIGHT/2)
237
+ track_drawing.rel_line_to(-FEATURE_ARROW_LENGTH, FEATURE_HEIGHT/2)
238
+ track_drawing.close_path.fill
239
+ end
240
+ when 'spliced'
241
+ gap_starts = Array.new
242
+ gap_stops = Array.new
243
+
244
+ # Need to get this for the imagemap
245
+ left_pixel_of_feature = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}[0].start_pixel
246
+ right_pixel_of_feature = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}[-1].stop_pixel
247
+
248
+ # First draw the parts
249
+ feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}.each do |pr|
250
+ track_drawing.rectangle(pr.start_pixel, top_pixel_of_feature, (pr.stop_pixel - pr.start_pixel), FEATURE_HEIGHT).fill
251
+ gap_starts.push(pr.stop_pixel)
252
+ gap_stops.push(pr.start_pixel)
253
+ end
254
+
255
+ # And then draw the connections in the gaps
256
+ # Start with removing the very first start and the very last stop.
257
+ gap_starts.sort!.pop
258
+ gap_stops.sort!.shift
259
+
260
+ gap_starts.length.times do |gap_number|
261
+ from = gap_starts[gap_number].to_f
262
+ to = gap_stops[gap_number].to_f
263
+ middle = from + ((to - from)/2)
264
+ track_drawing.move_to(from, top_pixel_of_feature+2)
265
+ track_drawing.line_to(middle, top_pixel_of_feature+7)
266
+ track_drawing.line_to(to, top_pixel_of_feature+2)
267
+ track_drawing.stroke
268
+ end
269
+
270
+ if feature.hidden_subfeatures_at_stop
271
+ from = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}[-1].stop_pixel
272
+ to = panel.width
273
+ track_drawing.move_to(from, top_pixel_of_feature+5)
274
+ track_drawing.line_to(to, top_pixel_of_feature+5)
275
+ track_drawing.stroke
276
+ end
277
+
278
+ if feature.hidden_subfeatures_at_start
279
+ from = 1
280
+ to = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}[0].start_pixel
281
+ track_drawing.move_to(from, top_pixel_of_feature+5)
282
+ track_drawing.line_to(to, top_pixel_of_feature+5)
283
+ track_drawing.stroke
284
+ end
285
+
286
+ when 'directed_spliced'
287
+ gap_starts = Array.new
288
+ gap_stops = Array.new
289
+ # First draw the parts
290
+ locations = feature.location.sort_by{|l| l.from}
291
+
292
+ # Need to get this for the imagemap
293
+ left_pixel_of_feature = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}[0].start_pixel
294
+ right_pixel_of_feature = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}[-1].stop_pixel
295
+
296
+ # Start with the one with the arrow
297
+ pixel_ranges = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}
298
+ range_with_arrow = nil
299
+ if feature.strand == -1 # reverse strand => box with arrow is first one
300
+ range_with_arrow = pixel_ranges.shift
301
+ track_drawing.rectangle((range_with_arrow.start_pixel)+FEATURE_ARROW_LENGTH, top_pixel_of_feature, range_with_arrow.stop_pixel - range_with_arrow.start_pixel, FEATURE_HEIGHT).fill
302
+ track_drawing.move_to(range_with_arrow.start_pixel+FEATURE_ARROW_LENGTH, top_pixel_of_feature)
303
+ track_drawing.rel_line_to(-FEATURE_ARROW_LENGTH, FEATURE_HEIGHT/2)
304
+ track_drawing.rel_line_to(FEATURE_ARROW_LENGTH, FEATURE_HEIGHT/2)
305
+ track_drawing.close_path.fill
306
+ else # forward strand => box with arrow is last one
307
+ range_with_arrow = pixel_ranges.pop
308
+ track_drawing.rectangle(range_with_arrow.start_pixel-FEATURE_ARROW_LENGTH, top_pixel_of_feature, range_with_arrow.stop_pixel - range_with_arrow.start_pixel, FEATURE_HEIGHT).fill
309
+ track_drawing.move_to(range_with_arrow.stop_pixel-FEATURE_ARROW_LENGTH, top_pixel_of_feature)
310
+ track_drawing.rel_line_to(FEATURE_ARROW_LENGTH, FEATURE_HEIGHT/2)
311
+ track_drawing.rel_line_to(-FEATURE_ARROW_LENGTH, FEATURE_HEIGHT/2)
312
+ end
313
+ gap_starts.push(range_with_arrow.stop_pixel)
314
+ gap_stops.push(range_with_arrow.start_pixel)
315
+
316
+ # And then add the others
317
+ pixel_ranges.each do |range|
318
+ track_drawing.rectangle(range.start_pixel, top_pixel_of_feature, range.stop_pixel - range.start_pixel, FEATURE_HEIGHT).fill
319
+ gap_starts.push(range.stop_pixel)
320
+ gap_stops.push(range.start_pixel)
321
+ end
322
+
323
+ # And then draw the connections in the gaps
324
+ # Start with removing the very first start and the very last stop.
325
+ gap_starts.sort!.pop
326
+ gap_stops.sort!.shift
327
+
328
+ gap_starts.length.times do |gap_number|
329
+ from = gap_starts[gap_number].to_f
330
+ to = gap_stops[gap_number].to_f
331
+ middle = from + ((to - from)/2)
332
+ track_drawing.move_to(from, top_pixel_of_feature+2)
333
+ track_drawing.line_to(middle, top_pixel_of_feature+7)
334
+ track_drawing.line_to(to, top_pixel_of_feature+2)
335
+ track_drawing.stroke
336
+ end
337
+
338
+ if feature.hidden_subfeatures_at_stop
339
+ from = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}[-1].stop_pixel
340
+ to = panel.width
341
+ track_drawing.move_to(from, top_pixel_of_feature+5)
342
+ track_drawing.line_to(to, top_pixel_of_feature+5)
343
+ track_drawing.stroke
344
+ end
345
+
346
+ if feature.hidden_subfeatures_at_start
347
+ from = 1
348
+ to = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}[0].start_pixel
349
+ track_drawing.move_to(from, top_pixel_of_feature+5)
350
+ track_drawing.line_to(to, top_pixel_of_feature+5)
351
+ track_drawing.stroke
352
+ end
353
+
354
+ else #treat as 'generic'
355
+ left_pixel_of_feature, right_pixel_of_feature = feature.pixel_range_collection[0].start_pixel, feature.pixel_range_collection[0].stop_pixel
356
+ track_drawing.rectangle(left_pixel_of_feature, top_pixel_of_feature, (right_pixel_of_feature - left_pixel_of_feature), FEATURE_HEIGHT).fill
357
+ end
358
+
359
+ # And add the region to the image map
360
+ if panel.clickable
361
+ # Comment: we have to add the vertical_offset and TRACK_HEADER_HEIGHT!
362
+ panel.image_map.elements.push(ImageMap::ImageMapElement.new(left_pixel_of_feature,
363
+ top_pixel_of_feature + vertical_offset + TRACK_HEADER_HEIGHT,
364
+ right_pixel_of_feature,
365
+ bottom_pixel_of_feature + vertical_offset + TRACK_HEADER_HEIGHT,
366
+ feature.link
367
+ ))
368
+ end
369
+
370
+
371
+ feature_drawn = true
372
+ end
373
+ end
374
+ end
375
+ end
376
+
377
+ end
378
+
379
+ @number_of_times_bumped = ( grid.keys.length == 0 ) ? 1 : grid.keys.max + 1
380
+
381
+ return panel_drawing
382
+ end
383
+
384
+ end #Track
385
+ end #Panel
386
+ end #Graphics
387
+ end #Bio
@@ -0,0 +1,37 @@
1
+ require File.dirname(__FILE__) + '/../lib/bio-graphics'
2
+
3
+ #Initialize graphic for a nucleotide sequence of 4173015 bp, zooming in on the
4
+ #region 11111..3333333
5
+ my_panel = Bio::Graphics::Panel.new(4173015, 800, false, 11111, 3333333)
6
+ #my_panel = Bio::Graphics::Panel.new(4173015, 800, false, 1, 4173015)
7
+
8
+ #Create and configure tracks
9
+ scaffold_track = my_panel.add_track('scaffold')
10
+ marker_track = my_panel.add_track('marker')
11
+ clone_track = my_panel.add_track('clone')
12
+
13
+ scaffold_track.feature_colour = [1,0,0]
14
+ marker_track.feature_colour = [0,1,0]
15
+ marker_track.feature_glyph = 'triangle'
16
+ clone_track.feature_colour = [0,0,1]
17
+
18
+ # Add data to tracks
19
+ File.open('data.txt').each do |line|
20
+ line.chomp!
21
+ accession, type, start, stop = line.split(/\t/)
22
+ if type == 'scaffold'
23
+ if start.nil?
24
+ scaffold_track.add_feature(accession)
25
+ else
26
+ scaffold_track.add_feature(accession, start + '..' + stop)
27
+ end
28
+
29
+ elsif type == 'marker'
30
+ marker_track.add_feature(accession, ((start.to_i + stop.to_i)/2).to_s, 'http://www.thearkdb.org/arkdb/do/getMarkerDetail?accession=' + accession)
31
+ elsif type == 'clone'
32
+ clone_track.add_feature(accession, start + '..' + stop)
33
+ end
34
+ end
35
+
36
+ # And draw
37
+ my_panel.draw('my_panel.png')
@@ -0,0 +1,32 @@
1
+ test scaffold
2
+ ARKSCA00000496 scaffold 1766280 3140306
3
+ ARKSCA00000495 scaffold 1454125 1756279
4
+ ARKMKR00050962 marker 1547565 1547116
5
+ ARKMKR00049743 marker 1467043 1467548
6
+ ARKMKR00049753 marker 1293787 1294437
7
+ ARKMKR00033347 marker 976330 976530
8
+ ARKMKR00049788 marker 959182 959941
9
+ ARKMKR00049746 marker 3030496 3031106
10
+ ARKCLN00574951 clone 1454125 1743183
11
+ ARKCLN00580755 clone 1115673 1332008
12
+ ARKCLN00734502 clone 2680312 2880020
13
+ ARKCLN00637391 clone 1291903 1444124
14
+ ARKCLN00733777 clone 554351 745744
15
+ ARKCLN00516431 clone 1766280 2053569
16
+ ARKCLN00734156 clone 1973620 2155335
17
+ ARKCLN00605941 clone 1576502 1756279
18
+ ARKCLN00608810 clone 672169 860914
19
+ ARKCLN00565213 clone 348808 418529
20
+ ARKCLN00679752 clone 2321244 2563972
21
+ ARKCLN00538485 clone 2851750 3078918
22
+ ARKCLN00581628 clone 2966855 3140306
23
+ ARKCLN00511832 clone 1034205 1213124
24
+ ARKCLN00734700 clone 2566852 2709684
25
+ ARKCLN00534126 clone 1043517 1290570
26
+ ARKCLN00734007 clone 951813 1154597
27
+ ARKCLN00733988 clone 140268 332409
28
+ ARKCLN00589095 clone 800155 1015201
29
+ ARKCLN00635737 clone 265756 445381
30
+ ARKCLN00573316 clone 2226636 2363631
31
+ ARKCLN00494906 clone 2130193 2314107
32
+ ARKCLN00515356 clone 81435 254456