From b73346af1c423103625545168271af7f1389623f Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Tue, 17 Dec 2013 23:29:38 +0000 Subject: Added the option to choose which method to use for the interval mapping function (pyLMM or qtl reaper) --- .../wqflask/interval_mapping/interval_mapping.py | 97 +++++++++++++++------- .../wqflask/marker_regression/marker_regression.py | 1 - .../static/new/javascript/interval_mapping.coffee | 57 ++++++------- .../static/new/javascript/interval_mapping.js | 21 ++--- .../static/new/javascript/marker_regression.coffee | 8 +- .../static/new/javascript/marker_regression.js | 7 +- .../new/javascript/show_trait_mapping_tools.coffee | 5 ++ .../new/javascript/show_trait_mapping_tools.js | 7 +- wqflask/wqflask/templates/base.html | 2 +- wqflask/wqflask/templates/interval_mapping.html | 15 ++-- wqflask/wqflask/templates/show_trait.html | 4 +- .../templates/show_trait_mapping_tools.html | 16 +++- wqflask/wqflask/views.py | 1 + 13 files changed, 153 insertions(+), 88 deletions(-) diff --git a/wqflask/wqflask/interval_mapping/interval_mapping.py b/wqflask/wqflask/interval_mapping/interval_mapping.py index de7a2704..f0985cc2 100755 --- a/wqflask/wqflask/interval_mapping/interval_mapping.py +++ b/wqflask/wqflask/interval_mapping/interval_mapping.py @@ -37,8 +37,6 @@ class IntervalMapping(object): def __init__(self, start_vars, temp_uuid): - print("TESTING!!!") - #Currently only getting trait data for one trait, but will need #to change this to accept multiple traits once the collection page is implemented helper_functions.get_species_dataset_trait(self, start_vars) @@ -57,7 +55,11 @@ class IntervalMapping(object): self.set_options(start_vars) - self.gen_qtl_results(tempdata) + if self.method == "qtl_reaper": + self.gen_reaper_results(tempdata) + else: + self.gen_pylmm_results(tempdata) + #self.gen_qtl_results(tempdata) #Get chromosome lengths for drawing the interval map plot chromosome_mb_lengths = {} @@ -78,6 +80,7 @@ class IntervalMapping(object): #self.plot_scale = start_vars['scale'] #if self.plotScale == 'physic' and not fd.genotype.Mbmap: # self.plotScale = 'morgan' + self.method = start_vars['mapping_method'] self.num_permutations = int(start_vars['num_permutations']) #self.do_bootstrap = start_vars['do_bootstrap'] self.selected_chr = start_vars['chromosome'] @@ -125,9 +128,6 @@ class IntervalMapping(object): # variance = variances, # control = self.control_locus) #else: - #reaper_results = self.dataset.group.genotype.regression(strains = trimmed_samples, - # trait = trimmed_values, - # control = self.control_locus) reaper_results = genotype.regression(strains = trimmed_samples, trait = trimmed_values, control = self.control_locus) @@ -139,8 +139,6 @@ class IntervalMapping(object): #else: print("strains:", trimmed_samples) print("trait:", trimmed_values) - #reaper_results = self.dataset.group.genotype.regression(strains = trimmed_samples, - # trait = trimmed_values) reaper_results = genotype.regression(strains = trimmed_samples, trait = trimmed_values) @@ -152,29 +150,70 @@ class IntervalMapping(object): qtl = {"lrs": qtl.lrs, "locus": locus, "additive": qtl.additive} self.qtl_results.append(qtl) - #pheno_vector = np.array([val == "x" and np.nan or float(val) for val in self.vals]) - #if self.dataset.group.species == "human": - # p_values, t_stats = self.gen_human_results(pheno_vector, tempdata) - #else: - #genotype_data = [marker['genotypes'] for marker in self.dataset.group.markers.markers] - # - #no_val_samples = self.identify_empty_samples() - #trimmed_genotype_data = self.trim_genotypes(genotype_data, no_val_samples) - # - #genotype_matrix = np.array(trimmed_genotype_data).T - - #t_stats, p_values = lmm.run( - # pheno_vector, - # genotype_matrix, - # restricted_max_likelihood=True, - # refit=False, - # temp_data=tempdata - #) - - #self.dataset.group.markers.add_pvalues(p_values) + def gen_reaper_results(self, tempdata): + genotype = self.dataset.group.read_genotype_file() + + samples, values, variances = self.this_trait.export_informative() + + trimmed_samples = [] + trimmed_values = [] + for i in range(0, len(samples)): + if samples[i] in self.dataset.group.samplelist: + trimmed_samples.append(samples[i]) + trimmed_values.append(values[i]) + + self.lrs_array = genotype.permutation(strains = trimmed_samples, + trait = trimmed_values, + nperm= self.num_permutations) + self.suggestive = self.lrs_array[int(self.num_permutations*0.37-1)] + self.significant = self.lrs_array[int(self.num_permutations*0.95-1)] + + print("samples:", trimmed_samples) + + if self.control_locus: + reaper_results = genotype.regression(strains = trimmed_samples, + trait = trimmed_values, + control = self.control_locus) + else: + reaper_results = genotype.regression(strains = trimmed_samples, + trait = trimmed_values) + + #Need to convert the QTL objects that qtl reaper returns into a json serializable dictionary + self.qtl_results = [] + for qtl in reaper_results: + reaper_locus = qtl.locus + locus = {"name":reaper_locus.name, "chr":reaper_locus.chr, "cM":reaper_locus.cM, "Mb":reaper_locus.Mb} + qtl = {"lrs_value": qtl.lrs, "chr":reaper_locus.chr, "Mb":reaper_locus.Mb, + "cM":reaper_locus.cM, "name":reaper_locus.name, "additive":qtl.additive} + self.qtl_results.append(qtl) + + def gen_pylmm_results(self, tempdata): + print("USING PYLMM") + self.dataset.group.get_markers() - #self.qtl_results = self.dataset.group.markers.markers + pheno_vector = np.array([val == "x" and np.nan or float(val) for val in self.vals]) + if self.dataset.group.species == "human": + p_values, t_stats = self.gen_human_results(pheno_vector, tempdata) + else: + genotype_data = [marker['genotypes'] for marker in self.dataset.group.markers.markers] + + no_val_samples = self.identify_empty_samples() + trimmed_genotype_data = self.trim_genotypes(genotype_data, no_val_samples) + + genotype_matrix = np.array(trimmed_genotype_data).T + + t_stats, p_values = lmm.run( + pheno_vector, + genotype_matrix, + restricted_max_likelihood=True, + refit=False, + temp_data=tempdata + ) + + print("p_values:", p_values) + self.dataset.group.markers.add_pvalues(p_values) + self.qtl_results = self.dataset.group.markers.markers def gen_qtl_results_2(self, tempdata): """Generates qtl results for plotting interval map""" diff --git a/wqflask/wqflask/marker_regression/marker_regression.py b/wqflask/wqflask/marker_regression/marker_regression.py index 334ce631..006c586b 100755 --- a/wqflask/wqflask/marker_regression/marker_regression.py +++ b/wqflask/wqflask/marker_regression/marker_regression.py @@ -91,7 +91,6 @@ class MarkerRegression(object): ) self.dataset.group.markers.add_pvalues(p_values) - self.qtl_results = self.dataset.group.markers.markers diff --git a/wqflask/wqflask/static/new/javascript/interval_mapping.coffee b/wqflask/wqflask/static/new/javascript/interval_mapping.coffee index 0aa21d97..81db186b 100644 --- a/wqflask/wqflask/static/new/javascript/interval_mapping.coffee +++ b/wqflask/wqflask/static/new/javascript/interval_mapping.coffee @@ -66,30 +66,30 @@ $ -> chr_lengths.push(this_length) cumulative_chr_lengths.push(total_length + this_length) total_length += this_length - + console.log("chr_lengths: ", chr_lengths) - + return [chr_lengths, cumulative_chr_lengths] - + create_coordinates: () -> chr_lengths = [] chr_seen = [] for result in js_data.qtl_results - if result.locus.chr == "X" + if result.chr == "X" chr_length = parseFloat(@chromosomes[20]) else - chr_length = parseFloat(@chromosomes[result.locus.chr]) - if not(result.locus.chr in chr_seen) - chr_seen.push(result.locus.chr) + chr_length = parseFloat(@chromosomes[result.chr]) + if not(result.chr in chr_seen) + chr_seen.push(result.chr) chr_lengths.push(chr_length) - if result.locus.chr != "1" + if result.chr != "1" @total_length += parseFloat(chr_lengths[chr_lengths.length - 2]) - @x_coords.push(@total_length + parseFloat(result.locus.Mb)) - @y_coords.push(result.lrs) - @marker_names.push(result.locus.name) + @x_coords.push(@total_length + parseFloat(result.Mb)) + @y_coords.push(result.lrs_value) + @marker_names.push(result.name) @total_length += parseFloat(chr_lengths[chr_lengths.length-1]) #console.log("chr_lengths: ", chr_lengths) - + create_svg: () -> svg = d3.select("#interval_map") .append("svg") @@ -98,7 +98,7 @@ $ -> .attr("height", @plot_height+@y_buffer) return svg - + create_graph: () -> @add_border() @add_x_axis() @@ -107,13 +107,13 @@ $ -> @fill_chr_areas() @add_chr_labels() @connect_markers() - + add_border: () -> border_coords = [[@y_buffer, @plot_height, @x_buffer, @x_buffer], [@y_buffer, @plot_height, @plot_width, @plot_width], [@y_buffer, @y_buffer, @x_buffer, @plot_width], [@plot_height, @plot_height, @x_buffer, @plot_width]] - + @svg.selectAll("line") .data(border_coords) .enter() @@ -131,16 +131,16 @@ $ -> return d[3] ) .style("stroke", "#000") - + create_scales: () -> @x_scale = d3.scale.linear() .domain([0, d3.max(@x_coords)]) .range([@x_buffer, @plot_width]) - + @y_scale = d3.scale.linear() .domain([0, @y_max]) .range([@plot_height, @y_buffer]) - + create_x_axis_tick_values: () -> tick_vals = [] for val in [25..@cumulative_chr_lengths[0]] when val%25 == 0 @@ -159,13 +159,13 @@ $ -> #console.log("tick_vals:", tick_vals) return tick_vals - + add_x_axis: () -> xAxis = d3.svg.axis() .scale(@x_scale) .orient("bottom") .tickValues(@create_x_axis_tick_values()) - + next_chr = 1 tmp_tick_val = 0 xAxis.tickFormat((d) => @@ -183,7 +183,7 @@ $ -> tick_val = tmp_tick_val return (tick_val) ) - + @svg.append("g") .attr("class", "x_axis") .attr("transform", "translate(0," + @plot_height + ")") @@ -196,7 +196,7 @@ $ -> ) #.attr("dy", "-1.0em") - + add_y_axis: () -> yAxis = d3.svg.axis() .scale(@y_scale) @@ -207,7 +207,7 @@ $ -> .attr("class", "y_axis") .attr("transform", "translate(" + @x_buffer + ",0)") .call(yAxis) - + add_chr_lines: () -> @svg.selectAll("line") .data(@cumulative_chr_lengths, (d) => @@ -241,7 +241,7 @@ $ -> ) .attr("height", @plot_height-@y_buffer) .attr("fill", "white") - + add_chr_labels: () -> chr_names = [] for key of @chromosomes @@ -265,7 +265,7 @@ $ -> .attr("font-family", "sans-serif") .attr("font-size", "18px") #.attr("fill", "grey") - + connect_markers: () -> @svg.selectAll("line") .data(@plot_coordinates) @@ -290,7 +290,8 @@ $ -> return @plot_height - ((@plot_height-@y_buffer) * d[1]/@y_max) ) .style("stroke", "black") - - console.time('Create manhattan plot') + + console.time('Create interval map') + console.log("TESTING") new Interval_Map(600, 1200) - console.timeEnd('Create manhattan plot') \ No newline at end of file + console.timeEnd('Create interval map') \ No newline at end of file diff --git a/wqflask/wqflask/static/new/javascript/interval_mapping.js b/wqflask/wqflask/static/new/javascript/interval_mapping.js index 521a1c7a..3a2ce6d7 100644 --- a/wqflask/wqflask/static/new/javascript/interval_mapping.js +++ b/wqflask/wqflask/static/new/javascript/interval_mapping.js @@ -85,21 +85,21 @@ _ref = js_data.qtl_results; for (_i = 0, _len = _ref.length; _i < _len; _i++) { result = _ref[_i]; - if (result.locus.chr === "X") { + if (result.chr === "X") { chr_length = parseFloat(this.chromosomes[20]); } else { - chr_length = parseFloat(this.chromosomes[result.locus.chr]); + chr_length = parseFloat(this.chromosomes[result.chr]); } - if (!(_ref1 = result.locus.chr, __indexOf.call(chr_seen, _ref1) >= 0)) { - chr_seen.push(result.locus.chr); + if (!(_ref1 = result.chr, __indexOf.call(chr_seen, _ref1) >= 0)) { + chr_seen.push(result.chr); chr_lengths.push(chr_length); - if (result.locus.chr !== "1") { + if (result.chr !== "1") { this.total_length += parseFloat(chr_lengths[chr_lengths.length - 2]); } } - this.x_coords.push(this.total_length + parseFloat(result.locus.Mb)); - this.y_coords.push(result.lrs); - this.marker_names.push(result.locus.name); + this.x_coords.push(this.total_length + parseFloat(result.Mb)); + this.y_coords.push(result.lrs_value); + this.marker_names.push(result.name); } return this.total_length += parseFloat(chr_lengths[chr_lengths.length - 1]); }; @@ -264,9 +264,10 @@ return Interval_Map; })(); - console.time('Create manhattan plot'); + console.time('Create interval map'); + console.log("TESTING"); new Interval_Map(600, 1200); - return console.timeEnd('Create manhattan plot'); + return console.timeEnd('Create interval map'); }); }).call(this); diff --git a/wqflask/wqflask/static/new/javascript/marker_regression.coffee b/wqflask/wqflask/static/new/javascript/marker_regression.coffee index 2892987e..f5f13c27 100644 --- a/wqflask/wqflask/static/new/javascript/marker_regression.coffee +++ b/wqflask/wqflask/static/new/javascript/marker_regression.coffee @@ -49,10 +49,10 @@ $ -> get_chr_lengths: () -> ### - Gets a list of both individual and cumulative (the position of one on the graph - is its own length plus the lengths of all preceding chromosomes) lengths in order - to draw the vertical lines separating chromosomes and the chromosome labels - + #Gets a list of both individual and cumulative (the position of one on the graph + #is its own length plus the lengths of all preceding chromosomes) lengths in order + #to draw the vertical lines separating chromosomes and the chromosome labels + # ### console.log("@chromosomes: ", @chromosomes) diff --git a/wqflask/wqflask/static/new/javascript/marker_regression.js b/wqflask/wqflask/static/new/javascript/marker_regression.js index ffcf1a75..cdf37671 100644 --- a/wqflask/wqflask/static/new/javascript/marker_regression.js +++ b/wqflask/wqflask/static/new/javascript/marker_regression.js @@ -57,9 +57,10 @@ Manhattan_Plot.prototype.get_chr_lengths = function() { /* - Gets a list of both individual and cumulative (the position of one on the graph - is its own length plus the lengths of all preceding chromosomes) lengths in order - to draw the vertical lines separating chromosomes and the chromosome labels + #Gets a list of both individual and cumulative (the position of one on the graph + #is its own length plus the lengths of all preceding chromosomes) lengths in order + #to draw the vertical lines separating chromosomes and the chromosome labels + # */ var chr_lengths, cumulative_chr_lengths, key, this_length, total_length; diff --git a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.coffee b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.coffee index 8571753e..df9bfc9d 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.coffee +++ b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.coffee @@ -53,6 +53,7 @@ $ -> return false $("#interval_mapping_compute").click(() => + console.log("In interval mapping") $("#progress_bar_container").modal() url = "/interval_mapping" form_data = $('#trait_data_form').serialize() @@ -118,8 +119,12 @@ $ -> composite_mapping_fields = -> $(".composite_fields").toggle() + mapping_method_fields = -> + $(".mapping_method_fields").toggle() + $("#use_composite_choice").change(composite_mapping_fields) + $("#mapping_method_choice").change(mapping_method_fields) #### Todo: Redo below so its like submit_special and requires no js hardcoding diff --git a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js index 1153b8ef..b474bd80 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js +++ b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js @@ -5,7 +5,7 @@ root = typeof exports !== "undefined" && exports !== null ? exports : this; $(function() { - var composite_mapping_fields, get_progress, submit_special, toggle_enable_disable, update_time_remaining, + var composite_mapping_fields, get_progress, mapping_method_fields, submit_special, toggle_enable_disable, update_time_remaining, _this = this; submit_special = function() { var url; @@ -64,6 +64,7 @@ }; $("#interval_mapping_compute").click(function() { var form_data, url; + console.log("In interval mapping"); $("#progress_bar_container").modal(); url = "/interval_mapping"; form_data = $('#trait_data_form').serialize(); @@ -128,7 +129,11 @@ composite_mapping_fields = function() { return $(".composite_fields").toggle(); }; + mapping_method_fields = function() { + return $(".mapping_method_fields").toggle(); + }; $("#use_composite_choice").change(composite_mapping_fields); + $("#mapping_method_choice").change(mapping_method_fields); toggle_enable_disable = function(elem) { return $(elem).prop("disabled", !$(elem).prop("disabled")); }; diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html index 0360f619..9b98c955 100644 --- a/wqflask/wqflask/templates/base.html +++ b/wqflask/wqflask/templates/base.html @@ -212,7 +212,7 @@ - + diff --git a/wqflask/wqflask/templates/interval_mapping.html b/wqflask/wqflask/templates/interval_mapping.html index 25de2dc1..e4e08388 100644 --- a/wqflask/wqflask/templates/interval_mapping.html +++ b/wqflask/wqflask/templates/interval_mapping.html @@ -1,7 +1,6 @@ {% extends "base.html" %} {% block title %}Interval Mapping{% endblock %} {% block css %} - @@ -31,7 +30,9 @@ Index LRS Score + {% if method == "qtl_reaper" %} Additive Effect + {% endif %} Chr Mb Locus @@ -41,11 +42,13 @@ {% for marker in qtl_results %} {{ loop.index }} - {{ marker.lrs|float }} + {{ marker.lrs_value|float }} + {% if method == "qtl_reaper" %} {{ marker.additive|float }} - {{ marker.locus.chr|int }} - {{ marker.locus.Mb|float }} - {{ marker.locus.name }} + {% endif %} + {{ marker.chr|int }} + {{ marker.Mb|float }} + {{ marker.name }} {% endfor %} @@ -63,7 +66,7 @@ diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index 0ad6eedb..86891bb0 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -59,8 +59,8 @@ - - + + {% endblock %} diff --git a/wqflask/wqflask/templates/show_trait_mapping_tools.html b/wqflask/wqflask/templates/show_trait_mapping_tools.html index a835a41b..58ee8982 100644 --- a/wqflask/wqflask/templates/show_trait_mapping_tools.html +++ b/wqflask/wqflask/templates/show_trait_mapping_tools.html @@ -16,6 +16,16 @@
+
+ +
+ +
+
+
@@ -28,14 +38,14 @@
-
+
-
+
@@ -44,7 +54,7 @@
-
+