Skip to content

Commit

Permalink
implement z-score scaling
Browse files Browse the repository at this point in the history
  • Loading branch information
brentp committed Oct 6, 2020
1 parent fc1566d commit fcd4d50
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 11 deletions.
6 changes: 4 additions & 2 deletions src/seqcoverpkg/seqcover.html
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,13 @@ <h5>Coverage summary</h5>
<div class="input-group-prepend">
<span class="input-group-text">Sample Scaling</span>
</div>
<input class="form-control z_scale" type="checkbox" id="z_scale_samples">
<input class="form-control z_scale" type="checkbox"
id="z_scale_samples" title="scale values within each sample">
<div class="input-group-prepend">
<span class="input-group-text">Gene Scaling</span>
</div>
<input class="form-control z_scale" type="checkbox" id="z_scale_genes">
<input class="form-control z_scale" type="checkbox"
id="z_scale_genes" title="scale values within each gene">
</div>
<div class="input-group input-group-sm">
<div class="input-group-prepend">
Expand Down
47 changes: 38 additions & 9 deletions src/seqcoverpkg/seqcover.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ function setHashParams(obj) {

window.onhashchange = function(event) {
let old_hp = getHashParams(new URL(event.oldURL).hash.substring(1))
// console.log(old_hp)
let new_hp = getHashParams()
update_selected_gene_header(new_hp.gene)
}
Expand Down Expand Up @@ -290,15 +289,13 @@ function handle_hover(data, depth_traces, gene, gene_layout) {

let low_depth_cutoff = 7; // TODO: get this from user-form input.
var selection_stats = transcript.stats([{ start: start_idx, stop: stop_idx }], gene.plot_coords.depths, gene.plot_coords.background_depths, low_depth_cutoff)
// console.log(selection_stats)

var tx_stats = transcript.stats([{ start: 0, stop: gene.plot_coords.x.length }], gene.plot_coords.depths, gene.plot_coords.background_depths, low_depth_cutoff)

// example of how to get stats for all CDSs. NOTE: this should only be done
// once per gene and result cached.
var cds = transcript.parts().filter(p => p.type == FeatureType.CDS)
var cds_stats = transcript.stats(cds, gene.plot_coords.depths, gene.plot_coords.background_depths, low_depth_cutoff)
// console.log("CDS:", cds_stats)

var gstart = gene.plot_coords.g[start_idx]
var gstop = gene.plot_coords.g[stop_idx]
Expand Down Expand Up @@ -378,6 +375,9 @@ function tie_heatmap_to_line_plot() {

function draw_heatmap() {

let sample_z_scale = jQuery('#z_scale_samples').is(":checked")
let gene_z_scale = jQuery('#z_scale_genes').is(":checked")

let stat_metric = jQuery("#metric_select").val()

var low_depth_cutoff = 7;
Expand All @@ -394,11 +394,9 @@ function draw_heatmap() {
var transcript = g.unioned_transcript
var stats = null
if (is_cds) {
// console.log("CDS")
var cds = transcript.parts().filter(p => p.type == FeatureType.CDS)
stats = transcript.stats(cds, g.plot_coords.depths, g.plot_coords.background_depths, low_depth_cutoff)
} else {
// console.log("transcript")
stats = transcript.stats([{ start: 0, stop: g.plot_coords.x.length }], g.plot_coords.depths, g.plot_coords.background_depths, low_depth_cutoff)
}

Expand All @@ -410,9 +408,18 @@ function draw_heatmap() {
}
row.push(stats[s][metric])
}
// console.log(row)
// row is a set of samples for a given metric
if(gene_z_scale) {
row = z_transform(row)
}

z.push(row)
}

if(sample_z_scale) {
z = z_transform_columns(z)
}

// heatmap draws from bottom up by default
z = z.reverse()
y = y.reverse()
Expand All @@ -429,8 +436,8 @@ function draw_heatmap() {
font: { size: 14 },
}
// TODO: this should be based on window width.
if(hlayout.width < 700) {
hlayout.width = 700;
if(hlayout.width < jQuery('#heatmap_plot').width()) {
hlayout.width = jQuery('#heatmap_plot').width();
}
let heatmap_config = {
displaylogo: false,
Expand Down Expand Up @@ -537,7 +544,8 @@ jQuery(document).ready(function () {
}
}

jQuery('#metric_select').on('change', function() { draw_heatmap() }).trigger('change')
jQuery('#metric_select,.z_scale').on('change', function() { draw_heatmap() })
jQuery('#metric_select').trigger('change')
var p = getHashParams();
var i = 0;
if ("gene" in p) {
Expand Down Expand Up @@ -572,3 +580,24 @@ jQuery(document).ready(function () {
}
})
})


function z_transform_columns(z) {
var ztr = new Array(z.length);
for(var rowi=0; rowi < z.length; rowi++){
ztr[rowi] = new Array(z[0].length)
}

for(var coli=0; coli < z[0].length; coli++){
var col = []
for(var rowi=0; rowi < z.length; rowi++) {
col.push(z[rowi][coli])
}
var tr = z_transform(col)
for(var rowi=0; rowi < z.length; rowi++) {
ztr[rowi][coli] = tr[rowi];
}

}
return ztr
}
13 changes: 13 additions & 0 deletions src/seqcoverpkg/transcript.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,24 @@ class Transcript {
}
}

function z_transform(data) {
// TODO: use 1-pass for mean, sd
var s = 0
for(let d of data) s += d;
let mean = s / data.length;

var sd = 0;
for(let d of data) { sd += Math.pow(d - mean, 2); }
sd = Math.sqrt(sd / data.length);

return data.map(d => (d - mean) / sd)
}

try {
// node.js stuff to allow testing
exports.Transcript = Transcript
exports.FeatureType = FeatureType
exports.z_transform = z_transform


if (require.main === module) {
Expand Down
13 changes: 13 additions & 0 deletions test/transcript-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,18 @@ describe('Transcript', function () {

})
});
describe('zscore tests', function () {
it('should return correct zscore', function (){
var vals = [2, 4, 6,7,8,9]
var expected = [-1.6803361 , -0.84016805, 0. , 0.42008403, 0.84016805,
1.26025208]

let zs = transcript.z_transform(vals)
for(var i=0; i <vals.length; i++){
assert(Math.abs(zs[i] - expected[i]) < 0.0001, "expected:" + expected[i] + " obs:" + zs[i])
}

})

})
});

0 comments on commit fcd4d50

Please sign in to comment.