about summary refs log tree commit diff
diff options
context:
space:
mode:
authorZachary Sloan2014-07-25 16:28:51 +0000
committerZachary Sloan2014-07-25 16:28:51 +0000
commite69c346553bc26c2f1ba8b0d9fc394add9f6784f (patch)
tree1eec23a32cf658d303b28aaba7b4782cc9e38023
parentb3058f8c3710c65288d88ed777aa0fcad8429aef (diff)
downloadgenenetwork2-e69c346553bc26c2f1ba8b0d9fc394add9f6784f.tar.gz
Got the heatmap/lodchart combo working
Started working on getting rqtl working as another mapping method
-rw-r--r--wqflask/wqflask/heatmap/heatmap.py171
-rwxr-xr-xwqflask/wqflask/marker_regression/marker_regression.py19
-rwxr-xr-xwqflask/wqflask/static/new/javascript/corr_scatter_plot.js138
-rw-r--r--wqflask/wqflask/static/new/javascript/create_heatmap.coffee6
-rw-r--r--wqflask/wqflask/static/new/javascript/create_heatmap.js6
-rw-r--r--wqflask/wqflask/static/new/javascript/curvechart.coffee335
-rw-r--r--wqflask/wqflask/static/new/javascript/curvechart.js353
-rw-r--r--wqflask/wqflask/static/new/javascript/iplotMScanone_noeff.coffee192
-rw-r--r--wqflask/wqflask/static/new/javascript/iplotMScanone_noeff.js113
-rw-r--r--wqflask/wqflask/static/new/javascript/lod_chart.coffee267
-rw-r--r--wqflask/wqflask/static/new/javascript/lod_chart.js224
-rw-r--r--wqflask/wqflask/static/new/javascript/lodheatmap.coffee4
-rw-r--r--wqflask/wqflask/static/new/javascript/lodheatmap.js4
-rw-r--r--wqflask/wqflask/static/new/javascript/show_corr.js15
-rw-r--r--wqflask/wqflask/templates/heatmap.html7
-rwxr-xr-xwqflask/wqflask/views.py2
16 files changed, 1409 insertions, 447 deletions
diff --git a/wqflask/wqflask/heatmap/heatmap.py b/wqflask/wqflask/heatmap/heatmap.py
index 8f910fa9..0433bf17 100644
--- a/wqflask/wqflask/heatmap/heatmap.py
+++ b/wqflask/wqflask/heatmap/heatmap.py
@@ -55,6 +55,8 @@ class Heatmap(object):
         

         helper_functions.get_trait_db_obs(self, trait_db_list)

         

+        self.temp_uuid = temp_uuid

+        self.num_permutations = 5000

         self.dataset = self.trait_list[0][1]

         

         self.json_data = {} #The dictionary that will be used to create the json object that contains all the data needed to create the figure

@@ -86,6 +88,135 @@ class Heatmap(object):
                     #self.sample_data[this_trait.name].append('')

             self.sample_data.append(this_trait_vals)

 

+        self.gen_reaper_results()

+        #self.gen_pylmm_results()

+            

+        chrnames = []

+        lodnames = []

+        chr_pos = []

+        pos = []

+        markernames = []

+        

+        for trait in self.trait_results.keys():

+            lodnames.append(trait)

+        

+        for marker in self.dataset.group.markers.markers:

+            if marker['chr'] not in chrnames:

+                chrnames.append(marker['chr'])

+            chr_pos.append(marker['chr'])

+            pos.append(marker['Mb'])

+            markernames.append(marker['name'])

+            

+        self.json_data['chrnames'] = chrnames

+        self.json_data['lodnames'] = lodnames

+        self.json_data['chr'] = chr_pos

+        self.json_data['pos'] = pos

+        self.json_data['markernames'] = markernames

+        

+        for trait in self.trait_results:

+            self.json_data[trait] = self.trait_results[trait]

+            

+        self.js_data = dict(

+            json_data = self.json_data

+        )

+            

+        print("self.js_data:", self.js_data)

+        

+        

+    def gen_reaper_results(self):

+        self.trait_results = {}

+        for trait_db in self.trait_list:

+            self.dataset.group.get_markers()

+            this_trait = trait_db[0]

+            #this_db = trait_db[1]

+            genotype = self.dataset.group.read_genotype_file()

+            samples, values, variances = 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)]

+

+            reaper_results = genotype.regression(strains = trimmed_samples,

+                                                 trait = trimmed_values)

+

+

+            lrs_values = [float(qtl.lrs) for qtl in reaper_results]

+            print("lrs_values:", lrs_values)

+            #self.dataset.group.markers.add_pvalues(p_values)

+            

+            self.trait_results[this_trait.name] = []

+            for qtl in reaper_results:

+                if qtl.additive > 0:

+                    self.trait_results[this_trait.name].append(-float(qtl.lrs))

+                else:

+                    self.trait_results[this_trait.name].append(float(qtl.lrs))

+            #for lrs in lrs_values:

+            #    if 

+            #    self.trait_results[this_trait.name].append(lrs)

+            

+            

+            #this_db_samples = self.dataset.group.samplelist

+            #this_sample_data = this_trait.data

+            ##print("this_sample_data", this_sample_data)

+            #this_trait_vals = []

+            #for index, sample in enumerate(this_db_samples):

+            #    if sample in this_sample_data:

+            #        sample_value = this_sample_data[sample].value

+            #        this_trait_vals.append(sample_value)

+            #    else:

+            #        this_trait_vals.append("x")

+                    

+            #pheno_vector = np.array([val == "x" and np.nan or float(val) for val in this_trait_vals])

+            

+            #key = "pylmm:input:" + str(self.temp_uuid)

+            #print("key is:", pf(key))

+            

+            #genotype_data = [marker['genotypes'] for marker in self.dataset.group.markers.markers]

+            

+            #no_val_samples = self.identify_empty_samples(this_trait_vals)

+            #trimmed_genotype_data = self.trim_genotypes(genotype_data, no_val_samples)

+            

+            #genotype_matrix = np.array(trimmed_genotype_data).T

+            

+            #print("genotype_matrix:", str(genotype_matrix.tolist()))

+            #print("pheno_vector:", str(pheno_vector.tolist()))

+            

+            #params = dict(pheno_vector = pheno_vector.tolist(),

+            #            genotype_matrix = genotype_matrix.tolist(),

+            #            restricted_max_likelihood = True,

+            #            refit = False,

+            #            temp_uuid = str(self.temp_uuid),

+            #            

+            #            # meta data

+            #            timestamp = datetime.datetime.now().isoformat(),

+            #            )

+            #

+            #json_params = json.dumps(params)

+            ##print("json_params:", json_params)

+            #Redis.set(key, json_params)

+            #Redis.expire(key, 60*60)

+            #print("before printing command")

+            #

+            #command = 'python /home/zas1024/gene/wqflask/wqflask/my_pylmm/pyLMM/lmm.py --key {} --species {}'.format(key,

+            #                                                                                                        "other")

+            #print("command is:", command)

+            #print("after printing command")

+            #

+            #os.system(command)

+            #

+            #json_results = Redis.blpop("pylmm:results:" + str(self.temp_uuid), 45*60)

+                

+    def gen_pylmm_results(self):    

         self.trait_results = {}

         for trait_db in self.trait_list:

             this_trait = trait_db[0]

@@ -105,7 +236,7 @@ class Heatmap(object):
                     

             pheno_vector = np.array([val == "x" and np.nan or float(val) for val in this_trait_vals])

             

-            key = "pylmm:input:" + str(temp_uuid)

+            key = "pylmm:input:" + str(self.temp_uuid)

             #print("key is:", pf(key))

             

             genotype_data = [marker['genotypes'] for marker in self.dataset.group.markers.markers]

@@ -122,7 +253,7 @@ class Heatmap(object):
                         genotype_matrix = genotype_matrix.tolist(),

                         restricted_max_likelihood = True,

                         refit = False,

-                        temp_uuid = str(temp_uuid),

+                        temp_uuid = str(self.temp_uuid),

                         

                         # meta data

                         timestamp = datetime.datetime.now().isoformat(),

@@ -141,7 +272,7 @@ class Heatmap(object):
 

             os.system(command)

             

-            json_results = Redis.blpop("pylmm:results:" + str(temp_uuid), 45*60)

+            json_results = Redis.blpop("pylmm:results:" + str(self.temp_uuid), 45*60)

             results = json.loads(json_results[1])

             p_values = [float(result) for result in results['p_values']]

             #print("p_values:", p_values)

@@ -150,40 +281,8 @@ class Heatmap(object):
             self.trait_results[this_trait.name] = []

             for marker in self.dataset.group.markers.markers:

                 self.trait_results[this_trait.name].append(marker['lod_score'])

+                

 

-        #print("self.trait_results:", self.trait_results)

-            

-        chrnames = []

-        lodnames = []

-        chr_pos = []

-        pos = []

-        markernames = []

-        

-        for trait in self.trait_results.keys():

-            lodnames.append(trait)

-        

-        for marker in self.dataset.group.markers.markers:

-            if marker['chr'] not in chrnames:

-                chrnames.append(marker['chr'])

-            chr_pos.append(marker['chr'])

-            pos.append(marker['Mb'])

-            markernames.append(marker['name'])

-            

-        self.json_data['chrnames'] = chrnames

-        self.json_data['lodnames'] = lodnames

-        self.json_data['chr'] = chr_pos

-        self.json_data['pos'] = pos

-        self.json_data['markernames'] = markernames

-        

-        for trait in self.trait_results:

-            self.json_data[trait] = self.trait_results[trait]

-            

-        self.js_data = dict(

-            json_data = self.json_data

-        )

-            

-        print("self.js_data:", self.js_data)

-        

     def identify_empty_samples(self, values):

         no_val_samples = []

         for sample_count, val in enumerate(values):

diff --git a/wqflask/wqflask/marker_regression/marker_regression.py b/wqflask/wqflask/marker_regression/marker_regression.py
index 0a83f9f8..648cb49b 100755
--- a/wqflask/wqflask/marker_regression/marker_regression.py
+++ b/wqflask/wqflask/marker_regression/marker_regression.py
@@ -186,10 +186,18 @@ class MarkerRegression(object):
     #

     #

     

-    #def run_rqtl(self):

-    #    os.chdir("/home/zas1024/plink")

-    #    

-    

+    def run_rqtl(self):

+        os.chdir("/home/zas1024/plink")

+        

+        output_filename = webqtlUtil.genRandStr("%s_%s_"%(self.dataset.group.name, self.this_trait.name))

+        

+        self.gen_pheno_txt_file_plink(pheno_filename = output_filename)

+        

+        rqtl_command = './plink --noweb --ped %s.ped --no-fid --no-parents --no-sex --no-pheno --map %s.map --pheno %s/%s.txt --pheno-name %s --maf %s --missing-phenotype -9999 --out %s%s --assoc ' % (self.dataset.group.name, self.dataset.group.name, webqtlConfig.TMPDIR, plink_output_filename, self.this_trait.name, self.maf, webqtlConfig.TMPDIR, plink_output_filename)

+        

+        os.system(rqtl_command)

+        

+        count, p_values = self.parse_rqtl_output(plink_output_filename)

     

     def run_plink(self):

     

@@ -317,6 +325,9 @@ class MarkerRegression(object):
     #    return ChrList,ChrNameOrderIdDict,ChrOrderIdNameDict,ChrLengthMbList

     

     

+    def parse_rqtl_output(self, output_filename):

+        return True

+    

     def parse_plink_output(self, output_filename):

         plink_results={}

     

diff --git a/wqflask/wqflask/static/new/javascript/corr_scatter_plot.js b/wqflask/wqflask/static/new/javascript/corr_scatter_plot.js
index df1e62b6..b06c70f4 100755
--- a/wqflask/wqflask/static/new/javascript/corr_scatter_plot.js
+++ b/wqflask/wqflask/static/new/javascript/corr_scatter_plot.js
@@ -1,77 +1,73 @@
-// Generated by CoffeeScript 1.6.1
-(function() {
-  var Scatter_Plot, root;
+// Generated by CoffeeScript 1.7.1
+var Scatter_Plot, root;
 
-  root = typeof exports !== "undefined" && exports !== null ? exports : this;
+root = typeof exports !== "undefined" && exports !== null ? exports : this;
 
-  Scatter_Plot = (function() {
-
-    function Scatter_Plot() {
-      var chart, data, g, height, i, main, margin, maxx, maxy, minx, miny, sample1, sample2, samplename, samples_1, samples_2, text, width, x, xAxis, y, yAxis;
-      data = new Array();
-      samples_1 = js_data.samples_1;
-      samples_2 = js_data.samples_2;
-      i = 0;
-      for (samplename in samples_1) {
-        sample1 = samples_1[samplename];
-        sample2 = samples_2[samplename];
-        data[i++] = [sample1.value, sample2.value];
-      }
-      margin = {
-        top: 100,
-        right: 15,
-        bottom: 60,
-        left: 60
-      };
-      width = js_data.width - margin.left - margin.right;
-      height = js_data.height - margin.top - margin.bottom;
-      minx = d3.min(data, function(d) {
-        return d[0];
-      }) * 0.95;
-      maxx = d3.max(data, function(d) {
-        return d[0];
-      }) * 1.05;
-      miny = d3.min(data, function(d) {
-        return d[1];
-      }) * 0.95;
-      maxy = d3.max(data, function(d) {
-        return d[1];
-      }) * 1.05;
-      x = d3.scale.linear().domain([minx, maxx]).range([0, width]);
-      y = d3.scale.linear().domain([miny, maxy]).range([height, 0]);
-      chart = d3.select("#scatter_plot").append("svg:svg").attr("width", width + margin.right + margin.left).attr("height", height + margin.top + margin.bottom).attr("class", "chart");
-      main = chart.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")").attr("width", width).attr("height", height).attr("class", "main");
-      xAxis = d3.svg.axis().scale(x).orient("bottom");
-      main.append("g").attr("transform", "translate(0," + height + ")").attr("class", "main axis date").call(xAxis);
-      yAxis = d3.svg.axis().scale(y).orient("left");
-      main.append("g").attr("transform", "translate(0,0)").attr("class", "main axis date").call(yAxis);
-      g = main.append("svg:g");
-      g.selectAll("scatter-dots").data(data).enter().append("svg:circle").attr("cx", function(d) {
-        return x(d[0]);
-      }).attr("cy", function(d) {
-        return y(d[1]);
-      }).attr("fill", js_data.circle_color).attr("r", js_data.circle_radius);
-      main.append("line").attr("x1", x(minx)).attr("y1", y(js_data.slope * minx + js_data.intercept)).attr("x2", x(maxx * 0.995)).attr("y2", y(js_data.slope * maxx * 0.995 + js_data.intercept)).style("stroke", js_data.line_color).style("stroke-width", js_data.line_width);
-      chart.append("text").attr("x", width / 2).attr("y", margin.top / 2 - 25).text("Sample Correlation Scatterplot");
-      text = "";
-      text += "N=" + js_data.num_overlap;
-      chart.append("text").attr("x", margin.left).attr("y", margin.top / 2 - 5).text(text);
-      text = "";
-      text += "r=" + js_data.r_value + "\t";
-      text += "p(r)=" + js_data.p_value;
-      chart.append("text").attr("x", margin.left).attr("y", margin.top / 2 + 15).text(text);
-      text = "";
-      text += "slope=" + js_data.slope + "\t";
-      text += "intercept=" + js_data.intercept;
-      chart.append("text").attr("x", margin.left).attr("y", margin.top / 2 + 35).text(text);
-      chart.append("text").attr("x", width / 2).attr("y", height + margin.top + 35).text(js_data.trait_1);
-      chart.append("text").attr("x", 20).attr("y", height / 2 + margin.top + 30).attr("transform", "rotate(-90 20," + (height / 2 + margin.top + 30) + ")").text(js_data.trait_2);
+Scatter_Plot = (function() {
+  function Scatter_Plot() {
+    var chart, data, g, height, i, main, margin, maxx, maxy, minx, miny, sample1, sample2, samplename, samples_1, samples_2, text, width, x, xAxis, y, yAxis;
+    data = new Array();
+    samples_1 = js_data.samples_1;
+    samples_2 = js_data.samples_2;
+    i = 0;
+    for (samplename in samples_1) {
+      sample1 = samples_1[samplename];
+      sample2 = samples_2[samplename];
+      data[i++] = [sample1.value, sample2.value];
     }
+    margin = {
+      top: 100,
+      right: 15,
+      bottom: 60,
+      left: 60
+    };
+    width = js_data.width - margin.left - margin.right;
+    height = js_data.height - margin.top - margin.bottom;
+    minx = d3.min(data, function(d) {
+      return d[0];
+    }) * 0.95;
+    maxx = d3.max(data, function(d) {
+      return d[0];
+    }) * 1.05;
+    miny = d3.min(data, function(d) {
+      return d[1];
+    }) * 0.95;
+    maxy = d3.max(data, function(d) {
+      return d[1];
+    }) * 1.05;
+    x = d3.scale.linear().domain([minx, maxx]).range([0, width]);
+    y = d3.scale.linear().domain([miny, maxy]).range([height, 0]);
+    chart = d3.select("#scatter_plot").append("svg:svg").attr("width", width + margin.right + margin.left).attr("height", height + margin.top + margin.bottom).attr("class", "chart");
+    main = chart.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")").attr("width", width).attr("height", height).attr("class", "main");
+    xAxis = d3.svg.axis().scale(x).orient("bottom");
+    main.append("g").attr("transform", "translate(0," + height + ")").attr("class", "main axis date").call(xAxis);
+    yAxis = d3.svg.axis().scale(y).orient("left");
+    main.append("g").attr("transform", "translate(0,0)").attr("class", "main axis date").call(yAxis);
+    g = main.append("svg:g");
+    g.selectAll("scatter-dots").data(data).enter().append("svg:circle").attr("cx", function(d) {
+      return x(d[0]);
+    }).attr("cy", function(d) {
+      return y(d[1]);
+    }).attr("fill", js_data.circle_color).attr("r", js_data.circle_radius);
+    main.append("line").attr("x1", x(minx)).attr("y1", y(js_data.slope * minx + js_data.intercept)).attr("x2", x(maxx * 0.995)).attr("y2", y(js_data.slope * maxx * 0.995 + js_data.intercept)).style("stroke", js_data.line_color).style("stroke-width", js_data.line_width);
+    chart.append("text").attr("x", width / 2).attr("y", margin.top / 2 - 25).text("Sample Correlation Scatterplot");
+    text = "";
+    text += "N=" + js_data.num_overlap;
+    chart.append("text").attr("x", margin.left).attr("y", margin.top / 2 - 5).text(text);
+    text = "";
+    text += "r=" + js_data.r_value + "\t";
+    text += "p(r)=" + js_data.p_value;
+    chart.append("text").attr("x", margin.left).attr("y", margin.top / 2 + 15).text(text);
+    text = "";
+    text += "slope=" + js_data.slope + "\t";
+    text += "intercept=" + js_data.intercept;
+    chart.append("text").attr("x", margin.left).attr("y", margin.top / 2 + 35).text(text);
+    chart.append("text").attr("x", width / 2).attr("y", height + margin.top + 35).text(js_data.trait_1);
+    chart.append("text").attr("x", 20).attr("y", height / 2 + margin.top + 30).attr("transform", "rotate(-90 20," + (height / 2 + margin.top + 30) + ")").text(js_data.trait_2);
+  }
 
-    return Scatter_Plot;
-
-  })();
+  return Scatter_Plot;
 
-  root.Scatter_Plot = Scatter_Plot;
+})();
 
-}).call(this);
+root.Scatter_Plot = Scatter_Plot;
diff --git a/wqflask/wqflask/static/new/javascript/create_heatmap.coffee b/wqflask/wqflask/static/new/javascript/create_heatmap.coffee
index 51ca5e8f..d3f9fb09 100644
--- a/wqflask/wqflask/static/new/javascript/create_heatmap.coffee
+++ b/wqflask/wqflask/static/new/javascript/create_heatmap.coffee
@@ -1,11 +1,11 @@
 create_heatmap = () ->

 

-    h = 700

-    w = 1000

+    h = 500

+    w = 1200

 

     mychart = lodheatmap().height(h)

                           .width(w)

-                          .zthresh(0.5)

+                          #.zthresh(1)

 

     data = js_data.json_data

 

diff --git a/wqflask/wqflask/static/new/javascript/create_heatmap.js b/wqflask/wqflask/static/new/javascript/create_heatmap.js
index 7d6f7a9d..df8f9673 100644
--- a/wqflask/wqflask/static/new/javascript/create_heatmap.js
+++ b/wqflask/wqflask/static/new/javascript/create_heatmap.js
@@ -3,9 +3,9 @@ var create_heatmap;
 
 create_heatmap = function() {
   var data, h, mychart, w;
-  h = 700;
-  w = 1000;
-  mychart = lodheatmap().height(h).width(w).zthresh(0.5);
+  h = 500;
+  w = 1200;
+  mychart = lodheatmap().height(h).width(w);
   data = js_data.json_data;
   console.log("data:", data);
   return d3.select("div#chart").datum(data).call(mychart);
diff --git a/wqflask/wqflask/static/new/javascript/curvechart.coffee b/wqflask/wqflask/static/new/javascript/curvechart.coffee
new file mode 100644
index 00000000..7ed4359a
--- /dev/null
+++ b/wqflask/wqflask/static/new/javascript/curvechart.coffee
@@ -0,0 +1,335 @@
+# curvechart: reuseable chart with many curves

+

+curvechart = () ->

+    width = 800

+    height = 500

+    margin = {left:60, top:40, right:40, bottom: 40, inner:5}

+    axispos = {xtitle:25, ytitle:30, xlabel:5, ylabel:5}

+    titlepos = 20

+    xlim = null

+    ylim = null

+    nxticks = 5

+    xticks = null

+    nyticks = 5

+    yticks = null

+    rectcolor = "#e6e6e6"

+    strokecolor = null

+    strokecolorhilit = null

+    strokewidth = 2

+    strokewidthhilit = 2

+    title = ""

+    xlab = "X"

+    ylab = "Y"

+    rotate_ylab = null

+    yscale = d3.scale.linear()

+    xscale = d3.scale.linear()

+    curvesSelect = null

+    commonX = true

+  

+    ## the main function

+    chart = (selection) ->

+        selection.each (data) ->

+

+            # grab indID if it's there

+            # if no indID, create a vector of them

+            indID = data?.indID ? null

+            indID = indID ? [1..data.data.length]

+

+            # groups of colors

+            group = data?.group ? (1 for i of data.data)

+            ngroup = d3.max(group)

+            group = (g-1 for g in group) # changed from (1,2,3,...) to (0,1,2,...)

+      

+            # default light stroke colors

+            strokecolor = strokecolor ? selectGroupColors(ngroup, "pastel")

+            strokecolor = expand2vector(strokecolor, ngroup)

+

+            # default dark stroke colors

+            strokecolorhilit = strokecolorhilit ? selectGroupColors(ngroup, "dark")

+            strokecolorhilit = expand2vector(strokecolorhilit, ngroup)

+  

+            # reorganize data?

+            if commonX # reorganize data

+                data = ({x:data.x, y:data.data[i]} for i of data.data)

+            else

+                data = data.data

+

+            xlim = xlim ? d3.extent(pullVarAsArray(data, "x"))

+            ylim = ylim ? d3.extent(pullVarAsArray(data, "y"))

+      

+            # reorganize again

+            for i of data

+                tmp = data[i]

+                data[i] = []

+                for j of tmp.x

+                    data[i].push({x:tmp.x[j], y:tmp.y[j]}) unless !tmp.x[j]? or !tmp.y[j]?

+

+            # Select the svg element, if it exists.

+            svg = d3.select(this).selectAll("svg").data([data])

+

+            # Otherwise, create the skeletal chart.

+            gEnter = svg.enter().append("svg").append("g")

+

+            # Update the outer dimensions.

+            svg.attr("width", width+margin.left+margin.right)

+               .attr("height", height+margin.top+margin.bottom)

+

+            g = svg.select("g")

+

+            # box

+            g.append("rect")

+             .attr("x", margin.left)

+             .attr("y", margin.top)

+             .attr("height", height)

+             .attr("width", width)

+             .attr("fill", rectcolor)

+             .attr("stroke", "none")

+

+            # scales

+            xrange = [margin.left+margin.inner, margin.left+width-margin.inner]

+            yrange = [margin.top+height-margin.inner, margin.top+margin.inner]

+            xscale.domain(xlim).range(xrange)

+            yscale.domain(ylim).range(yrange)

+            xs = d3.scale.linear().domain(xlim).range(xrange)

+            ys = d3.scale.linear().domain(ylim).range(yrange)

+

+            # if yticks not provided, use nyticks to choose pretty ones

+            yticks = yticks ? ys.ticks(nyticks)

+            xticks = xticks ? xs.ticks(nxticks)

+

+            # title

+            titlegrp = g.append("g").attr("class", "title")

+             .append("text")

+             .attr("x", margin.left + width/2)

+             .attr("y", margin.top - titlepos)

+             .text(title)

+

+            # x-axis

+            xaxis = g.append("g").attr("class", "x axis")

+            xaxis.selectAll("empty")

+                 .data(xticks)

+                 .enter()

+                 .append("line")

+                 .attr("x1", (d) -> xscale(d))

+                 .attr("x2", (d) -> xscale(d))

+                 .attr("y1", margin.top)

+                 .attr("y2", margin.top+height)

+                 .attr("fill", "none")

+                 .attr("stroke", "white")

+                 .attr("stroke-width", 1)

+                 .style("pointer-events", "none")

+            xaxis.selectAll("empty")

+                 .data(xticks)

+                 .enter()

+                 .append("text")

+                 .attr("x", (d) -> xscale(d))

+                 .attr("y", margin.top+height+axispos.xlabel)

+                 .text((d) -> formatAxis(xticks)(d))

+            xaxis.append("text").attr("class", "title")

+                 .attr("x", margin.left+width/2)

+                 .attr("y", margin.top+height+axispos.xtitle)

+                 .text(xlab)

+

+            # y-axis

+            rotate_ylab = rotate_ylab ? (ylab.length > 1)

+            yaxis = g.append("g").attr("class", "y axis")

+            yaxis.selectAll("empty")

+                 .data(yticks)

+                 .enter()

+                 .append("line")

+                 .attr("y1", (d) -> yscale(d))

+                 .attr("y2", (d) -> yscale(d))

+                 .attr("x1", margin.left)

+                 .attr("x2", margin.left+width)

+                 .attr("fill", "none")

+                 .attr("stroke", "white")

+                 .attr("stroke-width", 1)

+                 .style("pointer-events", "none")

+            yaxis.selectAll("empty")

+                 .data(yticks)

+                 .enter()

+                 .append("text")

+                 .attr("y", (d) -> yscale(d))

+                 .attr("x", margin.left-axispos.ylabel)

+                 .text((d) -> formatAxis(yticks)(d))

+            yaxis.append("text").attr("class", "title")

+                 .attr("y", margin.top+height/2)

+                 .attr("x", margin.left-axispos.ytitle)

+                 .text(ylab)

+                 .attr("transform", if rotate_ylab then "rotate(270,#{margin.left-axispos.ytitle},#{margin.top+height/2})" else "")

+

+            indtip = d3.tip()

+                       .attr('class', 'd3-tip')

+                       .html((d) -> indID[d])

+                       .direction('e')

+                       .offset([0,10])

+            svg.call(indtip)

+

+            curve = d3.svg.line()

+                     .x((d) -> xscale(d.x))

+                     .y((d) -> yscale(d.y))

+

+            curves = g.append("g").attr("id", "curves")

+            curvesSelect =

+               curves.selectAll("empty")

+                     .data(d3.range(data.length))

+                     .enter()

+                     .append("path")

+                     .datum((d) -> data[d])

+                     .attr("d", curve)

+                     .attr("class", (d,i) -> "path#{i}")

+                     .attr("fill", "none")

+                     .attr("stroke", (d,i) -> strokecolor[group[i]])

+                     .attr("stroke-width", strokewidth)

+                     .on "mouseover.panel", (d,i) ->

+                                               d3.select(this).attr("stroke", strokecolorhilit[group[i]]).moveToFront()

+                                               circle = d3.select("circle#hiddenpoint#{i}")

+                                               indtip.show(i, circle.node())

+                     .on "mouseout.panel", (d,i) ->

+                                               d3.select(this).attr("stroke", strokecolor[group[i]]).moveToBack()

+                                               indtip.hide()  

+

+            # grab the last non-null point from each curve

+            lastpoint = ({x:null, y:null} for i of data)

+            for i of data

+                for v in data[i]

+                    lastpoint[i] = v if v.x? and v.y?

+

+            pointsg = g.append("g").attr("id", "invisiblepoints")

+            points = pointsg.selectAll("empty")

+                            .data(lastpoint)

+                            .enter()

+                            .append("circle")

+                            .attr("id", (d,i) -> "hiddenpoint#{i}")

+                            .attr("cx", (d) -> xscale(d.x))

+                            .attr("cy", (d) -> yscale(d.y))

+                            .attr("r", 1)

+                            .attr("opacity", 0)

+

+            # box

+            g.append("rect")

+             .attr("x", margin.left)

+             .attr("y", margin.top)

+             .attr("height", height)

+             .attr("width", width)

+             .attr("fill", "none")

+             .attr("stroke", "black")

+             .attr("stroke-width", "none")

+

+    ## configuration parameters

+    chart.width = (value) ->

+                      return width if !arguments.length

+                      width = value

+                      chart

+

+    chart.height = (value) ->

+                      return height if !arguments.length

+                      height = value

+                      chart

+

+    chart.margin = (value) ->

+                      return margin if !arguments.length

+                      margin = value

+                      chart

+

+    chart.axispos = (value) ->

+                      return axispos if !arguments.length

+                      axispos = value

+                      chart

+

+    chart.titlepos = (value) ->

+                      return titlepos if !arguments.length

+                      titlepos

+                      chart

+

+    chart.xlim = (value) ->

+                      return xlim if !arguments.length

+                      xlim = value

+                      chart

+

+    chart.nxticks = (value) ->

+                      return nxticks if !arguments.length

+                      nxticks = value

+                      chart

+

+    chart.xticks = (value) ->

+                      return xticks if !arguments.length

+                      xticks = value

+                      chart

+

+    chart.ylim = (value) ->

+                      return ylim if !arguments.length

+                      ylim = value

+                      chart

+

+    chart.nyticks = (value) ->

+                      return nyticks if !arguments.length

+                      nyticks = value

+                      chart

+

+    chart.yticks = (value) ->

+                      return yticks if !arguments.length

+                      yticks = value

+                      chart

+

+    chart.rectcolor = (value) ->

+                      return rectcolor if !arguments.length

+                      rectcolor = value

+                      chart

+

+    chart.strokecolor = (value) ->

+                      return strokecolor if !arguments.length

+                      strokecolor = value

+                      chart

+

+    chart.strokecolorhilit = (value) ->

+                      return strokecolorhilit if !arguments.length

+                      strokecolorhilit = value

+                      chart

+

+    chart.strokewidth = (value) ->

+                      return strokewidth if !arguments.length

+                      strokewidth = value

+                      chart

+

+    chart.strokewidthhilit = (value) ->

+                      return strokewidthhilit if !arguments.length

+                      strokewidthhilit = value

+                      chart

+

+    chart.commonX = (value) ->

+                      return commonX if !arguments.length

+                      commonX = value

+                      chart

+

+    chart.title = (value) ->

+                      return title if !arguments.length

+                      title = value

+                      chart

+

+    chart.xlab = (value) ->

+                      return xlab if !arguments.length

+                      xlab = value

+                      chart

+

+    chart.ylab = (value) ->

+                      return ylab if !arguments.length

+                      ylab = value

+                      chart

+

+    chart.rotate_ylab = (value) ->

+                      return rotate_ylab if !arguments.length

+                      rotate_ylab = value

+                      chart

+

+    chart.yscale = () ->

+                      return yscale

+

+    chart.xscale = () ->

+                      return xscale

+

+    chart.curvesSelect = () ->

+                      return curvesSelect

+

+    # return the chart function

+    chart
\ No newline at end of file
diff --git a/wqflask/wqflask/static/new/javascript/curvechart.js b/wqflask/wqflask/static/new/javascript/curvechart.js
new file mode 100644
index 00000000..48526c41
--- /dev/null
+++ b/wqflask/wqflask/static/new/javascript/curvechart.js
@@ -0,0 +1,353 @@
+// Generated by CoffeeScript 1.7.1
+var curvechart;
+
+curvechart = function() {
+  var axispos, chart, commonX, curvesSelect, height, margin, nxticks, nyticks, rectcolor, rotate_ylab, strokecolor, strokecolorhilit, strokewidth, strokewidthhilit, title, titlepos, width, xlab, xlim, xscale, xticks, ylab, ylim, yscale, yticks;
+  width = 800;
+  height = 500;
+  margin = {
+    left: 60,
+    top: 40,
+    right: 40,
+    bottom: 40,
+    inner: 5
+  };
+  axispos = {
+    xtitle: 25,
+    ytitle: 30,
+    xlabel: 5,
+    ylabel: 5
+  };
+  titlepos = 20;
+  xlim = null;
+  ylim = null;
+  nxticks = 5;
+  xticks = null;
+  nyticks = 5;
+  yticks = null;
+  rectcolor = "#e6e6e6";
+  strokecolor = null;
+  strokecolorhilit = null;
+  strokewidth = 2;
+  strokewidthhilit = 2;
+  title = "";
+  xlab = "X";
+  ylab = "Y";
+  rotate_ylab = null;
+  yscale = d3.scale.linear();
+  xscale = d3.scale.linear();
+  curvesSelect = null;
+  commonX = true;
+  chart = function(selection) {
+    return selection.each(function(data) {
+      var curve, curves, g, gEnter, group, i, indID, indtip, j, lastpoint, ngroup, points, pointsg, svg, titlegrp, tmp, v, xaxis, xrange, xs, yaxis, yrange, ys, _i, _j, _len, _ref, _ref1, _ref2, _ref3, _results;
+      indID = (_ref = data != null ? data.indID : void 0) != null ? _ref : null;
+      indID = indID != null ? indID : (function() {
+        _results = [];
+        for (var _i = 1, _ref1 = data.data.length; 1 <= _ref1 ? _i <= _ref1 : _i >= _ref1; 1 <= _ref1 ? _i++ : _i--){ _results.push(_i); }
+        return _results;
+      }).apply(this);
+      group = (_ref2 = data != null ? data.group : void 0) != null ? _ref2 : (function() {
+        var _results1;
+        _results1 = [];
+        for (i in data.data) {
+          _results1.push(1);
+        }
+        return _results1;
+      })();
+      ngroup = d3.max(group);
+      group = (function() {
+        var _j, _len, _results1;
+        _results1 = [];
+        for (_j = 0, _len = group.length; _j < _len; _j++) {
+          g = group[_j];
+          _results1.push(g - 1);
+        }
+        return _results1;
+      })();
+      strokecolor = strokecolor != null ? strokecolor : selectGroupColors(ngroup, "pastel");
+      strokecolor = expand2vector(strokecolor, ngroup);
+      strokecolorhilit = strokecolorhilit != null ? strokecolorhilit : selectGroupColors(ngroup, "dark");
+      strokecolorhilit = expand2vector(strokecolorhilit, ngroup);
+      if (commonX) {
+        data = (function() {
+          var _results1;
+          _results1 = [];
+          for (i in data.data) {
+            _results1.push({
+              x: data.x,
+              y: data.data[i]
+            });
+          }
+          return _results1;
+        })();
+      } else {
+        data = data.data;
+      }
+      xlim = xlim != null ? xlim : d3.extent(pullVarAsArray(data, "x"));
+      ylim = ylim != null ? ylim : d3.extent(pullVarAsArray(data, "y"));
+      for (i in data) {
+        tmp = data[i];
+        data[i] = [];
+        for (j in tmp.x) {
+          if (!((tmp.x[j] == null) || (tmp.y[j] == null))) {
+            data[i].push({
+              x: tmp.x[j],
+              y: tmp.y[j]
+            });
+          }
+        }
+      }
+      svg = d3.select(this).selectAll("svg").data([data]);
+      gEnter = svg.enter().append("svg").append("g");
+      svg.attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom);
+      g = svg.select("g");
+      g.append("rect").attr("x", margin.left).attr("y", margin.top).attr("height", height).attr("width", width).attr("fill", rectcolor).attr("stroke", "none");
+      xrange = [margin.left + margin.inner, margin.left + width - margin.inner];
+      yrange = [margin.top + height - margin.inner, margin.top + margin.inner];
+      xscale.domain(xlim).range(xrange);
+      yscale.domain(ylim).range(yrange);
+      xs = d3.scale.linear().domain(xlim).range(xrange);
+      ys = d3.scale.linear().domain(ylim).range(yrange);
+      yticks = yticks != null ? yticks : ys.ticks(nyticks);
+      xticks = xticks != null ? xticks : xs.ticks(nxticks);
+      titlegrp = g.append("g").attr("class", "title").append("text").attr("x", margin.left + width / 2).attr("y", margin.top - titlepos).text(title);
+      xaxis = g.append("g").attr("class", "x axis");
+      xaxis.selectAll("empty").data(xticks).enter().append("line").attr("x1", function(d) {
+        return xscale(d);
+      }).attr("x2", function(d) {
+        return xscale(d);
+      }).attr("y1", margin.top).attr("y2", margin.top + height).attr("fill", "none").attr("stroke", "white").attr("stroke-width", 1).style("pointer-events", "none");
+      xaxis.selectAll("empty").data(xticks).enter().append("text").attr("x", function(d) {
+        return xscale(d);
+      }).attr("y", margin.top + height + axispos.xlabel).text(function(d) {
+        return formatAxis(xticks)(d);
+      });
+      xaxis.append("text").attr("class", "title").attr("x", margin.left + width / 2).attr("y", margin.top + height + axispos.xtitle).text(xlab);
+      rotate_ylab = rotate_ylab != null ? rotate_ylab : ylab.length > 1;
+      yaxis = g.append("g").attr("class", "y axis");
+      yaxis.selectAll("empty").data(yticks).enter().append("line").attr("y1", function(d) {
+        return yscale(d);
+      }).attr("y2", function(d) {
+        return yscale(d);
+      }).attr("x1", margin.left).attr("x2", margin.left + width).attr("fill", "none").attr("stroke", "white").attr("stroke-width", 1).style("pointer-events", "none");
+      yaxis.selectAll("empty").data(yticks).enter().append("text").attr("y", function(d) {
+        return yscale(d);
+      }).attr("x", margin.left - axispos.ylabel).text(function(d) {
+        return formatAxis(yticks)(d);
+      });
+      yaxis.append("text").attr("class", "title").attr("y", margin.top + height / 2).attr("x", margin.left - axispos.ytitle).text(ylab).attr("transform", rotate_ylab ? "rotate(270," + (margin.left - axispos.ytitle) + "," + (margin.top + height / 2) + ")" : "");
+      indtip = d3.tip().attr('class', 'd3-tip').html(function(d) {
+        return indID[d];
+      }).direction('e').offset([0, 10]);
+      svg.call(indtip);
+      curve = d3.svg.line().x(function(d) {
+        return xscale(d.x);
+      }).y(function(d) {
+        return yscale(d.y);
+      });
+      curves = g.append("g").attr("id", "curves");
+      curvesSelect = curves.selectAll("empty").data(d3.range(data.length)).enter().append("path").datum(function(d) {
+        return data[d];
+      }).attr("d", curve).attr("class", function(d, i) {
+        return "path" + i;
+      }).attr("fill", "none").attr("stroke", function(d, i) {
+        return strokecolor[group[i]];
+      }).attr("stroke-width", strokewidth).on("mouseover.panel", function(d, i) {
+        var circle;
+        d3.select(this).attr("stroke", strokecolorhilit[group[i]]).moveToFront();
+        circle = d3.select("circle#hiddenpoint" + i);
+        return indtip.show(i, circle.node());
+      }).on("mouseout.panel", function(d, i) {
+        d3.select(this).attr("stroke", strokecolor[group[i]]).moveToBack();
+        return indtip.hide();
+      });
+      lastpoint = (function() {
+        var _results1;
+        _results1 = [];
+        for (i in data) {
+          _results1.push({
+            x: null,
+            y: null
+          });
+        }
+        return _results1;
+      })();
+      for (i in data) {
+        _ref3 = data[i];
+        for (_j = 0, _len = _ref3.length; _j < _len; _j++) {
+          v = _ref3[_j];
+          if ((v.x != null) && (v.y != null)) {
+            lastpoint[i] = v;
+          }
+        }
+      }
+      pointsg = g.append("g").attr("id", "invisiblepoints");
+      points = pointsg.selectAll("empty").data(lastpoint).enter().append("circle").attr("id", function(d, i) {
+        return "hiddenpoint" + i;
+      }).attr("cx", function(d) {
+        return xscale(d.x);
+      }).attr("cy", function(d) {
+        return yscale(d.y);
+      }).attr("r", 1).attr("opacity", 0);
+      return g.append("rect").attr("x", margin.left).attr("y", margin.top).attr("height", height).attr("width", width).attr("fill", "none").attr("stroke", "black").attr("stroke-width", "none");
+    });
+  };
+  chart.width = function(value) {
+    if (!arguments.length) {
+      return width;
+    }
+    width = value;
+    return chart;
+  };
+  chart.height = function(value) {
+    if (!arguments.length) {
+      return height;
+    }
+    height = value;
+    return chart;
+  };
+  chart.margin = function(value) {
+    if (!arguments.length) {
+      return margin;
+    }
+    margin = value;
+    return chart;
+  };
+  chart.axispos = function(value) {
+    if (!arguments.length) {
+      return axispos;
+    }
+    axispos = value;
+    return chart;
+  };
+  chart.titlepos = function(value) {
+    if (!arguments.length) {
+      return titlepos;
+    }
+    titlepos;
+    return chart;
+  };
+  chart.xlim = function(value) {
+    if (!arguments.length) {
+      return xlim;
+    }
+    xlim = value;
+    return chart;
+  };
+  chart.nxticks = function(value) {
+    if (!arguments.length) {
+      return nxticks;
+    }
+    nxticks = value;
+    return chart;
+  };
+  chart.xticks = function(value) {
+    if (!arguments.length) {
+      return xticks;
+    }
+    xticks = value;
+    return chart;
+  };
+  chart.ylim = function(value) {
+    if (!arguments.length) {
+      return ylim;
+    }
+    ylim = value;
+    return chart;
+  };
+  chart.nyticks = function(value) {
+    if (!arguments.length) {
+      return nyticks;
+    }
+    nyticks = value;
+    return chart;
+  };
+  chart.yticks = function(value) {
+    if (!arguments.length) {
+      return yticks;
+    }
+    yticks = value;
+    return chart;
+  };
+  chart.rectcolor = function(value) {
+    if (!arguments.length) {
+      return rectcolor;
+    }
+    rectcolor = value;
+    return chart;
+  };
+  chart.strokecolor = function(value) {
+    if (!arguments.length) {
+      return strokecolor;
+    }
+    strokecolor = value;
+    return chart;
+  };
+  chart.strokecolorhilit = function(value) {
+    if (!arguments.length) {
+      return strokecolorhilit;
+    }
+    strokecolorhilit = value;
+    return chart;
+  };
+  chart.strokewidth = function(value) {
+    if (!arguments.length) {
+      return strokewidth;
+    }
+    strokewidth = value;
+    return chart;
+  };
+  chart.strokewidthhilit = function(value) {
+    if (!arguments.length) {
+      return strokewidthhilit;
+    }
+    strokewidthhilit = value;
+    return chart;
+  };
+  chart.commonX = function(value) {
+    if (!arguments.length) {
+      return commonX;
+    }
+    commonX = value;
+    return chart;
+  };
+  chart.title = function(value) {
+    if (!arguments.length) {
+      return title;
+    }
+    title = value;
+    return chart;
+  };
+  chart.xlab = function(value) {
+    if (!arguments.length) {
+      return xlab;
+    }
+    xlab = value;
+    return chart;
+  };
+  chart.ylab = function(value) {
+    if (!arguments.length) {
+      return ylab;
+    }
+    ylab = value;
+    return chart;
+  };
+  chart.rotate_ylab = function(value) {
+    if (!arguments.length) {
+      return rotate_ylab;
+    }
+    rotate_ylab = value;
+    return chart;
+  };
+  chart.yscale = function() {
+    return yscale;
+  };
+  chart.xscale = function() {
+    return xscale;
+  };
+  chart.curvesSelect = function() {
+    return curvesSelect;
+  };
+  return chart;
+};
diff --git a/wqflask/wqflask/static/new/javascript/iplotMScanone_noeff.coffee b/wqflask/wqflask/static/new/javascript/iplotMScanone_noeff.coffee
new file mode 100644
index 00000000..6aa301a0
--- /dev/null
+++ b/wqflask/wqflask/static/new/javascript/iplotMScanone_noeff.coffee
@@ -0,0 +1,192 @@
+# iplotMScanone_noeff: image of lod curves linked to plot of lod curves

+# Karl W Broman

+

+iplotMScanone_noeff = (lod_data, times, chartOpts) ->

+

+    # chartOpts start

+    wleft = chartOpts?.wleft ? 1000 # width of left panels in pixels

+    wright = chartOpts?.wright ? 500 # width of right panel in pixels

+    htop = chartOpts?.htop ? 350 # height of top panels in pixels

+    hbot = chartOpts?.hbot ? 350 # height of bottom panel in pixels

+    margin = chartOpts?.margin ? {left:100, top:40, right:40, bottom: 40, inner:5} # margins in pixels (left, top, right, bottom, inner)

+    axispos = chartOpts?.axispos ? {xtitle:25, ytitle:30, xlabel:5, ylabel:5} # position of axis labels in pixels (xtitle, ytitle, xlabel, ylabel)

+    titlepos = chartOpts?.titlepos ? 20 # position of chart title in pixels

+    chrGap = chartOpts?.chrGap ? 8 # gap between chromosomes in pixels

+    darkrect = chartOpts?.darkrect ? "#C8C8C8" # color of darker background rectangle

+    lightrect = chartOpts?.lightrect ? "#E6E6E6" # color of lighter background rectangle

+    nullcolor = chartOpts?.nullcolor ? "#E6E6E6" # color for pixels with null values

+    colors = chartOpts?.colors ? ["slateblue", "white", "crimson"] # heat map colors

+    zlim = chartOpts?.zlim ? null # z-axis limits

+    zthresh = chartOpts?.zthresh ? null # lower z-axis threshold for display in heat map

+    lod_ylab = chartOpts?.lod_ylab ? "" # y-axis label for LOD heatmap (also used as x-axis label on effect plot)

+    linecolor = chartOpts?.linecolor ? "darkslateblue" # color of lines

+    linewidth = chartOpts?.linewidth ? 2 # width of lines

+    nxticks = chartOpts?.nxticks ? 5 # no. ticks in x-axis on right-hand panel, if quantitative scale

+    xticks = chartOpts?.xticks ? null # tick positions in x-axis on right-hand panel, if quantitative scale

+    lod_labels = chartOpts?.lod_labels ? null # optional vector of strings, for LOD column labels

+    # chartOpts end

+    chartdivid = chartOpts?.chartdivid ? 'chart'

+  

+    totalh = htop + hbot + 2*(margin.top + margin.bottom)

+    totalw = wleft + wright + 2*(margin.left + margin.right)

+  

+    # if quant scale, use times as labels; otherwise use lod_data.lodnames

+    unless lod_labels?

+        lod_labels = if times? then (formatAxis(times, extra_digits=1)(x) for x in times) else lod_data.lodnames

+

+    mylodheatmap = lodheatmap().height(htop)

+                               .width(wleft)

+                               .margin(margin)

+                               .axispos(axispos)

+                               #.titlepos(titlepos)

+                               #.chrGap(chrGap)

+                               #.rectcolor(lightrect)

+                               #.colors(colors)

+                               #.zlim(zlim)

+                               #.zthresh(zthresh)

+                               #.quantScale(times)

+                               #.lod_labels(lod_labels)

+                               #.ylab(lod_ylab)

+                               #.nullcolor(nullcolor)

+  

+    svg = d3.select("div##{chartdivid}")

+            .append("svg")

+            .attr("height", totalh)

+            .attr("width", totalw)

+  

+    g_heatmap = svg.append("g")

+                   .attr("id", "heatmap")

+                   .datum(lod_data)

+                   .call(mylodheatmap)

+  

+    mylodchart = lodchart().height(hbot)

+                           .width(wleft)

+                           .margin(margin)

+                           .axispos(axispos)

+                           .titlepos(titlepos)

+                           .chrGap(chrGap)

+                           .linecolor("none")

+                           .pad4heatmap(true)

+                           .darkrect(darkrect)

+                           .lightrect(lightrect)

+                           .ylim([0, d3.max(mylodheatmap.zlim())])

+                           .pointsAtMarkers(false)

+  

+    g_lodchart = svg.append("g")

+                    .attr("transform", "translate(0,#{htop+margin.top+margin.bottom})")

+                    .attr("id", "lodchart")

+                    .datum(lod_data)

+                    .call(mylodchart)

+  

+    # function for lod curve path

+    lodcurve = (chr, lodcolumn) ->

+            d3.svg.line()

+                  .x((d) -> mylodchart.xscale()[chr](d))

+                  .y((d,i) -> mylodchart.yscale()(Math.abs(lod_data.lodByChr[chr][i][lodcolumn])))

+  

+    # plot lod curves for selected lod column

+    lodchart_curves = null

+    plotLodCurve = (lodcolumn) ->

+        lodchart_curves = g_lodchart.append("g").attr("id", "lodcurves")

+        for chr in lod_data.chrnames

+            lodchart_curves.append("path")

+                           .datum(lod_data.posByChr[chr])

+                           .attr("d", lodcurve(chr, lodcolumn))

+                           .attr("stroke", linecolor)

+                           .attr("fill", "none")

+                           .attr("stroke-width", linewidth)

+                           .style("pointer-events", "none")

+  

+    # rearrange data for curves of time x LOD

+    lod4curves = {data:[]}

+    for pos of lod_data.pos

+        y = (Math.abs(lod_data[lodcolumn][pos]) for lodcolumn in lod_data.lodnames)

+        x = (+i for i of lod_data.lodnames)

+        lod4curves.data.push({x:x, y:y})

+  

+    #mycurvechart = curvechart().height(htop)

+    #                           .width(wright)

+    #                           .margin(margin)

+    #                           .axispos(axispos)

+    #                           .titlepos(titlepos)

+    #                           .xlab(lod_ylab)

+    #                           .ylab("LOD score")

+    #                           .strokecolor("none")

+    #                           .rectcolor(lightrect)

+    #                           .xlim([-0.5, lod_data.lodnames.length-0.5])

+    #                           .ylim([0, d3.max(mylodheatmap.zlim())])

+    #                           .nxticks(0)

+    #                           .commonX(false)

+    #

+    #g_curvechart = svg.append("g")

+    #                  .attr("transform", "translate(#{wleft+margin.top+margin.bottom},0)")

+    #                  .attr("id", "curvechart")

+    #                  .datum(lod4curves)

+    #                  .call(mycurvechart)

+    #

+    ## add X axis

+    #if times? # use quantitative axis

+    #    xscale = d3.scale.linear().range(mycurvechart.xscale().range())

+    #    xscale.domain([times[0], times[times.length-1]])

+    #    xticks = xticks ? xscale.ticks(nxticks)

+    #    curvechart_xaxis = g_curvechart.select("g.x.axis")

+    #    curvechart_xaxis.selectAll("empty")

+    #                    .data(xticks)

+    #                    .enter()

+    #                    .append("line")

+    #                    .attr("x1", (d) -> xscale(d))

+    #                    .attr("x2", (d) -> xscale(d))

+    #                    .attr("y1", margin.top)

+    #                    .attr("y2", margin.top+htop)

+    #                    .attr("fill", "none")

+    #                    .attr("stroke", "white")

+    #                    .attr("stroke-width", 1)

+    #                    .style("pointer-events", "none")

+    #    curvechart_xaxis.selectAll("empty")

+    #                    .data(xticks)

+    #                    .enter()

+    #                    .append("text")

+    #                    .attr("x", (d) -> xscale(d))

+    #                    .attr("y", margin.top+htop+axispos.xlabel)

+    #                    .text((d) -> formatAxis(xticks)(d))

+    #else # qualitative axis

+    #    curvechart_xaxis = g_curvechart.select("g.x.axis")

+    #                                   .selectAll("empty")

+    #                                   .data(lod_labels)

+    #                                   .enter()

+    #                                   .append("text")

+    #                                   .attr("id", (d,i) -> "xaxis#{i}")

+    #                                   .attr("x", (d,i) -> mycurvechart.xscale()(i))

+    #                                   .attr("y", margin.top+htop+axispos.xlabel)

+    #                                   .text((d) -> d)

+    #                                   .attr("opacity", 0)

+

+    # hash for [chr][pos] -> posindex

+    #posindex = {}

+    #curindex = 0

+    #for chr in lod_data.chrnames

+    #    posindex[chr] = {}

+    #    for pos in lod_data.posByChr[chr]

+    #        posindex[chr][pos] = curindex

+    #        curindex += 1

+  

+    #mycurvechart.curvesSelect()

+    #            .on("mouseover.panel", null)

+    #            .on("mouseout.panel", null)

+    #

+    mylodheatmap.cellSelect()

+                .on "mouseover", (d) ->

+                         plotLodCurve(d.lodindex)

+                         g_lodchart.select("g.title text").text("#{lod_labels[d.lodindex]}")

+                         #g_curvechart.selectAll("path.path#{posindex[d.chr][d.pos]}").attr("stroke", linecolor)

+                         p = d3.format(".1f")(d.pos)

+                         #g_curvechart.select("g.title text").text("#{d.chr}@#{p}")

+                         #g_curvechart.select("text#xaxis#{d.lodindex}").attr("opacity", 1) unless times?

+                .on "mouseout", (d) ->

+                         lodchart_curves.remove()

+                         g_lodchart.select("g.title text").text("")

+                         #g_curvechart.selectAll("path.path#{posindex[d.chr][d.pos]}").attr("stroke", null)

+                         #g_curvechart.select("g.title text").text("")

+                         #g_curvechart.select("text#xaxis#{d.lodindex}").attr("opacity", 0) unless times?

+                         

+iplotMScanone_noeff(lod_data = js_data.json_data)
\ No newline at end of file
diff --git a/wqflask/wqflask/static/new/javascript/iplotMScanone_noeff.js b/wqflask/wqflask/static/new/javascript/iplotMScanone_noeff.js
new file mode 100644
index 00000000..e539d353
--- /dev/null
+++ b/wqflask/wqflask/static/new/javascript/iplotMScanone_noeff.js
@@ -0,0 +1,113 @@
+// Generated by CoffeeScript 1.7.1
+var iplotMScanone_noeff, lod_data;
+
+iplotMScanone_noeff = function(lod_data, times, chartOpts) {
+  var axispos, chartdivid, chrGap, colors, darkrect, extra_digits, g_heatmap, g_lodchart, hbot, htop, i, lightrect, linecolor, linewidth, lod4curves, lod_labels, lod_ylab, lodchart_curves, lodcolumn, lodcurve, margin, mylodchart, mylodheatmap, nullcolor, nxticks, plotLodCurve, pos, svg, titlepos, totalh, totalw, wleft, wright, x, xticks, y, zlim, zthresh, _ref, _ref1, _ref10, _ref11, _ref12, _ref13, _ref14, _ref15, _ref16, _ref17, _ref18, _ref19, _ref2, _ref20, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9;
+  wleft = (_ref = chartOpts != null ? chartOpts.wleft : void 0) != null ? _ref : 1000;
+  wright = (_ref1 = chartOpts != null ? chartOpts.wright : void 0) != null ? _ref1 : 500;
+  htop = (_ref2 = chartOpts != null ? chartOpts.htop : void 0) != null ? _ref2 : 350;
+  hbot = (_ref3 = chartOpts != null ? chartOpts.hbot : void 0) != null ? _ref3 : 350;
+  margin = (_ref4 = chartOpts != null ? chartOpts.margin : void 0) != null ? _ref4 : {
+    left: 100,
+    top: 40,
+    right: 40,
+    bottom: 40,
+    inner: 5
+  };
+  axispos = (_ref5 = chartOpts != null ? chartOpts.axispos : void 0) != null ? _ref5 : {
+    xtitle: 25,
+    ytitle: 30,
+    xlabel: 5,
+    ylabel: 5
+  };
+  titlepos = (_ref6 = chartOpts != null ? chartOpts.titlepos : void 0) != null ? _ref6 : 20;
+  chrGap = (_ref7 = chartOpts != null ? chartOpts.chrGap : void 0) != null ? _ref7 : 8;
+  darkrect = (_ref8 = chartOpts != null ? chartOpts.darkrect : void 0) != null ? _ref8 : "#C8C8C8";
+  lightrect = (_ref9 = chartOpts != null ? chartOpts.lightrect : void 0) != null ? _ref9 : "#E6E6E6";
+  nullcolor = (_ref10 = chartOpts != null ? chartOpts.nullcolor : void 0) != null ? _ref10 : "#E6E6E6";
+  colors = (_ref11 = chartOpts != null ? chartOpts.colors : void 0) != null ? _ref11 : ["slateblue", "white", "crimson"];
+  zlim = (_ref12 = chartOpts != null ? chartOpts.zlim : void 0) != null ? _ref12 : null;
+  zthresh = (_ref13 = chartOpts != null ? chartOpts.zthresh : void 0) != null ? _ref13 : null;
+  lod_ylab = (_ref14 = chartOpts != null ? chartOpts.lod_ylab : void 0) != null ? _ref14 : "";
+  linecolor = (_ref15 = chartOpts != null ? chartOpts.linecolor : void 0) != null ? _ref15 : "darkslateblue";
+  linewidth = (_ref16 = chartOpts != null ? chartOpts.linewidth : void 0) != null ? _ref16 : 2;
+  nxticks = (_ref17 = chartOpts != null ? chartOpts.nxticks : void 0) != null ? _ref17 : 5;
+  xticks = (_ref18 = chartOpts != null ? chartOpts.xticks : void 0) != null ? _ref18 : null;
+  lod_labels = (_ref19 = chartOpts != null ? chartOpts.lod_labels : void 0) != null ? _ref19 : null;
+  chartdivid = (_ref20 = chartOpts != null ? chartOpts.chartdivid : void 0) != null ? _ref20 : 'chart';
+  totalh = htop + hbot + 2 * (margin.top + margin.bottom);
+  totalw = wleft + wright + 2 * (margin.left + margin.right);
+  if (lod_labels == null) {
+    lod_labels = times != null ? (function() {
+      var _i, _len, _results;
+      _results = [];
+      for (_i = 0, _len = times.length; _i < _len; _i++) {
+        x = times[_i];
+        _results.push(formatAxis(times, extra_digits = 1)(x));
+      }
+      return _results;
+    })() : lod_data.lodnames;
+  }
+  mylodheatmap = lodheatmap().height(htop).width(wleft).margin(margin).axispos(axispos);
+  svg = d3.select("div#" + chartdivid).append("svg").attr("height", totalh).attr("width", totalw);
+  g_heatmap = svg.append("g").attr("id", "heatmap").datum(lod_data).call(mylodheatmap);
+  mylodchart = lodchart().height(hbot).width(wleft).margin(margin).axispos(axispos).titlepos(titlepos).chrGap(chrGap).linecolor("none").pad4heatmap(true).darkrect(darkrect).lightrect(lightrect).ylim([0, d3.max(mylodheatmap.zlim())]).pointsAtMarkers(false);
+  g_lodchart = svg.append("g").attr("transform", "translate(0," + (htop + margin.top + margin.bottom) + ")").attr("id", "lodchart").datum(lod_data).call(mylodchart);
+  lodcurve = function(chr, lodcolumn) {
+    return d3.svg.line().x(function(d) {
+      return mylodchart.xscale()[chr](d);
+    }).y(function(d, i) {
+      return mylodchart.yscale()(Math.abs(lod_data.lodByChr[chr][i][lodcolumn]));
+    });
+  };
+  lodchart_curves = null;
+  plotLodCurve = function(lodcolumn) {
+    var chr, _i, _len, _ref21, _results;
+    lodchart_curves = g_lodchart.append("g").attr("id", "lodcurves");
+    _ref21 = lod_data.chrnames;
+    _results = [];
+    for (_i = 0, _len = _ref21.length; _i < _len; _i++) {
+      chr = _ref21[_i];
+      _results.push(lodchart_curves.append("path").datum(lod_data.posByChr[chr]).attr("d", lodcurve(chr, lodcolumn)).attr("stroke", linecolor).attr("fill", "none").attr("stroke-width", linewidth).style("pointer-events", "none"));
+    }
+    return _results;
+  };
+  lod4curves = {
+    data: []
+  };
+  for (pos in lod_data.pos) {
+    y = (function() {
+      var _i, _len, _ref21, _results;
+      _ref21 = lod_data.lodnames;
+      _results = [];
+      for (_i = 0, _len = _ref21.length; _i < _len; _i++) {
+        lodcolumn = _ref21[_i];
+        _results.push(Math.abs(lod_data[lodcolumn][pos]));
+      }
+      return _results;
+    })();
+    x = (function() {
+      var _results;
+      _results = [];
+      for (i in lod_data.lodnames) {
+        _results.push(+i);
+      }
+      return _results;
+    })();
+    lod4curves.data.push({
+      x: x,
+      y: y
+    });
+  }
+  return mylodheatmap.cellSelect().on("mouseover", function(d) {
+    var p;
+    plotLodCurve(d.lodindex);
+    g_lodchart.select("g.title text").text("" + lod_labels[d.lodindex]);
+    return p = d3.format(".1f")(d.pos);
+  }).on("mouseout", function(d) {
+    lodchart_curves.remove();
+    return g_lodchart.select("g.title text").text("");
+  });
+};
+
+iplotMScanone_noeff(lod_data = js_data.json_data);
diff --git a/wqflask/wqflask/static/new/javascript/lod_chart.coffee b/wqflask/wqflask/static/new/javascript/lod_chart.coffee
index 8794625a..c9b277cc 100644
--- a/wqflask/wqflask/static/new/javascript/lod_chart.coffee
+++ b/wqflask/wqflask/static/new/javascript/lod_chart.coffee
@@ -43,9 +43,11 @@ lodchart = () ->
         

         lodvarname = lodvarname ? data.lodnames[0]

         data[lodvarname] = (Math.abs(x) for x in data[lodvarname]) # take absolute values

-        data['additive'] = (Math.abs(x) for x in data['additive'])

+        if 'additive' of data

+            data['additive'] = (Math.abs(x) for x in data['additive'])

         ylim = ylim ? [0, d3.max(data[lodvarname])]

-        if data['additive'].length > 0

+        if 'additive' of data

+        #if data['additive'].length > 0

             additive_ylim = additive_ylim ? [0, d3.max(data['additive'])]

         lodvarnum = data.lodnames.indexOf(lodvarname)

   

@@ -74,13 +76,15 @@ lodchart = () ->
         yscale.domain(ylim)

               .range([height+margin.top, margin.top+margin.inner])

         

-        if data['additive'].length > 0

+        #if data['additive'].length > 0

+        if 'additive' of data

             additive_yscale.domain(additive_ylim)

                   .range([height+margin.top, margin.top+margin.inner + height/2])

   

         # if yticks not provided, use nyticks to choose pretty ones

         yticks = yticks ? yscale.ticks(nyticks)

-        if data['additive'].length > 0

+        #if data['additive'].length > 0

+        if 'additive' of data

             additive_yticks = additive_yticks ? additive_yscale.ticks(nyticks)

   

         # reorganize lod,pos by chromosomes

@@ -179,7 +183,8 @@ lodchart = () ->
              .attr("text-anchor", "middle")

              .attr("fill", "slateblue")

   

-        if data['additive'].length > 0

+        #if data['additive'].length > 0

+        if 'additive' of data

             rotate_additive_ylab = rotate_additive_ylab ? (additive_ylab.length > 1)

             additive_yaxis = g.append("g").attr("class", "y axis")

             additive_yaxis.selectAll("empty")

@@ -214,33 +219,34 @@ lodchart = () ->
                  .attr("text-anchor", "middle")

                  .attr("fill", "green")

   

-        suggestive_bar = g.append("g").attr("class", "suggestive")

-        suggestive_bar.selectAll("empty")

-             .data([data.suggestive])

-             .enter()

-             .append("line")

-             .attr("y1", (d) -> yscale(d))

-             .attr("y2", (d) -> yscale(d))

-             .attr("x1", margin.left)

-             .attr("x2", margin.left+width)

-             .attr("fill", "none")

-             .attr("stroke", suggestivecolor)

-             .attr("stroke-width", 5)

-             .style("pointer-events", "none")

-

-        suggestive_bar = g.append("g").attr("class", "significant")

-        suggestive_bar.selectAll("empty")

-             .data([data.significant])

-             .enter()

-             .append("line")

-             .attr("y1", (d) -> yscale(d))

-             .attr("y2", (d) -> yscale(d))

-             .attr("x1", margin.left)

-             .attr("x2", margin.left+width)

-             .attr("fill", "none")

-             .attr("stroke", significantcolor)

-             .attr("stroke-width", 5)

-             .style("pointer-events", "none")

+        if 'suggestive' of data

+            suggestive_bar = g.append("g").attr("class", "suggestive")

+            suggestive_bar.selectAll("empty")

+                 .data([data.suggestive])

+                 .enter()

+                 .append("line")

+                 .attr("y1", (d) -> yscale(d))

+                 .attr("y2", (d) -> yscale(d))

+                 .attr("x1", margin.left)

+                 .attr("x2", margin.left+width)

+                 .attr("fill", "none")

+                 .attr("stroke", suggestivecolor)

+                 .attr("stroke-width", 5)

+                 .style("pointer-events", "none")

+    

+            suggestive_bar = g.append("g").attr("class", "significant")

+            suggestive_bar.selectAll("empty")

+                 .data([data.significant])

+                 .enter()

+                 .append("line")

+                 .attr("y1", (d) -> yscale(d))

+                 .attr("y2", (d) -> yscale(d))

+                 .attr("x1", margin.left)

+                 .attr("x2", margin.left+width)

+                 .attr("fill", "none")

+                 .attr("stroke", significantcolor)

+                 .attr("stroke-width", 5)

+                 .style("pointer-events", "none")

   

         # lod curves by chr

         lodcurve = (chr, lodcolumn) ->

@@ -248,7 +254,8 @@ lodchart = () ->
               .x((d) -> xscale[chr](d))

               .y((d,i) -> yscale(data.lodByChr[chr][i][lodcolumn]))

               

-        if data['additive'].length > 0

+        #if data['additive'].length > 0

+        if 'additive' of data

             additivecurve = (chr, lodcolumn) ->

                 d3.svg.line()

                   .x((d) -> xscale[chr](d))

@@ -256,16 +263,17 @@ lodchart = () ->
   

         curves = g.append("g").attr("id", "curves")

   

-        for chr in data.chrnames

-          curves.append("path")

-                .datum(data.posByChr[chr[0]])

-                .attr("d", lodcurve(chr[0], lodvarnum))

-                .attr("stroke", lodlinecolor)

-                .attr("fill", "none")

-                .attr("stroke-width", linewidth)

-                .style("pointer-events", "none")

+        #for chr in data.chrnames

+        #  curves.append("path")

+        #        .datum(data.posByChr[chr[0]])

+        #        .attr("d", lodcurve(chr[0], lodvarnum))

+        #        .attr("stroke", lodlinecolor)

+        #        .attr("fill", "none")

+        #        .attr("stroke-width", linewidth)

+        #        .style("pointer-events", "none")

         

-        if data['additive'].length > 0

+        #if data['additive'].length > 0

+        if 'additive' of data

             for chr in data.chrnames

                 curves.append("path")

                       .datum(data.posByChr[chr[0]])

@@ -493,95 +501,96 @@ lodchart = () ->
 # reorganize lod/pos by chromosome

 # lodvarname==null    -> case for multiple LOD columns (lodheatmap)

 # lodvarname provided -> case for one LOD column (lodchart)

-reorgLodData = (data, lodvarname=null) ->

-    data.posByChr = {}

-    data.lodByChr = {}

-    data.additiveByChr = {}

-    

-    for chr,i in data.chrnames

-      data.posByChr[chr[0]] = []

-      data.lodByChr[chr[0]] = []

-      data.additiveByChr[chr[0]] = []

-      for pos, j in data.pos

-        if data.chr[j] == chr[0]

-          data.posByChr[chr[0]].push(pos)

-          data.lodnames = [data.lodnames] unless Array.isArray(data.lodnames)

-          if data['additive'].length > 0

-            additiveval = (data['additive'][j] for lodcolumn in data.lodnames)

-          lodval = (data[lodcolumn][j] for lodcolumn in data.lodnames)

-          data.additiveByChr[chr[0]].push(additiveval)

-          data.lodByChr[chr[0]].push(lodval)

-

-    

-    if lodvarname?

-      data.markers = []

-      for marker,i in data.markernames

-        if marker != ""

-          data.markers.push({name:marker, chr:data.chr[i], pos:data.pos[i], lod:data[lodvarname][i]})

-    

-    data

+#reorgLodData = (data, lodvarname=null) ->

+#    data.posByChr = {}

+#    data.lodByChr = {}

+#    data.additiveByChr = {}

+#    

+#    for chr,i in data.chrnames

+#      data.posByChr[chr[0]] = []

+#      data.lodByChr[chr[0]] = []

+#      data.additiveByChr[chr[0]] = []

+#      for pos, j in data.pos

+#        if data.chr[j] == chr[0]

+#          data.posByChr[chr[0]].push(pos)

+#          data.lodnames = [data.lodnames] unless Array.isArray(data.lodnames)

+#          if 'additive' of data  

+#          #if data['additive'].length > 0

+#            additiveval = (data['additive'][j] for lodcolumn in data.lodnames)

+#          lodval = (data[lodcolumn][j] for lodcolumn in data.lodnames)

+#          data.additiveByChr[chr[0]].push(additiveval)

+#          data.lodByChr[chr[0]].push(lodval)

+#

+#    

+#    if lodvarname?

+#      data.markers = []

+#      for marker,i in data.markernames

+#        if marker != ""

+#          data.markers.push({name:marker, chr:data.chr[i], pos:data.pos[i], lod:data[lodvarname][i]})

+#    

+#    data

 

 

 # calculate chromosome start/end + scales, for heat map

-chrscales = (data, width, chrGap, leftMargin, pad4heatmap) ->

-    # start and end of chromosome positions

-    chrStart = []

-    chrEnd = []

-    chrLength = []

-    totalChrLength = 0

-    maxd = 0

-    for chr in data.chrnames

-      d = maxdiff(data.posByChr[chr[0]])

-      maxd = d if d > maxd

-  

-      rng = d3.extent(data.posByChr[chr[0]])

-      chrStart.push(rng[0])

-      chrEnd.push(rng[1])

-      L = rng[1] - rng[0]

-      chrLength.push(L)

-      totalChrLength += L

-  

-    # adjust lengths for heatmap

-    if pad4heatmap

-      data.recwidth = maxd

-      chrStart = chrStart.map (x) -> x-maxd/2

-      chrEnd = chrEnd.map (x) -> x+maxd/2

-      chrLength = chrLength.map (x) -> x+maxd

-      totalChrLength += (chrLength.length*maxd)

-  

-    # break up x axis into chromosomes by length, with gaps

-    data.chrStart = []

-    data.chrEnd = []

-    cur = leftMargin

-    cur += chrGap/2 unless pad4heatmap

-    data.xscale = {}

-    for chr,i in data.chrnames

-      data.chrStart.push(cur)

-      w = Math.round((width-chrGap*(data.chrnames.length-pad4heatmap))/totalChrLength*chrLength[i])

-      data.chrEnd.push(cur + w)

-      cur = data.chrEnd[i] + chrGap

-      # x-axis scales, by chromosome

-      data.xscale[chr[0]] = d3.scale.linear()

-                           .domain([chrStart[i], chrEnd[i]])

-                           .range([data.chrStart[i], data.chrEnd[i]])

-  

-    # return data with new stuff added

-    data

+#chrscales = (data, width, chrGap, leftMargin, pad4heatmap) ->

+#    # start and end of chromosome positions

+#    chrStart = []

+#    chrEnd = []

+#    chrLength = []

+#    totalChrLength = 0

+#    maxd = 0

+#    for chr in data.chrnames

+#      d = maxdiff(data.posByChr[chr[0]])

+#      maxd = d if d > maxd

+#  

+#      rng = d3.extent(data.posByChr[chr[0]])

+#      chrStart.push(rng[0])

+#      chrEnd.push(rng[1])

+#      L = rng[1] - rng[0]

+#      chrLength.push(L)

+#      totalChrLength += L

+#  

+#    # adjust lengths for heatmap

+#    if pad4heatmap

+#      data.recwidth = maxd

+#      chrStart = chrStart.map (x) -> x-maxd/2

+#      chrEnd = chrEnd.map (x) -> x+maxd/2

+#      chrLength = chrLength.map (x) -> x+maxd

+#      totalChrLength += (chrLength.length*maxd)

+#  

+#    # break up x axis into chromosomes by length, with gaps

+#    data.chrStart = []

+#    data.chrEnd = []

+#    cur = leftMargin

+#    cur += chrGap/2 unless pad4heatmap

+#    data.xscale = {}

+#    for chr,i in data.chrnames

+#      data.chrStart.push(cur)

+#      w = Math.round((width-chrGap*(data.chrnames.length-pad4heatmap))/totalChrLength*chrLength[i])

+#      data.chrEnd.push(cur + w)

+#      cur = data.chrEnd[i] + chrGap

+#      # x-axis scales, by chromosome

+#      data.xscale[chr[0]] = d3.scale.linear()

+#                           .domain([chrStart[i], chrEnd[i]])

+#                           .range([data.chrStart[i], data.chrEnd[i]])

+#  

+#    # return data with new stuff added

+#    data

     

 # maximum difference between adjacent values in a vector

-maxdiff = (x) ->

-    return null if x.length < 2

-    result = x[1] - x[0]

-    return result if x.length < 3

-    for i in [2...x.length]

-      d = x[i] - x[i-1]

-      result = d if d > result

-    result

-    

-# determine rounding of axis labels

-formatAxis = (d) ->

-    d = d[1] - d[0]

-    ndig = Math.floor( Math.log(d % 10) / Math.log(10) )

-    ndig = 0 if ndig > 0

-    ndig = Math.abs(ndig)

-    d3.format(".#{ndig}f")

+#maxdiff = (x) ->

+#    return null if x.length < 2

+#    result = x[1] - x[0]

+#    return result if x.length < 3

+#    for i in [2...x.length]

+#      d = x[i] - x[i-1]

+#      result = d if d > result

+#    result

+#    

+## determine rounding of axis labels

+#formatAxis = (d) ->

+#    d = d[1] - d[0]

+#    ndig = Math.floor( Math.log(d % 10) / Math.log(10) )

+#    ndig = 0 if ndig > 0

+#    ndig = Math.abs(ndig)

+#    d3.format(".#{ndig}f")

diff --git a/wqflask/wqflask/static/new/javascript/lod_chart.js b/wqflask/wqflask/static/new/javascript/lod_chart.js
index 75adc792..0f91fc71 100644
--- a/wqflask/wqflask/static/new/javascript/lod_chart.js
+++ b/wqflask/wqflask/static/new/javascript/lod_chart.js
@@ -1,5 +1,5 @@
 // Generated by CoffeeScript 1.7.1
-var chrscales, formatAxis, lodchart, maxdiff, reorgLodData;
+var lodchart;
 
 lodchart = function() {
   var additive_ylab, additive_ylim, additive_yscale, additive_yticks, additivelinecolor, axispos, chart, chrGap, chrSelect, darkrect, height, lightrect, linewidth, lodcurve, lodlinecolor, lodvarname, margin, markerSelect, nyticks, pad4heatmap, pointcolor, pointsAtMarkers, pointsize, pointstroke, rotate_ylab, significantcolor, suggestivecolor, title, titlepos, width, xlab, xscale, ylab, ylim, yscale, yticks;
@@ -51,7 +51,7 @@ lodchart = function() {
   pointsAtMarkers = true;
   chart = function(selection) {
     return selection.each(function(data) {
-      var additive_yaxis, additivecurve, chr, curves, g, gEnter, hiddenpoints, lodvarnum, markerpoints, markertip, redraw_plot, rotate_additive_ylab, suggestive_bar, svg, titlegrp, x, xaxis, yaxis, _i, _j, _len, _len1, _ref, _ref1;
+      var additive_yaxis, additivecurve, chr, curves, g, gEnter, hiddenpoints, lodvarnum, markerpoints, markertip, redraw_plot, rotate_additive_ylab, suggestive_bar, svg, titlegrp, x, xaxis, yaxis, _i, _len, _ref;
       console.log("data:", data);
       lodvarname = lodvarname != null ? lodvarname : data.lodnames[0];
       data[lodvarname] = (function() {
@@ -64,18 +64,20 @@ lodchart = function() {
         }
         return _results;
       })();
-      data['additive'] = (function() {
-        var _i, _len, _ref, _results;
-        _ref = data['additive'];
-        _results = [];
-        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-          x = _ref[_i];
-          _results.push(Math.abs(x));
-        }
-        return _results;
-      })();
+      if ('additive' in data) {
+        data['additive'] = (function() {
+          var _i, _len, _ref, _results;
+          _ref = data['additive'];
+          _results = [];
+          for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+            x = _ref[_i];
+            _results.push(Math.abs(x));
+          }
+          return _results;
+        })();
+      }
       ylim = ylim != null ? ylim : [0, d3.max(data[lodvarname])];
-      if (data['additive'].length > 0) {
+      if ('additive' in data) {
         additive_ylim = additive_ylim != null ? additive_ylim : [0, d3.max(data['additive'])];
       }
       lodvarnum = data.lodnames.indexOf(lodvarname);
@@ -85,11 +87,11 @@ lodchart = function() {
       g = svg.select("g");
       g.append("rect").attr("x", margin.left).attr("y", margin.top).attr("height", height).attr("width", width).attr("fill", darkrect).attr("stroke", "none");
       yscale.domain(ylim).range([height + margin.top, margin.top + margin.inner]);
-      if (data['additive'].length > 0) {
+      if ('additive' in data) {
         additive_yscale.domain(additive_ylim).range([height + margin.top, margin.top + margin.inner + height / 2]);
       }
       yticks = yticks != null ? yticks : yscale.ticks(nyticks);
-      if (data['additive'].length > 0) {
+      if ('additive' in data) {
         additive_yticks = additive_yticks != null ? additive_yticks : additive_yscale.ticks(nyticks);
       }
       data = reorgLodData(data, lodvarname);
@@ -145,7 +147,7 @@ lodchart = function() {
         return formatAxis(yticks)(d);
       });
       yaxis.append("text").attr("class", "title").attr("y", margin.top + height / 2).attr("x", margin.left - axispos.ytitle).text(ylab).attr("transform", rotate_ylab ? "rotate(270," + (margin.left - axispos.ytitle) + "," + (margin.top + height / 2) + ")" : "").attr("text-anchor", "middle").attr("fill", "slateblue");
-      if (data['additive'].length > 0) {
+      if ('additive' in data) {
         rotate_additive_ylab = rotate_additive_ylab != null ? rotate_additive_ylab : additive_ylab.length > 1;
         additive_yaxis = g.append("g").attr("class", "y axis");
         additive_yaxis.selectAll("empty").data(additive_yticks).enter().append("line").attr("y1", function(d) {
@@ -162,18 +164,20 @@ lodchart = function() {
         });
         additive_yaxis.append("text").attr("class", "title").attr("y", margin.top + 1.5 * height).attr("x", margin.left + width + axispos.ytitle).text(additive_ylab).attr("transform", rotate_additive_ylab ? "rotate(270," + (margin.left + width + axispos.ytitle) + ", " + (margin.top + height * 1.5) + ")" : "").attr("text-anchor", "middle").attr("fill", "green");
       }
-      suggestive_bar = g.append("g").attr("class", "suggestive");
-      suggestive_bar.selectAll("empty").data([data.suggestive]).enter().append("line").attr("y1", function(d) {
-        return yscale(d);
-      }).attr("y2", function(d) {
-        return yscale(d);
-      }).attr("x1", margin.left).attr("x2", margin.left + width).attr("fill", "none").attr("stroke", suggestivecolor).attr("stroke-width", 5).style("pointer-events", "none");
-      suggestive_bar = g.append("g").attr("class", "significant");
-      suggestive_bar.selectAll("empty").data([data.significant]).enter().append("line").attr("y1", function(d) {
-        return yscale(d);
-      }).attr("y2", function(d) {
-        return yscale(d);
-      }).attr("x1", margin.left).attr("x2", margin.left + width).attr("fill", "none").attr("stroke", significantcolor).attr("stroke-width", 5).style("pointer-events", "none");
+      if ('suggestive' in data) {
+        suggestive_bar = g.append("g").attr("class", "suggestive");
+        suggestive_bar.selectAll("empty").data([data.suggestive]).enter().append("line").attr("y1", function(d) {
+          return yscale(d);
+        }).attr("y2", function(d) {
+          return yscale(d);
+        }).attr("x1", margin.left).attr("x2", margin.left + width).attr("fill", "none").attr("stroke", suggestivecolor).attr("stroke-width", 5).style("pointer-events", "none");
+        suggestive_bar = g.append("g").attr("class", "significant");
+        suggestive_bar.selectAll("empty").data([data.significant]).enter().append("line").attr("y1", function(d) {
+          return yscale(d);
+        }).attr("y2", function(d) {
+          return yscale(d);
+        }).attr("x1", margin.left).attr("x2", margin.left + width).attr("fill", "none").attr("stroke", significantcolor).attr("stroke-width", 5).style("pointer-events", "none");
+      }
       lodcurve = function(chr, lodcolumn) {
         return d3.svg.line().x(function(d) {
           return xscale[chr](d);
@@ -181,7 +185,7 @@ lodchart = function() {
           return yscale(data.lodByChr[chr][i][lodcolumn]);
         });
       };
-      if (data['additive'].length > 0) {
+      if ('additive' in data) {
         additivecurve = function(chr, lodcolumn) {
           return d3.svg.line().x(function(d) {
             return xscale[chr](d);
@@ -191,15 +195,10 @@ lodchart = function() {
         };
       }
       curves = g.append("g").attr("id", "curves");
-      _ref = data.chrnames;
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        chr = _ref[_i];
-        curves.append("path").datum(data.posByChr[chr[0]]).attr("d", lodcurve(chr[0], lodvarnum)).attr("stroke", lodlinecolor).attr("fill", "none").attr("stroke-width", linewidth).style("pointer-events", "none");
-      }
-      if (data['additive'].length > 0) {
-        _ref1 = data.chrnames;
-        for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
-          chr = _ref1[_j];
+      if ('additive' in data) {
+        _ref = data.chrnames;
+        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+          chr = _ref[_i];
           curves.append("path").datum(data.posByChr[chr[0]]).attr("d", additivecurve(chr[0], lodvarnum)).attr("stroke", additivelinecolor).attr("fill", "none").attr("stroke-width", 1).style("pointer-events", "none");
         }
       }
@@ -431,152 +430,3 @@ lodchart = function() {
   };
   return chart;
 };
-
-reorgLodData = function(data, lodvarname) {
-  var additiveval, chr, i, j, lodcolumn, lodval, marker, pos, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2;
-  if (lodvarname == null) {
-    lodvarname = null;
-  }
-  data.posByChr = {};
-  data.lodByChr = {};
-  data.additiveByChr = {};
-  _ref = data.chrnames;
-  for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
-    chr = _ref[i];
-    data.posByChr[chr[0]] = [];
-    data.lodByChr[chr[0]] = [];
-    data.additiveByChr[chr[0]] = [];
-    _ref1 = data.pos;
-    for (j = _j = 0, _len1 = _ref1.length; _j < _len1; j = ++_j) {
-      pos = _ref1[j];
-      if (data.chr[j] === chr[0]) {
-        data.posByChr[chr[0]].push(pos);
-        if (!Array.isArray(data.lodnames)) {
-          data.lodnames = [data.lodnames];
-        }
-        if (data['additive'].length > 0) {
-          additiveval = (function() {
-            var _k, _len2, _ref2, _results;
-            _ref2 = data.lodnames;
-            _results = [];
-            for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
-              lodcolumn = _ref2[_k];
-              _results.push(data['additive'][j]);
-            }
-            return _results;
-          })();
-        }
-        lodval = (function() {
-          var _k, _len2, _ref2, _results;
-          _ref2 = data.lodnames;
-          _results = [];
-          for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
-            lodcolumn = _ref2[_k];
-            _results.push(data[lodcolumn][j]);
-          }
-          return _results;
-        })();
-        data.additiveByChr[chr[0]].push(additiveval);
-        data.lodByChr[chr[0]].push(lodval);
-      }
-    }
-  }
-  if (lodvarname != null) {
-    data.markers = [];
-    _ref2 = data.markernames;
-    for (i = _k = 0, _len2 = _ref2.length; _k < _len2; i = ++_k) {
-      marker = _ref2[i];
-      if (marker !== "") {
-        data.markers.push({
-          name: marker,
-          chr: data.chr[i],
-          pos: data.pos[i],
-          lod: data[lodvarname][i]
-        });
-      }
-    }
-  }
-  return data;
-};
-
-chrscales = function(data, width, chrGap, leftMargin, pad4heatmap) {
-  var L, chr, chrEnd, chrLength, chrStart, cur, d, i, maxd, rng, totalChrLength, w, _i, _j, _len, _len1, _ref, _ref1;
-  chrStart = [];
-  chrEnd = [];
-  chrLength = [];
-  totalChrLength = 0;
-  maxd = 0;
-  _ref = data.chrnames;
-  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-    chr = _ref[_i];
-    d = maxdiff(data.posByChr[chr[0]]);
-    if (d > maxd) {
-      maxd = d;
-    }
-    rng = d3.extent(data.posByChr[chr[0]]);
-    chrStart.push(rng[0]);
-    chrEnd.push(rng[1]);
-    L = rng[1] - rng[0];
-    chrLength.push(L);
-    totalChrLength += L;
-  }
-  if (pad4heatmap) {
-    data.recwidth = maxd;
-    chrStart = chrStart.map(function(x) {
-      return x - maxd / 2;
-    });
-    chrEnd = chrEnd.map(function(x) {
-      return x + maxd / 2;
-    });
-    chrLength = chrLength.map(function(x) {
-      return x + maxd;
-    });
-    totalChrLength += chrLength.length * maxd;
-  }
-  data.chrStart = [];
-  data.chrEnd = [];
-  cur = leftMargin;
-  if (!pad4heatmap) {
-    cur += chrGap / 2;
-  }
-  data.xscale = {};
-  _ref1 = data.chrnames;
-  for (i = _j = 0, _len1 = _ref1.length; _j < _len1; i = ++_j) {
-    chr = _ref1[i];
-    data.chrStart.push(cur);
-    w = Math.round((width - chrGap * (data.chrnames.length - pad4heatmap)) / totalChrLength * chrLength[i]);
-    data.chrEnd.push(cur + w);
-    cur = data.chrEnd[i] + chrGap;
-    data.xscale[chr[0]] = d3.scale.linear().domain([chrStart[i], chrEnd[i]]).range([data.chrStart[i], data.chrEnd[i]]);
-  }
-  return data;
-};
-
-maxdiff = function(x) {
-  var d, i, result, _i, _ref;
-  if (x.length < 2) {
-    return null;
-  }
-  result = x[1] - x[0];
-  if (x.length < 3) {
-    return result;
-  }
-  for (i = _i = 2, _ref = x.length; 2 <= _ref ? _i < _ref : _i > _ref; i = 2 <= _ref ? ++_i : --_i) {
-    d = x[i] - x[i - 1];
-    if (d > result) {
-      result = d;
-    }
-  }
-  return result;
-};
-
-formatAxis = function(d) {
-  var ndig;
-  d = d[1] - d[0];
-  ndig = Math.floor(Math.log(d % 10) / Math.log(10));
-  if (ndig > 0) {
-    ndig = 0;
-  }
-  ndig = Math.abs(ndig);
-  return d3.format("." + ndig + "f");
-};
diff --git a/wqflask/wqflask/static/new/javascript/lodheatmap.coffee b/wqflask/wqflask/static/new/javascript/lodheatmap.coffee
index 6cb8bfc7..6ffaefeb 100644
--- a/wqflask/wqflask/static/new/javascript/lodheatmap.coffee
+++ b/wqflask/wqflask/static/new/javascript/lodheatmap.coffee
@@ -8,7 +8,7 @@ lodheatmap = () ->
     chrGap = 8

     titlepos = 20

     rectcolor = d3.rgb(230, 230, 230)

-    colors = ["slateblue", "white", "crimson"]

+    colors = ["slateblue", "black", "yellow"]

     title = ""

     xlab = "Chromosome"

     ylab = ""

@@ -33,7 +33,9 @@ lodheatmap = () ->
             rectHeight = yscale(0)-yscale(1)

 

             xLR = {}

+            console.log("data.chrnames:", data.chrnames)

             for chr in data.chrnames

+                console.log("chr is:", chr)

                 xLR[chr] = getLeftRight(data.posByChr[chr])

       

             # z-axis (color) limits; if not provided, make symmetric about 0

diff --git a/wqflask/wqflask/static/new/javascript/lodheatmap.js b/wqflask/wqflask/static/new/javascript/lodheatmap.js
index 447287da..b009b4cd 100644
--- a/wqflask/wqflask/static/new/javascript/lodheatmap.js
+++ b/wqflask/wqflask/static/new/javascript/lodheatmap.js
@@ -20,7 +20,7 @@ lodheatmap = function() {
   chrGap = 8;
   titlepos = 20;
   rectcolor = d3.rgb(230, 230, 230);
-  colors = ["slateblue", "white", "crimson"];
+  colors = ["slateblue", "black", "yellow"];
   title = "";
   xlab = "Chromosome";
   ylab = "";
@@ -41,9 +41,11 @@ lodheatmap = function() {
       yscale.domain([-0.5, nlod - 0.5]).range([margin.top + height, margin.top]);
       rectHeight = yscale(0) - yscale(1);
       xLR = {};
+      console.log("data.chrnames:", data.chrnames);
       _ref = data.chrnames;
       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
         chr = _ref[_i];
+        console.log("chr is:", chr);
         xLR[chr] = getLeftRight(data.posByChr[chr]);
       }
       zmin = 0;
diff --git a/wqflask/wqflask/static/new/javascript/show_corr.js b/wqflask/wqflask/static/new/javascript/show_corr.js
index 0a866548..97b1a7db 100644
--- a/wqflask/wqflask/static/new/javascript/show_corr.js
+++ b/wqflask/wqflask/static/new/javascript/show_corr.js
@@ -1,11 +1,8 @@
-// Generated by CoffeeScript 1.6.1
-(function() {
-  var root;
+// Generated by CoffeeScript 1.7.1
+var root;
 
-  root = typeof exports !== "undefined" && exports !== null ? exports : this;
+root = typeof exports !== "undefined" && exports !== null ? exports : this;
 
-  $(function() {
-    return root.scatter_plot = new Scatter_Plot();
-  });
-
-}).call(this);
+$(function() {
+  return root.scatter_plot = new Scatter_Plot();
+});
diff --git a/wqflask/wqflask/templates/heatmap.html b/wqflask/wqflask/templates/heatmap.html
index 1ffbd5d8..81c4a9d9 100644
--- a/wqflask/wqflask/templates/heatmap.html
+++ b/wqflask/wqflask/templates/heatmap.html
@@ -1,5 +1,5 @@
 {% extends "base.html" %}

-{% block title %}Interval Mapping{% endblock %}

+{% block title %}Heatmap{% endblock %}

 {% block css %}

     <link rel="stylesheet" type="text/css" href="/static/new/css/d3-tip.min.css" />

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

@@ -35,7 +35,10 @@
     <script language="javascript" type="text/javascript" src="/static/new/js_external/d3-tip.min.js"></script>

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

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

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

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

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

+<!--    <script language="javascript" type="text/javascript" src="/static/new/javascript/create_heatmap.js"></script>-->

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

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

 

 {% endblock %}
\ No newline at end of file
diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py
index b55189eb..3c448988 100755
--- a/wqflask/wqflask/views.py
+++ b/wqflask/wqflask/views.py
@@ -209,7 +209,7 @@ def heatmap_page():
     start_vars = request.form
     temp_uuid = uuid.uuid4()
     
-    version = "v1"
+    version = "v4"
     key = "heatmap:{}:".format(version) + json.dumps(start_vars, sort_keys=True)
     print("key is:", pf(key))
     with Bench("Loading cache"):