diff options
7 files changed, 156 insertions, 25 deletions
diff --git a/wqflask/wqflask/api/router.py b/wqflask/wqflask/api/router.py index 845873a0..4ecd6699 100644 --- a/wqflask/wqflask/api/router.py +++ b/wqflask/wqflask/api/router.py @@ -290,6 +290,106 @@ def get_dataset_info(dataset_name, group_name = None, file_format="json"): else: return return_error(code=204, source=request.url_rule.rule, title="No Results", details="") +@app.route("/api/v_{}/traits/<path:dataset_name>".format(version), methods=('GET',)) +@app.route("/api/v_{}/traits/<path:dataset_name>.<path:file_format>".format(version), methods=('GET',)) +def fetch_traits(dataset_name, file_format = "csv"): + trait_ids, _trait_names, data_type, dataset_id = get_dataset_trait_ids(dataset_name) + if ('ids_only' in request.args) and (len(trait_ids) > 0): + if file_format == "json": + filename = dataset_name + "_trait_ids.json" + return flask.jsonify(trait_ids) + else: + filename = dataset_name + "_trait_ids.csv" + + si = StringIO.StringIO() + csv_writer = csv.writer(si) + csv_writer.writerows([[trait_id] for trait_id in trait_ids]) + output = make_response(si.getvalue()) + output.headers["Content-Disposition"] = "attachment; filename=" + filename + output.headers["Content-type"] = "text/csv" + return output + else: + if len(trait_ids) > 0: + if data_type == "ProbeSet": + query = """ + SELECT + ProbeSet.Id, ProbeSet.Name, ProbeSet.Symbol, ProbeSet.description, ProbeSet.Chr, ProbeSet.Mb, ProbeSet.alias, + ProbeSetXRef.mean, ProbeSetXRef.se, ProbeSetXRef.Locus, ProbeSetXRef.LRS, ProbeSetXRef.pValue, ProbeSetXRef.additive, ProbeSetXRef.h2 + FROM + ProbeSet, ProbeSetXRef + WHERE + ProbeSetXRef.ProbeSetFreezeId = '{0}' AND + ProbeSetXRef.ProbeSetId = ProbeSet.Id + ORDER BY + ProbeSet.Id + """ + + field_list = ["Id", "Name", "Symbol", "Description", "Chr", "Mb", "Aliases", "Mean", "SE", "Locus", "LRS", "P-Value", "Additive", "h2"] + elif data_type == "Geno": + query = """ + SELECT + Geno.Id, Geno.Name, Geno.Marker_Name, Geno.Chr, Geno.Mb, Geno.Sequence, Geno.Source + FROM + Geno, GenoXRef + WHERE + GenoXRef.GenoFreezeId = '{0}' AND + GenoXRef.GenoId = Geno.Id + ORDER BY + Geno.Id + """ + + field_list = ["Id", "Name", "Marker_Name", "Chr", "Mb", "Sequence", "Source"] + else: + query = """ + SELECT + PublishXRef.Id, PublishXRef.PhenotypeId, PublishXRef.PublicationId, PublishXRef.Locus, PublishXRef.LRS, PublishXRef.additive, PublishXRef.Sequence + FROM + PublishXRef + WHERE + PublishXRef.InbredSetId = {0} + ORDER BY + PublishXRef.Id + """ + + field_list = ["Id", "PhenotypeId", "PublicationId", "Locus", "LRS", "Additive", "Sequence"] + + if file_format == "json": + filename = dataset_name + "_traits.json" + + final_query = query.format(dataset_id) + + result_list = [] + for result in g.db.execute(final_query).fetchall(): + trait_dict = {} + for i, field in enumerate(field_list): + if result[i]: + trait_dict[field] = result[i] + result_list.append(trait_dict) + + return flask.jsonify(result_list) + elif file_format == "csv": + filename = dataset_name + "_traits.csv" + + results_list = [] + header_list = [] + header_list += field_list + results_list.append(header_list) + + final_query = query.format(dataset_id) + for result in g.db.execute(final_query).fetchall(): + results_list.append(result) + + si = StringIO.StringIO() + csv_writer = csv.writer(si) + csv_writer.writerows(results_list) + output = make_response(si.getvalue()) + output.headers["Content-Disposition"] = "attachment; filename=" + filename + output.headers["Content-type"] = "text/csv" + return output + else: + return return_error(code=400, source=request.url_rule.rule, title="Invalid Output Format", details="Current formats available are JSON and CSV, with CSV as default") + else: + return return_error(code=204, source=request.url_rule.rule, title="No Results", details="") @app.route("/api/v_{}/sample_data/<path:dataset_name>".format(version)) @app.route("/api/v_{}/sample_data/<path:dataset_name>.<path:file_format>".format(version)) @@ -528,8 +628,6 @@ def get_trait_info(dataset_name, trait_name, file_format = "json"): PublishXRef.Id = '{0}' AND PublishXRef.InbredSetId = '{1}' """.format(trait_name, group_id) - - logger.debug("QUERY:", pheno_query) pheno_results = g.db.execute(pheno_query) @@ -612,13 +710,6 @@ def get_genotypes(group_name, file_format="csv"): return output -@app.route("/api/v_{}/traits/<path:dataset_name>".format(version), methods=('GET',)) -@app.route("/api/v_{}/traits/<path:dataset_name>.<path:file_format>".format(version), methods=('GET',)) -def get_traits(dataset_name, file_format = "json"): - #ZS: Need to check about the "start" and "stop" stuff since it seems to just limit the number of results to stop - start + 1 in Pjotr's elixir code - - NotImplemented - def return_error(code, source, title, details): json_ob = {"errors": [ { @@ -652,7 +743,7 @@ def get_dataset_trait_ids(dataset_name): dataset_id = results[0][2] return trait_ids, trait_names, data_type, dataset_id - elif "Publish" in dataset_name: + elif "Publish" in dataset_name or get_group_id(dataset_name): data_type = "Publish" dataset_name = dataset_name.replace("Publish", "") dataset_id = get_group_id(dataset_name) @@ -743,7 +834,10 @@ def get_group_id_from_dataset(dataset_name): result = g.db.execute(query).fetchone() - return result[0] + if len(result) > 0: + return result[0] + else: + return None def get_group_id(group_name): query = """ diff --git a/wqflask/wqflask/static/new/javascript/plotly_probability_plot.js b/wqflask/wqflask/static/new/javascript/plotly_probability_plot.js index 14b0e056..d52cb100 100644 --- a/wqflask/wqflask/static/new/javascript/plotly_probability_plot.js +++ b/wqflask/wqflask/static/new/javascript/plotly_probability_plot.js @@ -161,8 +161,14 @@ intercept_line['samples_all'] = [[first_x, last_x], [first_value, last_value]] } + if (Math.max(y_values['samples_all']) - Math.min(y_values['samples_all']) < 6){ + tick_digits = '.1f' + } else { + tick_digits = 'f' + } + var layout = { - title: 'Quantile-Quantile Plot<a href="https://en.wikipedia.org/wiki/Q-Q_plot"><sup>?</sup></a>', + title: js_data.trait_id, margin: { l: 65, r: 30, @@ -196,7 +202,8 @@ ticklen: 4, tickfont: { size: 16 - } + }, + tickformat: tick_digits }, hovermode: "closest" } diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 31f59a13..167fafcb 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -922,6 +922,11 @@ get_bar_range = function(sample_list){ } root.chart_range = get_bar_range(sample_lists[0]) +if (root.chart_range[1] - root.chart_range[0] < 4){ + tick_digits = '.1f' +} else { + tick_digits = 'f' +} if (js_data.num_values < 256) { bar_chart_width = 25 * get_sample_vals(sample_lists[0]).length @@ -930,6 +935,7 @@ if (js_data.num_values < 256) { bottom_margin = get_bar_bottom_margin(sample_lists[0]) root.bar_layout = { + title: js_data.trait_id, xaxis: { titlefont: { size: 16 @@ -941,6 +947,7 @@ if (js_data.num_values < 256) { } }, yaxis: { + title: js_data.unit_type, range: root.chart_range, titlefont: { size: 16 @@ -949,12 +956,13 @@ if (js_data.num_values < 256) { ticklen: 4, tickfont: { size: 16 - } + }, + tickformat: tick_digits }, width: bar_chart_width, height: 600, margin: { - l: 50, + l: 55, r: 30, t: 30, b: bottom_margin @@ -979,7 +987,7 @@ var hist_trace = { root.histogram_data = [hist_trace]; root.histogram_layout = { bargap: 0.05, - title: "Sample Values", + title: js_data.trait_id, xaxis: { autorange: true, title: "Value", @@ -1025,6 +1033,7 @@ $('.histogram_samples_group').change(function() { }); root.box_layout = { + title: js_data.trait_id, xaxis: { showline: true, tickfont: { @@ -1032,12 +1041,14 @@ root.box_layout = { }, }, yaxis: { + title: js_data.unit_type, autorange: true, showline: true, ticklen: 4, tickfont: { size: 16 - } + }, + tickformat: tick_digits }, margin: { l: 50, @@ -1136,7 +1147,7 @@ $('.box_plot_tab').click(function() { // Violin Plot root.violin_layout = { - title: "Violin Plot", + title: js_data.trait_id, xaxis: { showline: true, tickfont: { @@ -1144,12 +1155,14 @@ root.violin_layout = { } }, yaxis: { + title: js_data.unit_type, autorange: true, showline: true, ticklen: 4, tickfont: { size: 16 }, + tickformat: tick_digits, zeroline: false }, margin: { diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index 6ab7d635..378f91b1 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -271,7 +271,7 @@ 'data': null, 'orderDataType': "dom-checkbox", 'render': function(data, type, row, meta) { - return '<input type="checkbox" name="searchResult" style="min-height: 20px;" class="checkbox edit_sample_checkbox" value="" checked="checked">' + return '<input type="checkbox" name="searchResult" style="min-height: 20px;" class="checkbox edit_sample_checkbox" value="">' } }, { @@ -403,7 +403,7 @@ 'data': null, 'orderDataType': "dom-checkbox", 'render': function(data, type, row, meta) { - return '<input type="checkbox" name="searchResult" style="min-height: 20px;" class="checkbox edit_sample_checkbox" value="" checked="checked">' + return '<input type="checkbox" name="searchResult" style="min-height: 20px;" class="checkbox edit_sample_checkbox" value="">' } }, { @@ -491,7 +491,20 @@ } ); {% endif %} - $('#samples_primary, #samples_other').find("tr.outlier").css('background-color', 'yellow') + $('#samples_primary, #samples_other').find("tr.outlier").css('background-color', 'orange') + + $('.edit_sample_checkbox:checkbox').change(function() { + if ($(this).is(":checked")) { + if (!$(this).closest('tr').hasClass('selected')) { + $(this).closest('tr').addClass('selected') + } + } + else { + if ($(this).closest('tr').hasClass('selected')) { + $(this).closest('tr').removeClass('selected') + } + } + }); var slider = document.getElementById('p_range_slider'); noUiSlider.create(slider, { diff --git a/wqflask/wqflask/templates/show_trait_calculate_correlations.html b/wqflask/wqflask/templates/show_trait_calculate_correlations.html index ef233333..8ceec4fa 100644 --- a/wqflask/wqflask/templates/show_trait_calculate_correlations.html +++ b/wqflask/wqflask/templates/show_trait_calculate_correlations.html @@ -73,6 +73,7 @@ </select> </div> </div> + {% if dataset.type != "Publish" %} <div class="form-group"> <label class="col-xs-2 control-label">Min Expr</label> <div class="col-xs-3 controls"> @@ -89,6 +90,7 @@ <br> </div> </div> + {% endif %} <div class="form-group"> <label class="col-xs-2 control-label">Range</label> <div class="col-xs-5 controls"> diff --git a/wqflask/wqflask/templates/show_trait_edit_data.html b/wqflask/wqflask/templates/show_trait_edit_data.html index 667d557c..fec141dc 100644 --- a/wqflask/wqflask/templates/show_trait_edit_data.html +++ b/wqflask/wqflask/templates/show_trait_edit_data.html @@ -1,6 +1,6 @@ <div> <div style="padding-bottom: 10px;"> - <input type="button" class="btn btn-primary reset" value="Reset"> + <input type="button" class="btn btn-success reset" value="Reset"> <span class="input-append"> <input type="button" class="btn btn-default export" value="Export"> <select class="select optional span2 export_format"> diff --git a/wqflask/wqflask/templates/show_trait_transform_and_filter.html b/wqflask/wqflask/templates/show_trait_transform_and_filter.html index 94b3fda3..fbdebcd0 100644 --- a/wqflask/wqflask/templates/show_trait_transform_and_filter.html +++ b/wqflask/wqflask/templates/show_trait_transform_and_filter.html @@ -16,7 +16,7 @@ {{ sample_group_types['samples_other'] }} </option> </select> - <input type="button" id="block_by_index" class="btn" value="Block"> + <input type="button" id="block_by_index" class="btn btn-danger" value="Block"> </div> <div id="remove_samples_invalid" class="alert alert-error" style="display:none;"> Please check that your input is formatted correctly, e.g. <strong>3, 5-10, 12</strong> @@ -38,7 +38,7 @@ <div> <input type="button" id="hide_no_value" class="btn btn-default" value="Hide No Value"> <input type="button" id="block_outliers" class="btn btn-default" value="Block Outliers"> - <input type="button" class="btn btn-primary reset" value="Reset"> + <input type="button" class="btn btn-success reset" value="Reset"> <span class="input-append"> <input type="button" class="btn btn-default export" value="Export"> <select class="select optional span2 export_format"> @@ -48,9 +48,11 @@ </span> <br> <div style="margin-top:10px;"> - <input type="button" id="normalize" class="btn btn-default" value="Normalize"> + <input type="button" id="normalize" class="btn btn-success" value="Normalize"> <select id="norm_method" class="select optional span2"> + {% if negative_vals_exist == "false" %} <option value="log2">Log2</option> + {% endif %} <option value="zscore">Z-score</option> <option value="qnorm">Quantile</option> <option value="sqrt">Square Root</option> |