diff options
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 34b10fc5..65896e06 100644 --- a/wqflask/wqflask/marker_regression/rqtl_mapping.py +++ b/wqflask/wqflask/marker_regression/rqtl_mapping.py @@ -17,7 +17,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) @@ -35,6 +36,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 do_control == "true" and control_marker: post_data["control"] = control_marker 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 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 23b4e07a..be3d9238 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -790,8 +790,8 @@ def mapping_results_page(): 'showGenes', 'viewLegend', 'haplotypeAnalystCheck', - 'mapmethod_rqtl_geno', - 'mapmodel_rqtl_geno', + 'mapmethod_rqtl', + 'mapmodel_rqtl', 'temp_trait', 'n_samples', 'transform' @@ -828,23 +828,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: |