aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--wqflask/tests/unit/wqflask/marker_regression/test_gemma_mapping.py4
-rw-r--r--wqflask/tests/unit/wqflask/marker_regression/test_rqtl_mapping.py2
-rw-r--r--wqflask/wqflask/marker_regression/rqtl_mapping.py6
-rw-r--r--wqflask/wqflask/marker_regression/run_mapping.py47
-rw-r--r--wqflask/wqflask/show_trait/show_trait.py3
-rw-r--r--wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js59
-rw-r--r--wqflask/wqflask/templates/pair_scan_results.html154
-rwxr-xr-xwqflask/wqflask/templates/show_trait_mapping_tools.html90
-rw-r--r--wqflask/wqflask/views.py20
9 files changed, 261 insertions, 124 deletions
diff --git a/wqflask/tests/unit/wqflask/marker_regression/test_gemma_mapping.py b/wqflask/tests/unit/wqflask/marker_regression/test_gemma_mapping.py
index 58a44b2a..f2ea22c0 100644
--- a/wqflask/tests/unit/wqflask/marker_regression/test_gemma_mapping.py
+++ b/wqflask/tests/unit/wqflask/marker_regression/test_gemma_mapping.py
@@ -114,7 +114,7 @@ class TestGemmaMapping(unittest.TestCase):
create_trait.side_effect = create_trait_side_effect
group = MockGroup({"name": "group_X", "samplelist": samplelist})
- this_dataset = AttributeSetter({"group": group, "name": "A"})
+ this_dataset = AttributeSetter({"group": group, "name": "dataset1_name"})
flat_files.return_value = "Home/Genenetwork"
with mock.patch("builtins.open", mock.mock_open())as mock_open:
@@ -134,7 +134,7 @@ class TestGemmaMapping(unittest.TestCase):
flat_files.assert_called_once_with('mapping')
mock_open.assert_called_once_with(
- 'Home/Genenetwork/COVAR_anFZ_LfZYV0Ulywo+7tRCw.txt', 'w')
+ 'Home/Genenetwork/COVAR_npKxIOnq3azWdgYixtd9IQ.txt', 'w')
filehandler = mock_open()
filehandler.write.assert_has_calls([mock.call(
'-9\t'), mock.call('-9\t'), mock.call('-9\t'), mock.call('-9\t'), mock.call('\n')])
diff --git a/wqflask/tests/unit/wqflask/marker_regression/test_rqtl_mapping.py b/wqflask/tests/unit/wqflask/marker_regression/test_rqtl_mapping.py
index 9d13e943..b4423d8f 100644
--- a/wqflask/tests/unit/wqflask/marker_regression/test_rqtl_mapping.py
+++ b/wqflask/tests/unit/wqflask/marker_regression/test_rqtl_mapping.py
@@ -32,7 +32,7 @@ class TestRqtlMapping(unittest.TestCase):
"results" : []}
results = run_rqtl(trait_name="the_trait", vals=[], samples=[],
- dataset=dataset, mapping_scale="cM", model="normal", method="hk",
+ dataset=dataset, pair_scan=False, mapping_scale="cM", model="normal", method="hk",
num_perm=5, perm_strata_list=[], do_control="false", control_marker="",
manhattan_plot=True, cofactors="")
diff --git a/wqflask/wqflask/marker_regression/rqtl_mapping.py b/wqflask/wqflask/marker_regression/rqtl_mapping.py
index e6421fe2..c7a3451a 100644
--- a/wqflask/wqflask/marker_regression/rqtl_mapping.py
+++ b/wqflask/wqflask/marker_regression/rqtl_mapping.py
@@ -20,7 +20,8 @@ from utility.tools import locate, GN3_LOCAL_URL
import utility.logger
logger = utility.logger.getLogger(__name__)
-def run_rqtl(trait_name, vals, samples, dataset, mapping_scale, model, method, num_perm, perm_strata_list, do_control, control_marker, manhattan_plot, cofactors):
+
+def run_rqtl(trait_name, vals, samples, dataset, pair_scan, mapping_scale, model, method, num_perm, perm_strata_list, do_control, control_marker, manhattan_plot, cofactors):
"""Run R/qtl by making a request to the GN3 endpoint and reading in the output file(s)"""
pheno_file = write_phenotype_file(trait_name, samples, vals, dataset, cofactors, perm_strata_list)
@@ -38,6 +39,9 @@ def run_rqtl(trait_name, vals, samples, dataset, mapping_scale, model, method, n
"scale": mapping_scale
}
+ if pair_scan:
+ post_data["pairscan"] = True
+
if cofactors:
covarstruct_file = write_covarstruct_file(cofactors)
post_data["covarstruct"] = covarstruct_file
diff --git a/wqflask/wqflask/marker_regression/run_mapping.py b/wqflask/wqflask/marker_regression/run_mapping.py
index 9d70bb15..cf217a96 100644
--- a/wqflask/wqflask/marker_regression/run_mapping.py
+++ b/wqflask/wqflask/marker_regression/run_mapping.py
@@ -108,6 +108,7 @@ class RunMapping:
self.mapping_results_path = "{}{}.csv".format(
webqtlConfig.GENERATED_IMAGE_DIR, mapping_results_filename)
+ self.pair_scan = False
self.manhattan_plot = False
if 'manhattan_plot' in start_vars:
if start_vars['manhattan_plot'].lower() != "false":
@@ -125,8 +126,6 @@ class RunMapping:
self.use_loco = None
self.suggestive = ""
self.significant = ""
- # Initializing this since it is checked in views to determine which template to use
- self.pair_scan = False
if 'transform' in start_vars:
self.transform = start_vars['transform']
else:
@@ -233,18 +232,19 @@ class RunMapping:
self.score_type = "-logP"
self.control_marker = start_vars['control_marker']
self.do_control = start_vars['do_control']
- if 'mapmethod_rqtl_geno' in start_vars:
- self.method = start_vars['mapmethod_rqtl_geno']
+ if 'mapmethod_rqtl' in start_vars:
+ self.method = start_vars['mapmethod_rqtl']
else:
self.method = "em"
- self.model = start_vars['mapmodel_rqtl_geno']
- # if start_vars['pair_scan'] == "true":
- # self.pair_scan = True
+ self.model = start_vars['mapmodel_rqtl']
+ self.pair_scan = False
+ if 'pair_scan' in start_vars:
+ self.pair_scan = True
if self.permCheck and self.num_perm > 0:
self.perm_output, self.suggestive, self.significant, results = rqtl_mapping.run_rqtl(
- self.this_trait.name, self.vals, self.samples, self.dataset, self.mapping_scale, self.model, self.method, self.num_perm, self.perm_strata, self.do_control, self.control_marker, self.manhattan_plot, self.covariates)
+ self.this_trait.name, self.vals, self.samples, self.dataset, self.pair_scan, self.mapping_scale, self.model, self.method, self.num_perm, self.perm_strata, self.do_control, self.control_marker, self.manhattan_plot, self.covariates)
else:
- results = rqtl_mapping.run_rqtl(self.this_trait.name, self.vals, self.samples, self.dataset, self.mapping_scale, self.model, self.method,
+ results = rqtl_mapping.run_rqtl(self.this_trait.name, self.vals, self.samples, self.dataset, self.pair_scan, self.mapping_scale, self.model, self.method,
self.num_perm, self.perm_strata, self.do_control, self.control_marker, self.manhattan_plot, self.covariates)
elif self.mapping_method == "reaper":
if "startMb" in start_vars: # ZS: Check if first time page loaded, so it can default to ON
@@ -311,33 +311,8 @@ class RunMapping:
self.no_results = True
else:
if self.pair_scan == True:
- self.qtl_results = []
- highest_chr = 1 # This is needed in order to convert the highest chr to X/Y
- for marker in results:
- if marker['chr1'] > 0 or marker['chr1'] == "X" or marker['chr1'] == "X/Y":
- if marker['chr1'] > highest_chr or marker['chr1'] == "X" or marker['chr1'] == "X/Y":
- highest_chr = marker['chr1']
- if 'lod_score' in list(marker.keys()):
- self.qtl_results.append(marker)
-
- self.trimmed_markers = results
-
- for qtl in enumerate(self.qtl_results):
- self.json_data['chr1'].append(str(qtl['chr1']))
- self.json_data['chr2'].append(str(qtl['chr2']))
- self.json_data['Mb'].append(qtl['Mb'])
- self.json_data['markernames'].append(qtl['name'])
-
- self.js_data = dict(
- json_data=self.json_data,
- this_trait=self.this_trait.name,
- data_set=self.dataset.name,
- maf=self.maf,
- manhattan_plot=self.manhattan_plot,
- mapping_scale=self.mapping_scale,
- qtl_results=self.qtl_results
- )
-
+ self.figure_data = results[0]
+ self.table_data = results[1]
else:
self.qtl_results = []
self.results_for_browser = []
diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py
index 93f95852..d9821d9c 100644
--- a/wqflask/wqflask/show_trait/show_trait.py
+++ b/wqflask/wqflask/show_trait/show_trait.py
@@ -280,6 +280,9 @@ class ShowTrait:
hddn['species'] = self.dataset.group.species
hddn['use_outliers'] = False
hddn['method'] = "gemma"
+ hddn['mapmethod_rqtl'] = "hk"
+ hddn['mapmodel_rqtl'] = "normal"
+ hddn['pair_scan'] = ""
hddn['selected_chr'] = -1
hddn['mapping_display_all'] = True
hddn['suggestive'] = 0
diff --git a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js
index d0b41d04..737a0b82 100644
--- a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js
+++ b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js
@@ -140,12 +140,17 @@ $('input[name=display_all]').change((function(_this) {
};
})(this));
-//ZS: This is a list of inputs to be passed to the loading page, since not all inputs on the trait page are relevant to mapping
-var mapping_input_list = ['temp_uuid', 'trait_id', 'dataset', 'tool_used', 'form_url', 'method', 'transform', 'trimmed_markers', 'selected_chr', 'chromosomes', 'mapping_scale',
- 'sample_vals', 'vals_hash', 'score_type', 'suggestive', 'significant', 'num_perm', 'permCheck', 'perm_output', 'perm_strata', 'categorical_vars',
- 'num_bootstrap', 'bootCheck', 'bootstrap_results', 'LRSCheck', 'covariates', 'maf', 'use_loco', 'manhattan_plot', 'control_marker',
- 'do_control', 'genofile', 'pair_scan', 'startMb', 'endMb', 'graphWidth', 'lrsMax', 'additiveCheck', 'showSNP', 'showGenes', 'viewLegend',
- 'haplotypeAnalystCheck', 'mapmethod_rqtl_geno', 'mapmodel_rqtl_geno', 'temp_trait', 'group', 'species', 'primary_samples']
+// This is a list of inputs to be passed to the loading page, since not all inputs on the trait page are relevant to mapping
+var mapping_input_list = ['temp_uuid', 'trait_id', 'dataset', 'tool_used', 'form_url', 'method',
+ 'transform', 'trimmed_markers', 'selected_chr', 'chromosomes', 'mapping_scale',
+ 'sample_vals', 'vals_hash', 'score_type', 'suggestive', 'significant',
+ 'num_perm', 'permCheck', 'perm_output', 'perm_strata', 'categorical_vars',
+ 'num_bootstrap', 'bootCheck', 'bootstrap_results', 'LRSCheck', 'covariates',
+ 'maf', 'use_loco', 'manhattan_plot', 'control_marker', 'do_control',
+ 'genofile', 'pair_scan', 'startMb', 'endMb', 'graphWidth', 'lrsMax',
+ 'additiveCheck', 'showSNP', 'showGenes', 'viewLegend', 'haplotypeAnalystCheck',
+ 'mapmethod_rqtl', 'mapmodel_rqtl', 'temp_trait', 'group', 'species',
+ 'reaper_version', 'primary_samples']
$(".rqtl-geno-tab, #rqtl_geno_compute").on("click", (function(_this) {
return function() {
@@ -156,6 +161,8 @@ $(".rqtl-geno-tab, #rqtl_geno_compute").on("click", (function(_this) {
$('input[name=selected_chr]').val($('#chr_rqtl_geno').val());
$('input[name=mapping_scale]').val($('#scale_rqtl_geno').val());
$('input[name=genofile]').val($('#genofile_rqtl_geno').val());
+ $('input[name=mapmodel_rqtl]').val($('#mapmodel_rqtl_geno').val());
+ $('input[name=mapmethod_rqtl]').val($('#mapmethod_rqtl_geno').val());
$('input[name=num_perm]').val($('input[name=num_perm_rqtl_geno]').val());
$('input[name=categorical_vars]').val(js_data.categorical_vars)
$('input[name=manhattan_plot]').val($('input[name=manhattan_plot_rqtl]:checked').val());
@@ -171,6 +178,30 @@ $(".rqtl-geno-tab, #rqtl_geno_compute").on("click", (function(_this) {
};
})(this));
+$(".rqtl-pair-tab, #rqtl_pair_compute").on("click", (function(_this) {
+ return function() {
+ if ($(this).hasClass('active') || $(this).attr('id') == "rqtl_pair_compute"){
+ var form_data, url;
+ url = "/loading";
+ $('input[name=method]').val("rqtl_geno");
+ $('input[name=pair_scan]').val("true");
+ $('input[name=genofile]').val($('#genofile_rqtl_pair').val());
+ $('input[name=mapmodel_rqtl]').val($('#mapmodel_rqtl_pair').val());
+ $('input[name=mapmethod_rqtl]').val($('#mapmethod_rqtl_pair').val());
+ $('input[name=num_perm]').val($('input[name=num_perm_rqtl_pair]').val());
+ $('input[name=categorical_vars]').val(js_data.categorical_vars)
+ $('input[name=control_marker]').val($('input[name=control_rqtl_pair]').val());
+ $('input[name=do_control]').val($('input[name=do_control_rqtl_pair]:checked').val());
+ $('input[name=tool_used]').val("Mapping");
+ $('input[name=form_url]').val("/run_mapping");
+ $('input[name=wanted_inputs]').val(mapping_input_list.join(","));
+ return submit_special(url);
+ } else {
+ return true
+ }
+ };
+})(this));
+
$(".gemma-tab, #gemma_compute").on("click", (function(_this) {
return function() {
if ($(this).hasClass('active') || $(this).attr('id') == "gemma_compute"){
@@ -238,25 +269,25 @@ $("#use_composite_choice").change(composite_mapping_fields);
$("#mapping_method_choice").change(mapping_method_fields);
-$("#mapmodel_rqtl_geno").change(function() {
+$("#mapmodel_rqtl_geno,#mapmodel_rqtl_pair").change(function() {
if ($(this).val() == "np"){
$("#mapmethod_rqtl_geno").attr('disabled', 'disabled');
$("#mapmethod_rqtl_geno").css('background-color', '#CCC');
- $("#missing_geno").attr('disabled', 'disabled');
- $("#missing_geno").css('background-color', '#CCC');
+ $("#missing_geno,#missing_geno_pair").attr('disabled', 'disabled');
+ $("#missing_geno,#missing_geno_pair").css('background-color', '#CCC');
} else {
$("#mapmethod_rqtl_geno").removeAttr('disabled');
$("#mapmethod_rqtl_geno").css('background-color', '#FFF');
- $("#missing_geno").removeAttr('disabled');
- $("#missing_geno").css('background-color', '#FFF');
+ $("#missing_geno,#missing_geno_pair").removeAttr('disabled');
+ $("#missing_geno,#missing_geno_pair").css('background-color', '#FFF');
}
});
-$("#mapmethod_rqtl_geno").change(function() {
+$("#mapmethod_rqtl_geno,#mapmethod_rqtl_pair").change(function() {
if ($(this).val() == "mr"){
- $("#missing_geno_div").css('display', 'block');
+ $("#missing_geno_div,#missing_geno_pair_div").css('display', 'block');
} else {
- $("#missing_geno_div").css('display', 'none');
+ $("#missing_geno_div,#missing_geno_pair_div").css('display', 'none');
}
});
diff --git a/wqflask/wqflask/templates/pair_scan_results.html b/wqflask/wqflask/templates/pair_scan_results.html
index fb825b90..b6ac26be 100644
--- a/wqflask/wqflask/templates/pair_scan_results.html
+++ b/wqflask/wqflask/templates/pair_scan_results.html
@@ -1,70 +1,114 @@
{% extends "base.html" %}
{% block title %}Pair Scan{% endblock %}
{% block css %}
- <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
- <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='d3-tip/d3-tip.css') }}" />
- <link rel="stylesheet" type="text/css" href="/static/new/css/panelutil.css" />
+<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='d3-tip/d3-tip.css') }}" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/d3panels.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/pair_scan.css" />
{% endblock %}
{% block content %} <!-- Start of body -->
- {{ header("Mapping",
- '{}: {}'.format(this_trait.name, this_trait.description_fmt)) }}
+{{ header("Mapping",
+ '{}: {}'.format(this_trait.name, this_trait.description_fmt)) }}
- <div class="container">
- <div>
- <h2>
- Pair Scan
- </h2>
- </div>
- <div id="chart_container">
- <div class="pair_scan_figure" id="pair_scan_figure">
- <a href="/tmp/{{ pair_scan_filename }}">
- <img alt="Embedded Image" src="data:image/png;base64,
- {% for elem in pair_scan_array -%}
- {% print("%c"|format(elem)) %}
- {%- endfor %}
- " /></a>
- </div>
- </div>
- <div>
- <h2>
- Results
- </h2>
- <table cellpadding="0" cellspacing="0" border="0" id="pair_scan_results" class="table table-hover table-striped table-bordered">
- <thead>
- <tr>
- <td>Index</td>
- <td>Locus</td>
- <td>Chr 1</td>
- <td>Mb</td>
- <td>Chr 2</td>
- </tr>
- </thead>
- <tbody>
- {% for marker in trimmed_markers %}
- <tr>
- <td>{{loop.index}}</td>
- <td>{{marker.name}}</td>
- <td>{{marker.chr1}}</td>
- <td>{{marker.Mb}}</td>
- <td>{{marker.chr2}}</td>
- </tr>
- {% endfor %}
- </tbody>
- </table>
- </div>
+<div id="main_div" class="container">
+ <div>
+ <h2>
+ Pair Scan
+ </h2>
</div>
+ <div class="qtlcharts" id="chart_container">
+ <div id="pairscan_chart"></div>
+ </div>
+ <div class="pairscan-container">
+ <h2>
+ Results
+ </h2>
+ <table cellpadding="0" cellspacing="0" border="0" id="pair_scan_results" class="table table-hover table-striped table-bordered">
+ <thead>
+ <tr>
+ <th colspan="3">Interval 1</th>
+ <th rowspan="3">LOD</th>
+ <th colspan="3">Interval 2</th>
+ </tr>
+ <tr>
+ <th rowspan="2">Position</th>
+ <th colspan="2">Flanking Markers</th>
+ <th rowspan="2">Position</th>
+ <th colspan="2">Flanking Markers</th>
+ </tr>
+ <tr>
+ <th>Proximal</th>
+ <th>Distal</th>
+ <th>Proximal</th>
+ <th>Distal</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for row in table_data %}
+ <tr>
+ <td>{{ row.pos1 }}</td>
+ <td>{{ row.proximal1 }}</td>
+ <td>{{ row.distal1 }}</td>
+ <td>{{ row.lod }}</td>
+ <td>{{ row.pos2 }}</td>
+ <td>{{ row.proximal2 }}</td>
+ <td>{{ row.distal2 }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+</div>
{% endblock %}
{% block js %}
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='d3js/d3.min.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='d3-tip/d3-tip.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/scientific.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/underscore.min.js') }}"></script>
+<script>
+ var figure_data = {{ figure_data | safe }}
+</script>
+
+<script src="https://d3js.org/d3.v7.min.js"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.js') }}"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/scientific.js') }}"></script>
+<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script>
+<script language="javascript" type="text/javascript" src="/static/new/javascript/d3panels.js"></script>
+
+<script type="text/javascript">
+
+var data, mychart;
+
+mychart = d3panels.lod2dheatmap({
+ equalCells: true
+});
-{% endblock %} \ No newline at end of file
+mychart(d3.select('div#pairscan_chart'), figure_data);
+
+table_conf = {
+ "columns":[
+ { "width": "165px" },
+ { "width": "130px" },
+ { "width": "130px" },
+ { "width": "50px" },
+ { "width": "165px" },
+ { "width": "130px" },
+ { "width": "130px" },
+ ],
+ "sDom": "itir",
+ "autoWidth": false,
+ "bSortClasses": false,
+ "order": [[3, "desc" ]],
+ "scrollY": "100vh",
+ "scroller": true,
+ "scrollCollapse": true
+ }
+
+trait_table = $('#pair_scan_results').DataTable(table_conf);
+
+</script>
+
+{% endblock %}
diff --git a/wqflask/wqflask/templates/show_trait_mapping_tools.html b/wqflask/wqflask/templates/show_trait_mapping_tools.html
index 3af94ed6..fbb26ede 100755
--- a/wqflask/wqflask/templates/show_trait_mapping_tools.html
+++ b/wqflask/wqflask/templates/show_trait_mapping_tools.html
@@ -13,6 +13,9 @@
<li class="rqtl-geno-tab mapping-tab {% if dataset.group.mapping_id == '3' %}active{% endif %}">
<a href="#rqtl_geno" data-toggle="tab">R/qtl</a>
</li>
+ <li class="rqtl-pair-tab mapping-tab">
+ <a href="#rqtl_pair" data-toggle="tab">Pair Scan</a>
+ </li>
{% elif mapping_method == "QTLReaper" %}
<li class="reaper-tab mapping-tab">
<a href="#interval_mapping" data-toggle="tab">Haley-Knott Regression</a>
@@ -325,6 +328,89 @@
</div>
</div>
</div>
+ <div class="tab-pane" id="rqtl_pair">
+ <div class="form-horizontal section-form-div">
+ {% if genofiles and genofiles|length > 0 %}
+ <div class="mapping_method_fields form-group">
+ <label for="genofiles" class="col-xs-3 control-label">Genotypes</label>
+ <div class="col-xs-6 controls">
+ <select id="genofile_rqtl_pair" class="form-control">
+ {% for item in genofiles %}
+ <option value="{{item['location']}}:{{item['title']}}">{{item['title']}}</option>
+ {% endfor %}
+ </select>
+ </div>
+ </div>
+ {% endif %}
+ <div class="mapping_method_fields form-group">
+ <label for="control_for" class="col-xs-3 control-label">Control&nbsp;for</label>
+ <div class="col-xs-6 controls">
+ <input name="control_rqtl_pair" value="{% if dataset.type == 'ProbeSet' and this_trait.locus_chr != '' %}{{ nearest_marker }}{% endif %}" type="text" class="form-control cofactor-input" />
+ <label class="radio-inline">
+ <input type="radio" name="do_control_rqtl" value="true">
+ Yes
+ </label>
+ <label class="radio-inline">
+ <input type="radio" name="do_control_rqtl" value="false" checked="">
+ No
+ </label>
+ </div>
+ </div>
+ <div class="mapping_method_fields form-group">
+ <label for="mapmodel_rqtl_pair" class="col-xs-3 control-label">Model</label>
+ <div class="col-xs-4 controls">
+ <select id="mapmodel_rqtl_pair" name="mapmodel_rqtl_pair" class="form-control">
+ <option value="normal">Normal</option>
+ {% if binary == "true" %}<option value="binary">Binary</option>{% endif %}
+ <!--<option value="2part">2-part</option>-->
+ <option value="np">Non-parametric</option>
+ </select>
+ </div>
+ </div>
+ <div class="mapping_method_fields form-group">
+ <label for="mapmethod_rqtl_pair" class="col-xs-3 control-label">Method</label>
+ <div class="col-xs-6 controls">
+ <select id="mapmethod_rqtl_pair" name="mapmethod_rqtl_pair" class="form-control">
+ <option value="hk" selected>Haley-Knott</option>
+ <option value="ehk">Extended Haley-Knott</option>
+ <option value="mr">Marker Regression</option>
+ <option value="em">Expectation-Maximization</option>
+ <option value="imp">Imputation</option>
+ </select>
+ </div>
+ </div>
+ <div id="missing_geno_pair_div" class="mapping_method_fields form-group" style="display: none;">
+ <label for="missing_genotypes_pair" class="col-xs-3 control-label"></label>
+ <div class="col-xs-6 controls">
+ <select id="missing_genotype_pair" name="missing_genotypes" class="form-control">
+ <option value="mr">Remove Samples w/o Genotypes</option>
+ <option value="mr-imp">Single Imputation</option>
+ <option value="mr-argmax">Imputation w/ Viterbi Algorithm</option>
+ </select>
+ </div>
+ </div>
+ <div class="mapping_method_fields form-group">
+ <label class="col-xs-3 control-label">Covariates<br><span class="covar-text">Select covariate(s) from a collection</span></label>
+ <div class="col-xs-8 covar-options">
+ {% if g.user_session.num_collections < 1 %}
+ No collections available. Please add traits to a collection to use them as covariates.
+ {% else %}
+ <div class="select-covar-div">
+ <button type="button" class="btn btn-default select-covar-button select_covariates">Select</button>
+ <button type="button" class="btn btn-default select-covar-button remove_covariates">Remove</button>
+ </div>
+ <textarea rows="3" cols="50" readonly placeholder="No covariates selected" class="selected-covariates"></textarea>
+ {% endif %}
+ </div>
+ </div>
+ <div class="mapping_method_fields form-group">
+ <label class="col-xs-3 control-label"></label>
+ <div class="col-xs-6 controls">
+ <button id="rqtl_pair_compute" type="button" class="btn submit_special btn-success" data-url="/marker_regression" title="Compute Pair Scan" value="Compute">Compute</button>
+ </div>
+ </div>
+ </div>
+ </div>
{% endif %}
{% endfor %}
</div>
@@ -338,8 +424,10 @@
<dt>GEMMA</dt>
<dd>Maps traits with correction for kinship among samples using a linear mixed model method, and also allows users to fit multiple covariates such as sex, age, treatment, and genetic markers (<a href="https://www.ncbi.nlm.nih.gov/pubmed/24531419">PMID: 2453419</a>, and <a href="https://github.com/genetics-statistics/GEMMA"> GitHub code</a>). GEMMA incorporates the Leave One Chromosome Out (LOCO) method to ensure that the correction for kinship does not remove useful genetic variance near each marker. Markers can be filtered to include only those with minor allele frequencies (MAF) above a threshold. The default MAF is 0.05.</dd>
{% elif mapping_method == "R/qtl" %}
- <dt class="map-method-text">R/qtl (version 1.44.9</dt>
+ <dt class="map-method-text">R/qtl (version 1.44.9)</dt>
<dd>The original R/qtl mapping package that supports classic experimental crosses including 4-parent F2 intercrosses (e.g., NIA ITP UM-HET3). R/qtl is ideal for populations that do not have complex kinship or admixture (<a href="https://www.ncbi.nlm.nih.gov/pubmed/12724300">PMID: 12724300</a>). Both R/qtl as implemented here, and R/qtl2 (<a href="https://www.ncbi.nlm.nih.gov/pubmed/30591514">PMID: 30591514</a>) are available as <span class="broken-link" href="https://kbroman.org/pages/software.html">R suites</span>.</dd>
+ <dt class="map-method-text">Pair Scan</dt>
+ <dd>Pair Scan using the R/qtl scantwo function.</dd>
{% elif mapping_method == "QTLReaper" %}
<dt class="map-method-text">Haley-Knott Regression</dt>
<dd>Fast linear mapping method (<a href="https://www.ncbi.nlm.nih.gov/pubmed/16718932">PMID 16718932</a>) works well with F2 intercrosses and backcrosses, but that is not recommended for complex or admixed populations (e.g., GWAS or heterogeneous stock studies) or for advanced intercrosses, recombinant inbred families, or diallel crosses. Interactive plots in GeneNetwork have relied on the fast HK mapping for two decades and we still use this method for mapping omics data sets and computing genome-wide permutation threshold (<a href="https://github.com/pjotrp/QTLReaper">QTL Reaper code</a>).</dd>
diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py
index 59dba309..b2cf95fb 100644
--- a/wqflask/wqflask/views.py
+++ b/wqflask/wqflask/views.py
@@ -808,8 +808,8 @@ def mapping_results_page():
'showGenes',
'viewLegend',
'haplotypeAnalystCheck',
- 'mapmethod_rqtl_geno',
- 'mapmodel_rqtl_geno',
+ 'mapmethod_rqtl',
+ 'mapmodel_rqtl',
'temp_trait',
'n_samples',
'transform'
@@ -846,23 +846,15 @@ def mapping_results_page():
rendered_template = render_template("mapping_error.html")
return rendered_template
- template_vars.js_data = json.dumps(template_vars.js_data,
- default=json_default_handler,
- indent=" ")
+ if not template_vars.pair_scan:
+ template_vars.js_data = json.dumps(template_vars.js_data,
+ default=json_default_handler,
+ indent=" ")
result = template_vars.__dict__
if result['pair_scan']:
with Bench("Rendering template"):
- img_path = result['pair_scan_filename']
- logger.info("img_path:", img_path)
- initial_start_vars = request.form
- logger.info("initial_start_vars:", initial_start_vars)
- imgfile = open(TEMPDIR + img_path, 'rb')
- imgdata = imgfile.read()
- imgB64 = base64.b64encode(imgdata)
- bytesarray = array.array('B', imgB64)
- result['pair_scan_array'] = bytesarray
rendered_template = render_template(
"pair_scan_results.html", **result)
else: