2 new commits in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/changeset/b80ca015c305/ changeset: b80ca015c305 user: jgoecks date: 2011-11-05 23:21:38 summary: Trackster: color reads based on strand aligned to. affected #: 2 files diff -r 21138a4a1fead60fd3c364658a1dabbde870646b -r b80ca015c305cc0768de10dbf60c38bd91abca50 lib/galaxy/visualization/tracks/data_providers.py --- a/lib/galaxy/visualization/tracks/data_providers.py +++ b/lib/galaxy/visualization/tracks/data_providers.py @@ -462,8 +462,10 @@ # ID: feature[2], cigar, + # TODO? VCF does not have strand, so default to positive. + "+", new_seq, - float( feature[5] )] + float( feature[5] ) ] rval.append(payload) return { 'data': rval, 'message': message } @@ -609,11 +611,11 @@ data - a list of reads with the format [<guid>, <start>, <end>, <name>, <read_1>, <read_2>] where <read_1> has the format - [<start>, <end>, <cigar>, ?<read_seq>?] + [<start>, <end>, <cigar>, <strand>, ?<read_seq>?] and <read_2> has the format - [<start>, <end>, <cigar>, ?<read_seq>?] + [<start>, <end>, <cigar>, <strand>, ?<read_seq>?] For single-end reads, read has format: - [<guid>, <start>, <end>, <name>, cigar, seq] + [<guid>, <start>, <end>, <name>, <cigar>, <strand>, <seq>] NOTE: read end and sequence data are not valid for reads outside of requested region and should not be used. @@ -641,17 +643,34 @@ else: return None + # Decode strand from read flag. + def decode_strand( read_flag, mask ): + strand_flag = ( read_flag & mask == 0 ) + if strand_flag: + return "+" + else: + return "-" + # Encode reads as list of lists. results = [] paired_pending = {} + unmapped = 0 for count, read in enumerate( data ): if count < start_val: continue - if count-start_val >= max_vals: + if ( count - start_val - unmapped ) >= max_vals: message = ERROR_MAX_VALS % ( max_vals, "reads" ) break + + # If not mapped, skip read. + is_mapped = ( read.flag & 0x0004 == 0 ) + if not is_mapped: + unmapped += 1 + continue + qname = read.qname seq = read.seq + strand = decode_strand( read.flag, 0x0010 ) if read.cigar is not None: read_len = sum( [cig[1] for cig in read.cigar] ) # Use cigar to determine length else: @@ -664,14 +683,15 @@ pair['start'], read.pos + read_len, qname, - [ pair['start'], pair['end'], pair['cigar'], pair['seq'] ], - [ read.pos, read.pos + read_len, read.cigar, seq ] + [ pair['start'], pair['end'], pair['cigar'], pair['strand'], pair['seq'] ], + [ read.pos, read.pos + read_len, read.cigar, strand, seq ] ] ) del paired_pending[qname] else: - paired_pending[qname] = { 'start': read.pos, 'end': read.pos + read_len, 'seq': seq, 'mate_start': read.mpos, 'rlen': read_len, 'cigar': read.cigar } + paired_pending[qname] = { 'start': read.pos, 'end': read.pos + read_len, 'seq': seq, 'mate_start': read.mpos, + 'rlen': read_len, 'strand': strand, 'cigar': read.cigar } else: - results.append( [ "%i_%s" % ( read.pos, qname ), read.pos, read.pos + read_len, qname, read.cigar, read.seq] ) + results.append( [ "%i_%s" % ( read.pos, qname ), read.pos, read.pos + read_len, qname, read.cigar, strand, read.seq] ) # Take care of reads whose mates are out of range. # TODO: count paired reads when adhering to max_vals? @@ -683,14 +703,14 @@ # Make read_1 start=end so that length is 0 b/c we don't know # read length. r1 = [ read['mate_start'], read['mate_start'] ] - r2 = [ read['start'], read['end'], read['cigar'], read['seq'] ] + r2 = [ read['start'], read['end'], read['cigar'], read['strand'], read['seq'] ] else: # Mate is after read. read_start = read['start'] # Make read_2 start=end so that length is 0 b/c we don't know # read length. Hence, end of read is start of read_2. read_end = read['mate_start'] - r1 = [ read['start'], read['end'], read['cigar'], read['seq'] ] + r1 = [ read['start'], read['end'], read['cigar'], read['strand'], read['seq'] ] r2 = [ read['mate_start'], read['mate_start'] ] results.append( [ "%i_%s" % ( read_start, qname ), read_start, read_end, qname, r1, r2 ] ) diff -r 21138a4a1fead60fd3c364658a1dabbde870646b -r b80ca015c305cc0768de10dbf60c38bd91abca50 static/scripts/trackster.js --- a/static/scripts/trackster.js +++ b/static/scripts/trackster.js @@ -3580,11 +3580,15 @@ var ReadTrack = function (name, view, container, hda_ldda, dataset_id, prefs, filters) { FeatureTrack.call(this, name, view, container, hda_ldda, dataset_id, prefs, filters); + var + block_color = get_random_color(), + reverse_strand_color = get_random_color( [ block_color, "#ffffff" ] ); this.config = new DrawableConfig( { track: this, params: [ { key: 'name', label: 'Name', type: 'text', default_value: name }, - { key: 'block_color', label: 'Block color', type: 'color', default_value: get_random_color() }, + { key: 'block_color', label: 'Block and sense strand color', type: 'color', default_value: block_color }, + { key: 'reverse_strand_color', label: 'Antisense strand color', type: 'color', default_value: reverse_strand_color }, { key: 'label_color', label: 'Label color', type: 'color', default_value: 'black' }, { key: 'show_insertions', label: 'Show insertions', type: 'bool', default_value: false }, { key: 'show_differences', label: 'Show differences only', type: 'bool', default_value: true }, @@ -4388,8 +4392,6 @@ this.ref_seq = (ref_seq ? ref_seq.data : null); }; -ReadPainter.prototype.default_prefs = extend({}, FeaturePainter.prototype.default_prefs, { show_insertions: false }); - extend(ReadPainter.prototype, FeaturePainter.prototype, { /** * Returns height based on mode. @@ -4414,14 +4416,15 @@ /** * Draw a single read. */ - draw_read: function(ctx, mode, w_scale, tile_low, tile_high, feature_start, cigar, orig_seq, y_center) { + draw_read: function(ctx, mode, w_scale, y_center, tile_low, tile_high, feature_start, cigar, strand, orig_seq) { ctx.textAlign = "center"; var track = this, tile_region = [tile_low, tile_high], base_offset = 0, seq_offset = 0, gap = 0, - char_width_px = ctx.canvas.manager.char_width_px; + char_width_px = ctx.canvas.manager.char_width_px, + block_color = (strand === "+" ? this.prefs.block_color : this.prefs.reverse_strand_color); // Keep list of items that need to be drawn on top of initial drawing layer. var draw_last = []; @@ -4468,7 +4471,7 @@ // Draw. var seq = orig_seq.slice(seq_offset, seq_offset + cig_len); if (gap > 0) { - ctx.fillStyle = this.prefs.block_color; + ctx.fillStyle = block_color; ctx.fillRect(s_start - gap, y_center + 1, s_end - s_start, 9); ctx.fillStyle = CONNECTOR_COLOR; // TODO: this can be made much more efficient by computing the complete sequence @@ -4486,7 +4489,7 @@ } } } else { - ctx.fillStyle = this.prefs.block_color; + ctx.fillStyle = block_color; // TODO: This is a pretty hack-ish way to fill rectangle based on mode. ctx.fillRect(s_start, y_center + 4, s_end - s_start, SQUISH_FEATURE_HEIGHT); } @@ -4615,7 +4618,6 @@ f_start = Math.floor( Math.max(0, (feature_start - tile_low) * w_scale) ), f_end = Math.ceil( Math.min(width, Math.max(0, (feature_end - tile_low) * w_scale)) ), y_center = (mode === "Dense" ? 0 : (0 + slot)) * y_scale, - block_color = this.prefs.block_color, label_color = this.prefs.label_color, // Left-gap for label text since we align chrom text to the position tick. gap = 0; @@ -4626,7 +4628,6 @@ } // Draw read. - ctx.fillStyle = block_color; if (feature[5] instanceof Array) { // Read is paired. var b1_start = Math.floor( Math.max(0, (feature[4][0] - tile_low) * w_scale) ), @@ -4635,12 +4636,12 @@ b2_end = Math.ceil( Math.min(width, Math.max(0, (feature[5][1] - tile_low) * w_scale)) ); // Draw left/forward read. - if (feature[4][1] >= tile_low && feature[4][0] <= tile_high && feature[4][2]) { - this.draw_read(ctx, mode, w_scale, tile_low, tile_high, feature[4][0], feature[4][2], feature[4][3], y_center); + if (feature[4][1] >= tile_low && feature[4][0] <= tile_high && feature[4][2]) { + this.draw_read(ctx, mode, w_scale, y_center, tile_low, tile_high, feature[4][0], feature[4][2], feature[4][3], feature[4][4]); } // Draw right/reverse read. if (feature[5][1] >= tile_low && feature[5][0] <= tile_high && feature[5][2]) { - this.draw_read(ctx, mode, w_scale, tile_low, tile_high, feature[5][0], feature[5][2], feature[5][3], y_center); + this.draw_read(ctx, mode, w_scale, y_center, tile_low, tile_high, feature[5][0], feature[5][2], feature[5][3], feature[5][4]); } // Draw connector. if (b2_start > b1_end) { @@ -4649,8 +4650,7 @@ } } else { // Read is single. - ctx.fillStyle = block_color; - this.draw_read(ctx, mode, w_scale, tile_low, tile_high, feature_start, feature[4], feature[5], y_center); + this.draw_read(ctx, mode, w_scale, y_center, tile_low, tile_high, feature_start, feature[4], feature[5], feature[6]); } if (mode === "Pack" && feature_start > tile_low && feature_name !== ".") { // Draw label. @@ -4664,7 +4664,6 @@ ctx.textAlign = "right"; ctx.fillText(feature_name, f_start - LABEL_SPACING - gap, y_center + 8); } - ctx.fillStyle = block_color; } // FIXME: provide actual coordinates for drawn read. https://bitbucket.org/galaxy/galaxy-central/changeset/545288e40ee1/ changeset: 545288e40ee1 user: jgoecks date: 2011-11-06 00:12:07 summary: Trackster: tooltips for navigational elements and better showing/hiding of add tracks button. affected #: 2 files diff -r b80ca015c305cc0768de10dbf60c38bd91abca50 -r 545288e40ee10ed48d422eb772b734ace1422451 static/scripts/trackster.js --- a/static/scripts/trackster.js +++ b/static/scripts/trackster.js @@ -941,7 +941,7 @@ } }; this.nav_input = $("<input/>").addClass("nav-input").hide().bind("keyup focusout", submit_nav).appendTo(this.nav_controls); - this.location_span = $("<span/>").addClass("location").appendTo(this.nav_controls); + this.location_span = $("<span/>").addClass("location").attr('original-title', 'Click to change location').tipsy( { gravity: 'n' } ).appendTo(this.nav_controls); this.location_span.click(function() { view.location_span.hide(); view.chrom_select.hide(); @@ -953,8 +953,11 @@ if (this.vis_id !== undefined) { this.hidden_input = $("<input/>").attr("type", "hidden").val(this.vis_id).appendTo(this.nav_controls); } - this.zo_link = $("<a id='zoom-out' />").click(function() { view.zoom_out(); view.request_redraw(); }).appendTo(this.nav_controls); - this.zi_link = $("<a id='zoom-in' />").click(function() { view.zoom_in(); view.request_redraw(); }).appendTo(this.nav_controls); + + this.zo_link = $("<a/>").attr("id", "zoom-out").attr("title", "Zoom out").tipsy( {gravity: 'n'} ) + .click(function() { view.zoom_out(); view.request_redraw(); }).appendTo(this.nav_controls); + this.zi_link = $("<a/>").attr("id", "zoom-in").attr("title", "Zoom in").tipsy( {gravity: 'n'} ) + .click(function() { view.zoom_in(); view.request_redraw(); }).appendTo(this.nav_controls); // Get initial set of chroms. this.load_chroms_deferred = this.load_chroms({low: 0}); @@ -1069,7 +1072,6 @@ this.reset(); $(window).trigger("resize"); - this.update_intro_div(); }, /** Add or remove intro div depending on view state. */ update_intro_div: function() { diff -r b80ca015c305cc0768de10dbf60c38bd91abca50 -r 545288e40ee10ed48d422eb772b734ace1422451 static/scripts/trackster_ui.js --- a/static/scripts/trackster_ui.js +++ b/static/scripts/trackster_ui.js @@ -111,6 +111,9 @@ } } + // Need to update intro div after drawables have been added. + view.update_intro_div(); + // Set overview. var overview_track; for (var i = 0; i < view.drawables.length; i++) { Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.