about summary refs log tree commit diff
diff options
context:
space:
mode:
authorZachary Sloan2013-12-17 23:29:38 +0000
committerZachary Sloan2013-12-17 23:29:38 +0000
commitb73346af1c423103625545168271af7f1389623f (patch)
treee32ac40d961b8b4ad5217377a5a5ae63467e9a8f
parent17ed5f2a56e03ded169b3191a7a7d280c5b584bf (diff)
downloadgenenetwork2-b73346af1c423103625545168271af7f1389623f.tar.gz
Added the option to choose which method to use for the interval
mapping function (pyLMM or qtl reaper)
-rwxr-xr-xwqflask/wqflask/interval_mapping/interval_mapping.py97
-rwxr-xr-xwqflask/wqflask/marker_regression/marker_regression.py1
-rw-r--r--wqflask/wqflask/static/new/javascript/interval_mapping.coffee57
-rw-r--r--wqflask/wqflask/static/new/javascript/interval_mapping.js21
-rw-r--r--wqflask/wqflask/static/new/javascript/marker_regression.coffee8
-rw-r--r--wqflask/wqflask/static/new/javascript/marker_regression.js7
-rw-r--r--wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.coffee5
-rw-r--r--wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js7
-rw-r--r--wqflask/wqflask/templates/base.html2
-rw-r--r--wqflask/wqflask/templates/interval_mapping.html15
-rw-r--r--wqflask/wqflask/templates/show_trait.html4
-rw-r--r--wqflask/wqflask/templates/show_trait_mapping_tools.html16
-rw-r--r--wqflask/wqflask/views.py1
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 @@
     </script>
     <script src="/static/new/js_external/jquery.cookie.js"></script>
     <script type="text/javascript" src="/static/new/js_external/json2.js"></script>
-<!--    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js" type="text/javascript"></script>-->
+    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js" type="text/javascript"></script>
 
     <script language="javascript" type="text/javascript" src="/static/packages/colorbox/jquery.colorbox.js"></script>
     <!--<script type="text/javascript" src="/static/new/javascript/login.js"></script>-->
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 %}

-    <link rel="stylesheet" type="text/css" href="/static/packages/jqplot/jquery.jqplot.min.css" />

     <link rel="stylesheet" type="text/css" href="/static/new/css/interval_mapping.css" />

     <link rel="stylesheet" type="text/css" href="/static/new/packages/DataTables/css/jquery.dataTables.css" />

     <link rel="stylesheet" type="text/css" href="/static/packages/DT_bootstrap/DT_bootstrap.css" />

@@ -31,7 +30,9 @@
                 <tr>

                     <td>Index</td>

                     <td>LRS Score</td>

+                    {% if method == "qtl_reaper" %}

                     <td>Additive Effect</td>

+                    {% endif %}

                     <td>Chr</td>

                     <td>Mb</td>

                     <td>Locus</td>

@@ -41,11 +42,13 @@
                 {% for marker in qtl_results %}

                 <tr>

                     <td>{{ loop.index }}</td>

-                    <td>{{ marker.lrs|float }}</td>

+                    <td>{{ marker.lrs_value|float }}</td>

+                    {% if method == "qtl_reaper" %}

                     <td>{{ marker.additive|float }}</td>

-                    <td>{{ marker.locus.chr|int }}</td>

-                    <td>{{ marker.locus.Mb|float  }}</td>

-                    <td>{{ marker.locus.name }}</td>

+                    {% endif %}

+                    <td>{{ marker.chr|int }}</td>

+                    <td>{{ marker.Mb|float  }}</td>

+                    <td>{{ marker.name }}</td>

                 </tr>

                 {% endfor %}

             </tbody>

@@ -63,7 +66,7 @@
     </script>

 

     <!--[if lt IE 9]>

-        <script language="javascript" type="text/javascript" src="/static/packages/jqplot/excanvas.js"></script>

+<!--        <script language="javascript" type="text/javascript" src="/static/packages/jqplot/excanvas.js"></script>-->

     <![endif]-->

     <script language="javascript" type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>

     <script language="javascript" type="text/javascript" src="/static/new/javascript/interval_mapping.js"></script>

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 @@
     <script type="text/javascript" src="/static/new/javascript/get_traits_from_collection.js"></script>    
     <script type="text/javascript" src="/static/new/javascript/bar_chart.js"></script>
     <script type="text/javascript" src="/static/new/javascript/box_plot.js"></script>
-
-    <script type="text/javascript" src="/static/new/javascript/show_trait.js"></script>
+    
     <script type="text/javascript" src="/static/new/javascript/show_trait_mapping_tools.js"></script>
+    <script type="text/javascript" src="/static/new/javascript/show_trait.js"></script>
     <script type="text/javascript" src="/static/new/javascript/validation.js"></script>
 {% 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
@@ -17,6 +17,16 @@
             <div class="tab-content">
                 <div class="tab-pane active" id="interval_mapping">
                     <div class="control-group">
+                        <label for="mapping_method" class="control-label">Mapping Method</label>
+                        <div class="controls" id="mapping_method_choice">
+                            <select name="mapping_method">
+                                <option value="qtl_reaper">H&K Regression</option>
+                                <option value="pylmm">Linear Mixed</option>
+                            </select>
+                        </div>
+                    </div>
+                    
+                    <div class="control-group">
                         <label for="chromosome" class="control-label">Chromosome</label>
                         <div class="controls">
                             <select name="chromosome">
@@ -28,14 +38,14 @@
                         </div>
                     </div>
     
-                    <div class="control-group">
+                    <div class="control-group mapping_method_fields">
                         <label for="mapping_permutations" class="control-label">Permutations (n)</label>
                         <div class="controls">
                             <input name="num_permutations" value="2000" type="text" />
                         </div>
                     </div>
     
-                    <div class="control-group">
+                    <div class="control-group mapping_method_fields">
                         <label for="mapping_bootstraps" class="control-label"
                                title="Bootstrapping Resamples">Bootstrap (n)</label>
                         <div class="controls">
@@ -44,7 +54,7 @@
                     </div>
 
 
-                    <div class="control-group">
+                    <div class="control-group mapping_method_fields">
                         <label class="control-label"><b>Composite Mapping</b></label>
                         <div class="controls" id="use_composite_choice">                      
                             <label class="radio inline">
diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py
index b528f2b1..828199c5 100644
--- a/wqflask/wqflask/views.py
+++ b/wqflask/wqflask/views.py
@@ -258,6 +258,7 @@ def interval_mapping_page():
     wanted = (
         'trait_id',
         'dataset',
+        'mapping_method',
         'chromosome',
         'num_permutations',
         'do_bootstraps',