aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--wqflask/wqflask/collect.py31
-rw-r--r--wqflask/wqflask/database.py12
-rw-r--r--wqflask/wqflask/partial_correlations_views.py415
-rw-r--r--wqflask/wqflask/static/new/javascript/partial_correlations.js358
-rw-r--r--wqflask/wqflask/templates/collections/view.html27
-rw-r--r--wqflask/wqflask/templates/partial_correlations.html355
-rw-r--r--wqflask/wqflask/templates/partial_correlations/pcorrs_error.html54
-rw-r--r--wqflask/wqflask/templates/partial_correlations/pcorrs_poll_results.html15
-rw-r--r--wqflask/wqflask/templates/partial_correlations/pcorrs_results_presentation.html249
-rw-r--r--wqflask/wqflask/templates/partial_correlations/pcorrs_select_operations.html146
-rw-r--r--wqflask/wqflask/templates/tool_buttons.html7
11 files changed, 762 insertions, 907 deletions
diff --git a/wqflask/wqflask/collect.py b/wqflask/wqflask/collect.py
index 3475ae5d..815bb7c1 100644
--- a/wqflask/wqflask/collect.py
+++ b/wqflask/wqflask/collect.py
@@ -189,6 +189,30 @@ def delete_collection():
return redirect(url_for('list_collections'))
+def trait_info_str(trait):
+ """Provide a string representation for given trait"""
+ def __trait_desc(trt):
+ if trait.dataset.type == "Geno":
+ return f"Marker: {trt.name}"
+ return trt.description_display or "N/A"
+
+ def __symbol(trt):
+ return (trt.symbol or trt.abbreviation or "N/A")[:20]
+
+ def __lrs(trt):
+ return (
+ f"{float(trait.LRS_score_repr):0.3f}" if float(trait.LRS_score_repr) > 0
+ else f"{trait.LRS_score_repr}")
+
+ def __location(trt):
+ if hasattr(trt, "location_repr"):
+ return trt.location_repr
+ return None
+
+ return "{}|||{}|||{}|||{}|||{}|||{:0.3f}|||{}|||{}".format(
+ trait.name, trait.dataset.name, __trait_desc(trait), __symbol(trait),
+ __location(trait), trait.mean, __lrs(trait), trait.LRS_location_repr)
+
@app.route("/collections/view")
def view_collection():
params = request.args
@@ -227,9 +251,10 @@ def view_collection():
if "json" in params:
return json.dumps(json_version)
else:
- return render_template("collections/view.html",
- **collection_info
- )
+ return render_template(
+ "collections/view.html",
+ trait_info_str=trait_info_str,
+ **collection_info)
@app.route("/collections/change_name", methods=('POST',))
diff --git a/wqflask/wqflask/database.py b/wqflask/wqflask/database.py
index 11f8d287..e485bcf1 100644
--- a/wqflask/wqflask/database.py
+++ b/wqflask/wqflask/database.py
@@ -1,10 +1,13 @@
# Module to initialize sqlalchemy with flask
+import MySQLdb
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from utility.tools import SQL_URI
+from flask import current_app
+
engine = create_engine(SQL_URI, encoding="latin1")
@@ -16,3 +19,12 @@ Base.query = db_session.query_property()
# Initialise the db
Base.metadata.create_all(bind=engine)
+
+
+def database_connection():
+ """Returns a database connection"""
+ return MySQLdb.Connect(
+ db=current_app.config.get("DB_NAME"),
+ user=current_app.config.get("DB_USER"),
+ passwd=current_app.config.get("DB_PASS"),
+ host=current_app.config.get("DB_HOST"))
diff --git a/wqflask/wqflask/partial_correlations_views.py b/wqflask/wqflask/partial_correlations_views.py
index 6bc5efee..659b49e9 100644
--- a/wqflask/wqflask/partial_correlations_views.py
+++ b/wqflask/wqflask/partial_correlations_views.py
@@ -1,142 +1,31 @@
+import json
+import math
+import requests
+from functools import reduce
from typing import Union, Tuple
-import MySQLdb
-from gn3.db.traits import retrieve_trait_info
-from flask import flash, request, current_app, render_template
-from gn3.computations.partial_correlations import partial_correlations_entry
+from flask import (
+ flash,
+ request,
+ url_for,
+ redirect,
+ current_app,
+ render_template)
from wqflask import app
from utility.tools import GN_SERVER_URL
+from wqflask.database import database_connection
+from gn3.db.partial_correlations import traits_info
-def parse_trait(trait_str: str) -> Union[dict, None]:
- keys = (
- "name", "dataset", "symbol", "description", "location", "mean_expr",
- "max_lrs", "data_hmac")
- parts = tuple(part.strip() for part in trait_str.split(":::"))
- if len(parts) == len(keys):
- return dict(zip(keys, parts))
- return None
-
-def process_step_select_primary(
- primary_trait: dict, control_traits: Tuple[dict, ...],
- target_traits: Tuple[dict, ...],
- traits_list: Tuple[dict, ...], corr_method: str) -> Tuple[
- str, dict, Tuple[dict, ...], Tuple[dict, ...], Tuple[dict, ...],
- str]:
- if primary_trait is None:
- flash("You must select a primary trait", "alert-danger")
- return (
- "select-primary", primary_trait, control_traits, target_traits,
- traits_list, corr_method)
-
- return (
- "select-controls", primary_trait, control_traits, target_traits,
- tuple(
- trait for trait in traits_list
- if trait["data_hmac"] != primary_trait["data_hmac"]),
- corr_method)
-
-def process_step_select_controls(
- primary_trait: dict, control_traits: Tuple[dict, ...],
- target_traits: Tuple[dict, ...],
- traits_list: Tuple[dict, ...], corr_method: str) -> Tuple[
- str, dict, Tuple[dict, ...], Tuple[dict, ...], Tuple[dict, ...],
- str]:
- if len(control_traits) == 0 or len(control_traits) > 3:
- flash(
- ("You must select a minimum of one control trait, up to a maximum "
- "of three control traits."),
- "alert-danger")
- return (
- "select-controls", primary_trait, control_traits, target_traits,
- traits_list, corr_method)
-
- hmacs =(primary_trait["data_hmac"],) + tuple(
- trait["data_hmac"] for trait in control_traits)
- return (
- "select-corr-method", primary_trait, control_traits, target_traits,
- tuple(
- trait for trait in traits_list if trait["data_hmac"] not in hmacs),
- corr_method)
-
-def process_step_select_targets(
- primary_trait: dict, control_traits: Tuple[dict, ...],
- target_traits: Tuple[dict, ...],
- traits_list: Tuple[dict, ...], corr_method: str) -> Tuple[
- str, dict, Tuple[dict, ...], Tuple[dict, ...], Tuple[dict, ...],
- str]:
- if len(target_traits) == 0:
- flash(
- "You must select at least one target trait.", "alert-danger")
- return (
- "select-targets", primary_trait, control_traits, target_traits,
- traits_list, corr_method)
-
- hmacs =(primary_trait["data_hmac"],) + tuple(
- trait["data_hmac"] for trait in (control_traits + target_traits))
- return (
- "select-corr-method", primary_trait, control_traits, target_traits,
- tuple(
- trait for trait in traits_list if trait["data_hmac"] not in hmacs),
- corr_method)
-
-def process_step_select_corr_method(
- primary_trait: dict, control_traits: Tuple[dict, ...],
- target_traits: Tuple[dict, ...],
- traits_list: Tuple[dict, ...], corr_method: str) -> Tuple[
- str, dict, Tuple[dict, ...], Tuple[dict, ...], Tuple[dict, ...],
- str]:
- methods = (
- "genetic correlation, pearson's r",
- "genetic correlation, spearman's rho",
- "sgo literature correlation",
- "tissue correlation, pearson's r",
- "tissue correlation, spearman's rho")
- if corr_method.lower() not in methods:
- flash(
- "Selected method is unknown.", "alert-danger")
- return (
- "select-corr-method", primary_trait, control_traits, target_traits,
- traits_list, corr_method)
-
- hmacs =(primary_trait["data_hmac"],) + tuple(
- trait["data_hmac"] for trait in (control_traits + target_traits))
- return (
- "run-correlation", primary_trait, control_traits, target_traits,
- tuple(
- trait for trait in traits_list if trait["data_hmac"] not in hmacs),
- corr_method)
-
-def process_step(
- step: str, primary_trait: dict, control_traits: Tuple[dict, ...],
- target_traits: Tuple[dict, ...], traits_list: Tuple[dict, ...],
- corr_method: str) -> Tuple[
- str, dict, Tuple[dict, ...], Tuple[dict, ...], Tuple[dict, ...],
- str]:
- processor_functions = {
- # "select-traits": lambda arg: arg,
- "select-primary": process_step_select_primary,
- "select-controls": process_step_select_controls,
- "select-targets": process_step_select_targets,
- "select-corr-method": process_step_select_corr_method
- }
- return processor_functions[(step or "select-primary")](
- primary_trait, control_traits, target_traits, traits_list, corr_method)
-
-def sequence_of_traits(trait_strs) -> Tuple[dict, ...]:
- return tuple(filter(
- lambda trt: trt is not None,
- (parse_trait(tstr.strip()) for tstr in trait_strs)))
-
-def publish_target_dabases(conn, group, threshold):
+def publish_target_databases(conn, groups, threshold):
query = (
"SELECT PublishFreeze.FullName,PublishFreeze.Name "
"FROM PublishFreeze, InbredSet "
"WHERE PublishFreeze.InbredSetId = InbredSet.Id "
- "AND InbredSet.Name = %(group)s "
- "AND PublishFreeze.public > %(threshold)s")
+ f"AND InbredSet.Name IN ({', '.join(['%s'] * len(groups))}) "
+ "AND PublishFreeze.public > %s")
with conn.cursor() as cursor:
- cursor.execute(query, {"group": group, "threshold": threshold})
+ cursor.execute(query, tuple(groups) + (threshold,))
res = cursor.fetchall()
if res:
return tuple(
@@ -144,15 +33,15 @@ def publish_target_dabases(conn, group, threshold):
return tuple()
-def geno_target_databases(conn, group, threshold):
+def geno_target_databases(conn, groups, threshold):
query = (
"SELECT GenoFreeze.FullName,GenoFreeze.Name "
"FROM GenoFreeze, InbredSet "
"WHERE GenoFreeze.InbredSetId = InbredSet.Id "
- "AND InbredSet.Name = %(group)s "
- "AND GenoFreeze.public > %(threshold)s")
+ f"AND InbredSet.Name IN ({', '.join(['%s'] * len(groups))}) "
+ "AND GenoFreeze.public > %s")
with conn.cursor() as cursor:
- cursor.execute(query, {"group": group, "threshold": threshold})
+ cursor.execute(query, tuple(groups) + (threshold,))
res = cursor.fetchall()
if res:
return tuple(
@@ -160,27 +49,26 @@ def geno_target_databases(conn, group, threshold):
return tuple()
-def probeset_target_databases(conn, group, threshold):
+def probeset_target_databases(conn, groups, threshold):
query1 = "SELECT Id, Name FROM Tissue order by Name"
- query2 = (
- "SELECT ProbeFreeze.TissueId, ProbeSetFreeze.FullName, ProbeSetFreeze.Name "
- "FROM ProbeSetFreeze, ProbeFreeze, InbredSet "
- "WHERE ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id "
- "AND ProbeFreeze.TissueId IN %(tissue_ids)s "
- "AND ProbeSetFreeze.public > %(threshold)s "
- "AND ProbeFreeze.InbredSetId = InbredSet.Id "
- "AND InbredSet.Name like %(group)s "
- "ORDER BY ProbeSetFreeze.CreateTime desc, ProbeSetFreeze.AvgId")
with conn.cursor() as cursor:
cursor.execute(query1)
tissue_res = cursor.fetchall()
if tissue_res:
tissue_ids = tuple(row[0] for row in tissue_res)
- cursor.execute(
- query2,{
- "tissue_ids": tissue_ids, "group": f"{group}%%",
- "threshold": threshold
- })
+ groups_clauses = ["InbredSet.Name like %s"] * len(groups)
+ query2 = (
+ "SELECT ProbeFreeze.TissueId, ProbeSetFreeze.FullName, "
+ "ProbeSetFreeze.Name "
+ "FROM ProbeSetFreeze, ProbeFreeze, InbredSet "
+ "WHERE ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id "
+ "AND ProbeFreeze.TissueId IN "
+ f"({', '.join(['%s'] * len(tissue_ids))}) "
+ "AND ProbeSetFreeze.public > %s "
+ "AND ProbeFreeze.InbredSetId = InbredSet.Id "
+ f"AND ({' OR '.join(groups_clauses)}) "
+ "ORDER BY ProbeSetFreeze.CreateTime desc, ProbeSetFreeze.AvgId")
+ cursor.execute(query2, tissue_ids + (threshold,) + tuple(groups))
db_res = cursor.fetchall()
if db_res:
databases = tuple(
@@ -197,70 +85,201 @@ def probeset_target_databases(conn, group, threshold):
return tuple()
-def target_databases(conn, step, trait, threshold):
+def target_databases(conn, traits, threshold):
"""
Retrieves the names of possible target databases from the database.
"""
- if step != "select-corr-method":
- return None
-
- trait_info = retrieve_trait_info(
- threshold, f"{trait['dataset']}::{trait['name']}", conn)
- group = trait_info["group"]
+ trait_info = traits_info(
+ conn, threshold,
+ tuple(f"{trait['dataset']}::{trait['trait_name']}" for trait in traits))
+ groups = tuple(set(row["db"]["group"] for row in trait_info))
return (
- publish_target_dabases(conn, group, threshold) +
- geno_target_databases(conn, group, threshold) +
- probeset_target_databases(conn, group, threshold))
+ publish_target_databases(conn, groups, threshold) +
+ geno_target_databases(conn, groups, threshold) +
+ probeset_target_databases(conn, groups, threshold))
+
+def primary_error(args):
+ if len(args["primary_trait"]) == 0 or len(args["primary_trait"]) > 1:
+ return {
+ **args,
+ "errors": (args.get("errors", tuple()) +
+ ("You must provide one, and only one primary trait",))}
+ return args
+
+def controls_error(args):
+ if len(args["control_traits"]) == 0 or len(args["control_traits"]) > 3:
+ return {
+ **args,
+ "errors": (
+ args.get("errors", tuple()) +
+ (("You must provide at least one control trait, and a maximum "
+ "of three control traits"),))}
+ return args
+
+def target_db_error(args):
+ if not args["target_db"]:
+ return {
+ **args,
+ "errors": (
+ args.get("errors", tuple()) +
+ ("The target database must be provided",))}
+ return args
+
+def method_error(args):
+ methods = (
+ "genetic correlation, pearson's r",
+ "genetic correlation, spearman's rho",
+ "sgo literature correlation",
+ "tissue correlation, pearson's r",
+ "tissue correlation, spearman's rho")
+ if not args["method"] or args["method"].lower() not in methods:
+ return {
+ **args,
+ "errors": (
+ args.get("errors", tuple()) +
+ ("Invalid correlation method provided",))}
+ return args
-def pcorrelations(conn, values):
- if values["step"] != "run-correlation":
- return None
+def criteria_error(args):
+ try:
+ int(args.get("criteria", "invalid"))
+ return args
+ except ValueError:
+ return {
+ **args,
+ "errors": (
+ args.get("errors", tuple()) +
+ ("Invalid return number provided",))}
- def trait_fullname(trait):
- return f"{trait['dataset']}::{trait['name']}"
+def errors(args):
+ return criteria_error(method_error(target_db_error(controls_error(
+ primary_error(args)))))
- return partial_correlations_entry(
- conn, trait_fullname(values["primary_trait"]),
- tuple(trait_fullname(trait) for trait in values["control_traits"]),
- values["method"], values["criteria"], values["target_db"])
+def __classify_args(acc, item):
+ if item[1].startswith("primary_"):
+ return {
+ **acc,
+ "primary_trait": (acc.get("primary_trait", tuple()) + (item,))}
+ if item[1].startswith("controls_"):
+ return {**acc, "control_traits": (acc.get("control_traits", tuple()) + (item,))}
+ if item[0] == "target_db":
+ return {**acc, "target_db": item[1]}
+ if item[0] == "method":
+ return {**acc, "method": item[1]}
+ if item[0] == "criteria":
+ return {**acc, "criteria": item[1]}
+ return acc
+
+def __build_args(raw_form, traits):
+ args = reduce(__classify_args, raw_form.items(), {})
+ return {
+ **args,
+ "primary_trait": [
+ item for item in traits if item["trait_name"] in
+ (name[1][8:] for name in args["primary_trait"])],
+ "control_traits": [
+ item for item in traits if item["trait_name"] in
+ (name[1][9:] for name in args["control_traits"])]
+ }
+
+def parse_trait(trait_str):
+ return dict(zip(
+ ("trait_name", "dataset", "description", "symbol", "location", "mean",
+ "lrs", "lrs_location"),
+ trait_str.strip().split("|||")))
+
+def response_error_message(response):
+ error_messages = {
+ 404: ("We could not connect to the API server at this time. "
+ "Try again later."),
+ 500: ("The API server experienced a problem. We will be working on a "
+ "fix. Please try again later.")
+ }
+ return error_messages.get(
+ response.status_code,
+ "General API server error!!")
+
+def render_error(error_message):
+ return render_template(
+ "partial_correlations/pcorrs_error.html",
+ message = error_message)
+
+def handle_200_response(response):
+ if response["status"] == "success":
+ return redirect(
+ url_for(
+ "poll_partial_correlation_results",
+ command_id=response["results"]),
+ code=303)
+ return render_error(response["results"])
+
+def handle_response(response):
+ if response.status_code != 200:
+ return render_template(
+ "partial_correlations/pcorrs_error.html",
+ message = response_error_message(response))
+ return handle_200_response(response.json())
@app.route("/partial_correlations", methods=["POST"])
def partial_correlations():
form = request.form
- traits_list = tuple(filter(
- lambda trt: trt is not None,
- (parse_trait(tstr) for tstr in form.get("traits_list", "").split("|||"))))
+ traits = tuple(
+ parse_trait(trait) for trait in
+ form.get("trait_list").split(";;;"))
- args_dict = dict(zip(
- ("step", "primary_trait", "control_traits", "target_traits",
- "traits_list", "method"),
- process_step(
- form.get("step", None),
- parse_trait(form.get("primary_trait", "")),
- sequence_of_traits(
- form.getlist("control_traits[]") or
- form.get("control_traits", "").split("|||")),
- sequence_of_traits(
- form.getlist("target_traits[]") or
- form.get("target_traits", "").split("|||")),
- sequence_of_traits(form.get("traits_list", "").split("|||")),
- form.get("method"))))
+ if form.get("submit") == "Run Partial Correlations":
+ args = errors(__build_args(form, traits))
+ if len(args.get("errors", [])) == 0:
+ post_data = {
+ **args,
+ "primary_trait": args["primary_trait"][0]
+ }
+ return handle_response(requests.post(
+ url=f"{GN_SERVER_URL}api/correlation/partial",
+ json=json.dumps(post_data)))
- conn = MySQLdb.Connect(
- db=current_app.config.get("DB_NAME"),
- user=current_app.config.get("DB_USER"),
- passwd=current_app.config.get("DB_PASS"),
- host=current_app.config.get("DB_HOST"))
- target_dbs = target_databases(
- conn, args_dict["step"], args_dict["primary_trait"], 0)
+ for error in args["errors"]:
+ flash(error, "alert-danger")
- if args_dict["step"] == "run-correlation":
- args_dict = {
- **args_dict, "target_db": form.get("target_db"),
- "criteria": int(form.get("criteria", 500))}
+ with database_connection() as conn:
+ target_dbs = target_databases(conn, traits, threshold=0)
+ return render_template(
+ "partial_correlations/pcorrs_select_operations.html",
+ trait_list_str=form.get("trait_list"),
+ traits=traits,
+ target_dbs=target_dbs)
- corr_results = pcorrelations(conn, args_dict)
+def process_pcorrs_command_output(result):
+ if result["status"] == "success":
+ def __format_number(num):
+ if num is None or math.isnan(num):
+ return ""
+ if abs(num) <= 1.04E-4:
+ return f"{num:.2e}"
+ return f"{num:.5f}"
- return render_template(
- "partial_correlations.html", **args_dict, target_dbs=target_dbs,
- corr_results=corr_results, part_corr_url=f"{GN_SERVER_URL}api/correlation/partial")
+ return render_template(
+ "partial_correlations/pcorrs_results_presentation.html",
+ primary=result["results"]["primary_trait"],
+ controls=result["results"]["control_traits"],
+ correlations=result["results"]["correlations"],
+ dataset_type=result["results"]["dataset_type"],
+ method=result["results"]["method"],
+ format_number=__format_number)
+ if result["status"] == "error":
+ return render_error(
+ "The partial correlations computation failed with an error")
+
+@app.route("/partial_correlations/<command_id>", methods=["GET"])
+def poll_partial_correlation_results(command_id):
+ response = requests.get(
+ url=f"{GN_SERVER_URL}api/async_commands/state/{command_id}")
+ if response.status_code == 200:
+ data = response.json()
+ if data["status"] == "error":
+ return render_error(response["result"])
+ if data["status"] == "success":
+ return process_pcorrs_command_output(json.loads(data["result"]))
+ return render_template(
+ "partial_correlations/pcorrs_poll_results.html",
+ command_id = command_id)
diff --git a/wqflask/wqflask/static/new/javascript/partial_correlations.js b/wqflask/wqflask/static/new/javascript/partial_correlations.js
index 3bf2acc4..5de1204c 100644
--- a/wqflask/wqflask/static/new/javascript/partial_correlations.js
+++ b/wqflask/wqflask/static/new/javascript/partial_correlations.js
@@ -1,336 +1,26 @@
-/**
- * This is, hopefully, a short-term stop-gap measure to get the system working
- * and to get some feedback, even as better optimisation is done in the
- * background to get better response/performance for the partial correlation
- * computations
- */
-
-function key_value(keys, values) {
- if(!(keys.length == values.length)) {
- Error("The 'keys' and 'values' objects MUST be the same length");
- return null;
- }
- return values.reduce(function(accumulator, item, index) {
- accumulator[keys[index]] = item;
- return accumulator;
- }, {});
-}
-
-function trait(trait_str) {
- return key_value(
- ["name", "dataset", "symbol", "description", "location", "mean_expr",
- "max_lrs", "data_hmac"],
- trait_str.split(":::"));
-}
-
-function primary_trait() {
- trait_string = document.querySelector(
- "#partial-correlations-form input[name=primary_trait]").value;
- return trait(trait_string);
-}
-
-function control_traits() {
- return document.querySelector(
- "#partial-correlations-form input[name=control_traits]").value.split(
- "|||").map(trait).filter(trait => !(trait === null));
-}
-
-function correlation_method() {
- return document.querySelector(
- "#partial-correlations-form select[name=method]").value;
-}
-
-function criteria() {
- return document.querySelector(
- "#partial-correlations-form select[name=criteria]").value;
-}
-
-function target_db() {
- return document.querySelector(
- "#partial-correlations-form select[name=target_db]").value;
-}
-
-function partial_corr_request_data() {
- return {
- "primary_trait": primary_trait(),
- "control_traits": control_traits(),
- "method": correlation_method(),
- "criteria": criteria(),
- "target_db": target_db()
- }
-}
-
-function rho_or_r(method) {
- if (method === "spearman") {
- return "rho";
- }
- return "r";
-}
-
-function format_number(num) {
- if(num === null) {
- return NaN;
- }
- if(Math.abs(num) <= 1.04e-4) {
- return num.toExponential(2);
- }
- return num.toFixed(5);
-}
-
-function display_publish_results(primary, controls, correlations, method) {
- table = document.getElementById("part-corr-results-publish");
- table.setAttribute("style", "display: block;");
- table_body = document.querySelector("#part-corr-results-publish tbody");
- template_row = document.querySelector(
- "#part-corr-results-publish tr.template-publish-results-row");
- correlations.forEach(function(item, index, arr) {
- new_row = template_row.cloneNode(true);
- new_row.setAttribute("class", "results-row");
- new_row.querySelector(
- 'td[data-column-heading="Record"]').innerHTML = item["trait_name"];
- new_row.querySelector(
- 'td[data-column-heading="Phenotype"]').innerHTML = (
- item["post_publication_description"]);
- new_row.querySelector(
- 'td[data-column-heading="Authors"]').innerHTML = item["authors"];
- new_row.querySelector(
- 'td[data-column-heading="Year"]').innerHTML = item["year"];
- new_row.querySelector(
- 'td[data-column-heading="N"]').innerHTML = item["noverlap"];
- new_row.querySelector(
- `td[data-column-heading="Partial ${rho_or_r(method)}"]`
- ).innerHTML = format_number(item["partial_corr"]);
- new_row.querySelector(
- `td[data-column-heading="p(partial ${rho_or_r(method)})"]`
- ).innerHTML = format_number(item["partial_corr_p_value"]);
- new_row.querySelector(
- `td[data-column-heading="${rho_or_r(method)}"]`
- ).innerHTML = format_number(item["corr"]);
- new_row.querySelector(
- `td[data-column-heading="p(${rho_or_r(method)})"]`
- ).innerHTML = format_number(item["corr_p_value"]);
- new_row.querySelector(
- `td[data-column-heading="delta ${rho_or_r(method)}"]`
- ).innerHTML = format_number(item["delta"]);
- table_body.appendChild(new_row);
- });
- table_body.removeChild(template_row);
-}
-
-function display_geno_results(primary, controls, correlations, method) {
- table = document.getElementById("part-corr-results-geno");
- table.setAttribute("style", "display: block;");
- table_body = document.querySelector("#part-corr-results-geno tbody");
- template_row = document.querySelector(
- "#part-corr-results-geno tr.template-geno-results-row");
- correlations.forEach(function(item, index, arr) {
- new_row = template_row.cloneNode(true);
- new_row.setAttribute("class", "results-row");
- new_row.querySelector(
- 'td[data-column-heading="Locus"]').innerHTML = item["trait_name"];
- new_row.querySelector(
- 'td[data-column-heading="Chr"]').innerHTML = item["chr"];
- new_row.querySelector(
- 'td[data-column-heading="Megabase"]').innerHTML = item["mb"];
- new_row.querySelector(
- 'td[data-column-heading="N"]').innerHTML = item["noverlap"];
- new_row.querySelector(
- `td[data-column-heading="Partial ${rho_or_r(method)}"]`
- ).innerHTML = format_number(item["partial_corr"]);
- new_row.querySelector(
- `td[data-column-heading="p(partial ${rho_or_r(method)})"]`
- ).innerHTML = format_number(item["partial_corr_p_value"]);
- new_row.querySelector(
- `td[data-column-heading="${rho_or_r(method)}"]`
- ).innerHTML = format_number(item["corr"]);
- new_row.querySelector(
- `td[data-column-heading="p(${rho_or_r(method)})"]`
- ).innerHTML = format_number(item["corr_p_value"]);
- new_row.querySelector(
- `td[data-column-heading="delta ${rho_or_r(method)}"]`
- ).innerHTML = format_number(item["delta"]);
- table_body.appendChild(new_row);
- });
- table_body.removeChild(template_row);
-}
-
-function display_probeset_results(primary, controls, correlations, method) {
- table = document.getElementById("part-corr-results-probeset");
- table.setAttribute("style", "display: block;");
- table_body = document.querySelector("#part-corr-results-probeset tbody");
- template_row = document.querySelector(
- "#part-corr-results-probeset tr.template-probeset-results-row");
- correlations.forEach(function(item, index, arr) {
- new_row = template_row.cloneNode(true);
- new_row.setAttribute("class", "results-row");
- new_row.querySelector(
- 'td[data-column-heading="Record"]').innerHTML = item["trait_name"];
- new_row.querySelector(
- 'td[data-column-heading="Gene ID"]').innerHTML = item["geneid"];
- new_row.querySelector(
- 'td[data-column-heading="Homologene ID"]').innerHTML = item["homologeneid"];
- new_row.querySelector(
- 'td[data-column-heading="Symbol"]').innerHTML = item["symbol"];
- new_row.querySelector(
- 'td[data-column-heading="Description"]').innerHTML = item["description"];
- new_row.querySelector(
- 'td[data-column-heading="Chr"]').innerHTML = item["chr"];
- new_row.querySelector(
- 'td[data-column-heading="Megabase"]').innerHTML = item["mb"];
- new_row.querySelector(
- 'td[data-column-heading="Mean Expr"]').innerHTML = item["mean_expr"];
- new_row.querySelector(
- 'td[data-column-heading="N"]').innerHTML = item["noverlap"];
- new_row.querySelector(
- `td[data-column-heading="Sample Partial ${rho_or_r(method)}"]`
- ).innerHTML = format_number(item["partial_corr"] || NaN);
- new_row.querySelector(
- `td[data-column-heading="Sample p(partial ${rho_or_r(method)})"]`
- ).innerHTML = format_number(item["partial_corr_p_value"] || NaN);
- new_row.querySelector(
- `td[data-column-heading="Sample ${rho_or_r(method)}"]`
- ).innerHTML = format_number(item["corr"] || NaN);
- new_row.querySelector(
- `td[data-column-heading="Sample p(${rho_or_r(method)})"]`
- ).innerHTML = format_number(item["corr_p_value"] || NaN);
- new_row.querySelector(
- `td[data-column-heading="delta ${rho_or_r(method)}"]`
- ).innerHTML = format_number(item["delta"] || NaN);
- new_row.querySelector(
- `td[data-column-heading="Lit Corr"]`
- ).innerHTML = format_number(item["l_corr"] || NaN);
- new_row.querySelector(
- `td[data-column-heading="Tissue ${rho_or_r(method)}"]`
- ).innerHTML = format_number(item["tissue_corr"] || NaN);
- new_row.querySelector(
- `td[data-column-heading="Tissue p(${rho_or_r(method)})"]`
- ).innerHTML = format_number(item["tissue_p_value"] || NaN);
- table_body.appendChild(new_row);
- });
- template_row.setAttribute("display", "none");
- /*table_body.removeChild(template_row);*/
-}
-
-function replace_r_with_rho(method) {
- /* Mostly utility: Replace `r` with `rho` in the appropriate places */
- pattern = /\br\b/;
- if(method == "spearman") {
- results_div = document.getElementById("partial-correlation-results");
- headers = results_div.getElementsByTagName("th");
- for(let header of headers) {
- header.innerHTML = header.innerHTML.replace(pattern, "rho");
- }
-
- cells = results_div.getElementsByTagName("td");
- for(let cell of cells) {
- cell.setAttribute(
- "data-column-heading",
- cell.getAttribute(
- "data-column-heading").replace(pattern, "rho"));
- }
+function selected_traits() {
+ traits = $("#trait_table input:checked").map(function() {
+ return $(this).attr("data-trait-info");
+ }).get();
+ if (traits.length == 0){
+ num_traits = $("#trait_table input").length
+ if (num_traits <= 100){
+ traits = $("#trait_table input").map(function() {
+ return $(this).attr("data-trait-info");
+ }).get();
+ }
}
-}
-
-function display_partial_corr_results(data, status, xhr) {
- progress_indicator = document.getElementById(
- "partial-correlations-progress-indicator").style.display = "none";
- console.log(data);
-
- replace_r_with_rho(data["results"]["method"]);
-
- display_functions = {
- "Publish": display_publish_results,
- "Geno": display_geno_results,
- "ProbeSet": display_probeset_results
- }
-
- display_functions[data["results"]["dataset_type"]](
- data["results"]["primary_traits"],
- data["results"]["control_traits"],
- data["results"]["correlations"],
- data["results"]["method"]);
-
- initializePcorrTable(data["results"]["dataset_type"]);
-}
-
-function display_partial_corr_error(xhr, status, error) {
- document.getElementById(
- "partial-correlations-progress-indicator").style.display = "none";
- error_element = document.getElementById("part-corr-error");
- panel = document.createElement("div");
- panel.setAttribute("class", "panel panel-danger");
- error_element.appendChild(panel);
-
- panel_header = document.createElement("div");
- panel_header.setAttribute("class", "panel-heading");
- panel_header.textContent = "Error: " + xhr.status;
- panel.appendChild(panel_header);
-
- panel_body = document.createElement("div");
- panel_body.setAttribute("class", "panel-body");
- panel_body.textContent = xhr.statusText;
- panel.appendChild(panel_body);
- console.log(xhr)
-}
-
-function send_data_and_process_results(
- remote_url, request_data, success_fn, error_fn, indicator_id) {
- document.getElementById(indicator_id).style.display = "block";
- $.ajax({
- type: "POST",
- url: remote_url,
- contentType: "application/json",
- data: JSON.stringify(request_data),
- dataType: "JSON",
- success: success_fn,
- error: error_fn
- });
-}
-
-function initializePcorrTable(dataType){
- tableId = "part-corr-results-" + dataType.toLowerCase();
- if (dataType == "Publish") {
- orderCol = 8;
- } else if (dataType == "ProbeSet") {
- orderCol = 12;
- } else {
- orderCol = 7;
- }
-
- $('#' + tableId).dataTable( {
- 'drawCallback': function( settings ) {
- $('#' + tableId + ' tr').off().on("click", function(event) {
- if (event.target.type !== 'checkbox' && event.target.tagName.toLowerCase() !== 'a') {
- var obj =$(this).find('input');
- obj.prop('checked', !obj.is(':checked'));
- }
- if ($(this).hasClass("selected") && event.target.tagName.toLowerCase() !== 'a'){
- $(this).removeClass("selected")
- } else if (event.target.tagName.toLowerCase() !== 'a') {
- $(this).addClass("selected")
- }
- });
- },
- "order": [[orderCol, "asc" ]],
- "sDom": "itir",
- "iDisplayLength": -1,
- "autoWidth": false,
- "bDeferRender": true,
- "bSortClasses": false,
- "paging": false
- } );
-}
-
-$("#partial-correlations-form").submit(function(e) {
- e.preventDefault();
-});
-
-$("#run-partial-corr-button").click(function(evt) {
- send_data_and_process_results(
- document.getElementById(
- "run-partial-corr-button").getAttribute("data-url"),
- partial_corr_request_data(),
- display_partial_corr_results,
- display_partial_corr_error,
- "partial-correlations-progress-indicator");
+ return traits
+}
+
+$("#partial-correlations").on("click", function() {
+ // Submit the form to the `partial_correlations` endpoint
+ url = $(this).data("url")
+ traits = selected_traits();
+ $("#trait_list").val(traits.reduce(function(acc, str) {
+ return acc.concat(";;;".concat(str));
+ }));
+ $("input[name=tool_used]").val("Partial Correlation")
+ $("input[name=form_url]").val(url)
+ return submit_special(url)
})
diff --git a/wqflask/wqflask/templates/collections/view.html b/wqflask/wqflask/templates/collections/view.html
index f896471a..6f1a9680 100644
--- a/wqflask/wqflask/templates/collections/view.html
+++ b/wqflask/wqflask/templates/collections/view.html
@@ -67,22 +67,6 @@
</div>
</form>
&nbsp;
- <form id="partial-correlations-form"
- method="POST"
- action="{{url_for('partial_correlations')}}">
- <input type="hidden"
- id="collection_uuid"
- value="{{uc.uc_id}}" />
- <input type="hidden"
- name="traits_list"
- value="{% for this_trait in trait_obs %}{{ this_trait.name }}:::{{ this_trait.dataset.name }}:::{{this_trait.symbol}}:::{{this_trait.description_display}}:::{{this_trait.location_repr}}:::{{this_trait.mean}}:::{{this_trait['LRS_location_repr']}}:::{{data_hmac('{}:{}'.format(this_trait.name, this_trait.dataset.name))}}|||{% endfor %}" />
- <button id="run-partial-correlations"
- class="btn btn-primary"
- title="Run partial correlations"
- type="submit" style="margin-top: 10px;">
- Partial Correlations
- </button>
- </form>
</div>
<div>
@@ -128,7 +112,13 @@
<tbody>
{% for this_trait in trait_obs %}
<TR id="trait:{{ this_trait.name }}:{{ this_trait.dataset.name }}">
- <TD align="center" style="padding: 0px;"><INPUT TYPE="checkbox" NAME="searchResult" class="checkbox trait_checkbox" VALUE="{{ data_hmac('{}:{}'.format(this_trait.name, this_trait.dataset.name)) }}"></TD>
+ <TD align="center" style="padding: 0px;">
+ <input type="checkbox"
+ name="searchResult"
+ class="checkbox trait_checkbox"
+ value="{{data_hmac('{}:{}'.format(this_trait.name, this_trait.dataset.name))}}"
+ data-trait-info="{{trait_info_str(this_trait)}}">
+ </TD>
<TD data-export="{{ loop.index }}" align="right">{{ loop.index }}</TD>
<TD title="{{ this_trait.dataset.fullname }}" data-export="{{ this_trait.dataset.fullname }}">{{ this_trait.dataset.fullname }}</TD>
<TD data-export="{{ this_trait.name }}">
@@ -193,6 +183,9 @@
<script type="text/javascript" src="{{ url_for('js', filename='plotly/plotly.min.js') }}"></script>
+ <script type="text/javascript"
+ src="/static/new/javascript/partial_correlations.js"></script>
+
<script language="javascript" type="text/javascript">
$(document).ready( function () {
diff --git a/wqflask/wqflask/templates/partial_correlations.html b/wqflask/wqflask/templates/partial_correlations.html
deleted file mode 100644
index 0cf09afc..00000000
--- a/wqflask/wqflask/templates/partial_correlations.html
+++ /dev/null
@@ -1,355 +0,0 @@
-{%extends "base.html"%}
-
-{%block title%}Partial Correlations:{%endblock%}
-
-{%block css%}
-<link rel="stylesheet" type="text/css" href="/static/new/css/partial_correlations.css" />
-<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
-<link rel="stylesheet" type="text/css" href="/static/new/css/trait_list.css" />
-<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
-{%endblock%}
-
-{%block content%}
-<div class="container">
-<form id="partial-correlations-form"
- method="POST"
- action="{{url_for('partial_correlations')}}">
-
- <div id="main-form">
- {%with messages = get_flashed_messages(with_categories=true)%}
- {%if messages:%}
- <ul class=flashes>
- {%for category, message in messages:%}
- <li class="{{category}}">{{message}}</li>
- {%endfor%}
- </ul>
- {%endif%}
- {%endwith%}
-
- {%if step == "select-primary":%}
- <p>Please select the primary trait (X)</p>
- {%include "with-trait-items.html" %}
-
- <button type="submit" class="btn btn-primary">
- Next: Select Control Traits
- </button>
- {%endif%}
-
-
-
- {%if step == "select-controls":%}
-
- <p>Select a maximum of three (3) control traits (Z)</p>
- {%include "with-trait-items.html" %}
-
- <button type="submit" class="btn btn-primary">
- Next: Select Target
- </button>
- {%endif%}
-
-
-
- {%if step == "select-targets":%}
- <p>Select at least one target trait (Y)</p>
- {%for trait in traits_list:%}
- <div class="label-element-combo">
- <input type="checkbox"
- name="target_traits[]"
- value="{{trait['name']}}:::{{trait['dataset']}}:::{{trait['symbol']}}:::{{trait['description']}}:::{{trait['data_hmac']}}"
- checked="checked"
- id="trait_{{trait['data_hmac']}}" />
- <label for="trait_{{trait['data_hmac']}}">
- {{trait["name"]}} - {{trait["symbol"]}} - {{trait["description"]}}
- </label>
- </div>
- {%endfor%}
- <button type="submit" class="btn btn-primary">
- Next: Select Correlation Method
- </button>
- {%endif%}
-
-
-
- {%if step == "select-corr-method":%}
- <div class="label-element-combo">
- <label for="target-db-input">Choose Database</label>
- <select id="target-db-input" required="required" name="target_db">
- {%if target_dbs:%}
- {%for item in target_dbs:%}
- {%if "description" in item.keys():%}
- <option value="{{item['value']}}">{{item['description']}}</option>
- {%else:%}
- {%for group, opts in item.items()%}
- {%if opts | length > 0:%}
- <optgroup label="{{group}} ------">
- {%for item2 in opts:%}
- <option value="{{item2['value']}}">{{item2['description']}}</option>
- {%endfor%}
- </optgroup>
- {%endif%}
- {%endfor%}
- {%endif%}
- {%endfor%}
- {%endif%}
- </select>
- </div>
-
- <div class="label-element-combo">
- <label for="corr-method-input">Compute</label>
- <select id="corr-method-input" required="required" name="method">
- <option value="Genetic Correlation, Pearson's r">
- Genetic Correlation, Pearson's r</option>
- <option value="Genetic Correlation, Spearman's rho">
- Genetic Correlation, Spearman's rho</option>
- <option value="SGO Literature Correlation">
- SGO Literature Correlation</option>
- <option value="Tissue Correlation, Pearson's r">
- Tissue Correlation, Pearson's r</option>
- <option value="Tissue Correlation, Spearman's rho">
- Tissue Correlation, Spearman's rho</option>
- </select>
- </div>
-
- <div class="label-element-combo">
- <label for="criteria-input">Return</label>
- <select id="criteria-input" required="required" name="criteria" size="1">
- <option value="100">top 100</option>
- <option value="200">top 200</option>
- <option value="500" selected="selected">top 500</option>
- <option value="1000">top 1000</option>
- <option value="2000">top 2000</option>
- <option value="5000">top 5000</option>
- <option value="10000">top 10000</option>
- <option value="15000">top 15000</option>
- <option value="20000">top 20000</option>
- </select>
- </div>
-
- <button id="run-partial-corr-button"
- type="submit"
- class="btn btn-primary"
- data-url="{{part_corr_url}}">
- Run Partial Correlation
- </button>
- {%endif%}
-
- {%if step == "run-correlation":%}
- <input type="hidden" name="selected_method" value="{{method}}" />
- <input type="hidden" name="selected_target_db" value="{{target_db}}" />
- <input type="hidden" name="selected_criteria" value="{{criteria}}" />
-
- {{corr_results}}
- {%endif%}
- </div>
-
- <div id="form-display-area">
- <input type="hidden" name="step" id="step-indicator" value="{{step}}" />
- <input type="hidden"
- name="traits_list"
- value="{% for trait in traits_list %}{{trait['name']}}:::{{trait['dataset']}}:::{{trait['symbol']}}:::{{trait['description']}}:::{{trait['location']}}:::{{trait['mean_expr']}}:::{{trait['max_lrs']}}:::{{trait['data_hmac']}}|||{% endfor %}">
-
- {%if primary_trait:%}
- <input type="hidden"
- name="primary_trait"
- value="{{primary_trait['name']}}:::{{primary_trait['dataset']}}:::{{primary_trait['symbol']}}:::{{primary_trait['description']}}:::{{primary_trait['location']}}:::{{primary_trait['mean_expr']}}:::{{primary_trait['max_lrs']}}:::{{primary_trait['data_hmac']}}"
- id="trait_{{primary_trait['data_hmac']}}" />
-
- <div class="panel panel-info">
- <div class="panel-heading">Primary Trait (X)</div>
- <div class="panel-body">
- {{primary_trait["name"]}}&nbsp;-&nbsp;
- {{primary_trait["symbol"]}}&nbsp;-&nbsp;{{primary_trait["description"]}}
- </div>
- </div>
- {%endif%}
-
- {%if target_traits:%}
- <input type="hidden"
- name="target_traits"
- value="{%for trait in target_traits:%}{{trait['name']}}:::{{trait['dataset']}}:::{{trait['symbol']}}:::{{trait['description']}}:::{{trait['location']}}:::{{trait['mean_expr']}}:::{{trait['max_lrs']}}:::{{trait['data_hmac']}}|||{%endfor%}" />
- <div class="panel panel-info">
- <div class="panel-heading">Target Traits (Y)</div>
- <div class="panel-body">
- <ul>
- {%for trait in target_traits:%}
- <li>
- {{trait["name"]}}&nbsp;-&nbsp;{{trait["symbol"]}}&nbsp;-&nbsp;
- {{trait["description"]}}</li>
- {%endfor%}
- </ul>
- </div>
- </div>
- {%endif%}
-
- {%if control_traits:%}
- <input type="hidden"
- name="control_traits"
- value="{%for trait in control_traits:%}{{trait['name']}}:::{{trait['dataset']}}:::{{trait['symbol']}}:::{{trait['description']}}:::{{trait['location']}}:::{{trait['mean_expr']}}:::{{trait['max_lrs']}}:::{{trait['data_hmac']}}|||{%endfor%}" />
- <div class="panel panel-info">
- <div class="panel-heading">Control Traits (Z)</div>
- <div class="panel-body">
- <ul>
- {%for trait in control_traits:%}
- <li>
- {{trait["name"]}}&nbsp;-&nbsp;{{trait["symbol"]}}&nbsp;-&nbsp;
- {{trait["description"]}}</li>
- {%endfor%}
- </ul>
- </div>
- </div>
- {%endif%}
- </div>
-
-</form>
-
-<div id="partial-correlation-results">
- <span id="partial-correlations-progress-indicator"
- style="display: {%if step == 'run-correlation':%}block{%else:%}none{%endif%};">
- <img src="/static/gif/waitAnima2.gif">
- </span>
- <div id="part-corr-success">
- <table id="part-corr-results-publish" class="table-hover table-striped cell-border" style="display:none; float: left;">
- <thead>
- <tr>
- <th></th>
- <th>Index</th>
- <th>Record</th>
- <th>Phenotype</th>
- <th>Authors</th>
- <th>Year</th>
- <th>N</th>
- <th>Partial {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
- <th>p(partial {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%})</th>
- <th>{%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
- <th>p({%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%})</th>
- <th>delta {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
- </tr>
- </thead>
-
- <tbody>
- <tr class="template-publish-results-row">
- <td></td>
- <td data-column-heading="Index"></td>
- <td data-column-heading="Record"></td>
- <td data-column-heading="Phenotype"></td>
- <td data-column-heading="Authors"></td>
- <td data-column-heading="Year"></td>
- <td data-column-heading="N"></td>
- <td data-column-heading="Partial {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
- </td>
- <td data-column-heading="p(partial {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%})">
- </td>
- <td data-column-heading="{%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
- </td>
- <td data-column-heading="p({%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%})">
- </td>
- <td data-column-heading="delta {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
- </td>
- </tr>
- </tbody>
- </table>
-
- <table id="part-corr-results-geno" style="display:none;">
- <thead>
- <tr>
- <th></th>
- <th>Index</th>
- <th>Locus</th>
- <th>Chr</th>
- <th>Megabase</th>
- <th>N</th>
- <th>Partial {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
- <th>p(partial {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%})</th>
- <th>{%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
- <th>p({%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%})</th>
- <th>delta {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
- </tr>
- </thead>
-
- <tbody>
- <tr class="template-geno-results-row">
- <td></td>
- <td data-column-heading="Index"></td>
- <td data-column-heading="Locus"></td>
- <td data-column-heading="Chr"></td>
- <td data-column-heading="Megabase"></td>
- <td data-column-heading="N"></td>
- <td data-column-heading="Partial {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
- </td>
- <td data-column-heading="p(partial {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%})">
- </td>
- <td data-column-heading="{%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
- </td>
- <td data-column-heading="p({%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%})">
- </td>
- <td data-column-heading="delta {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
- </td>
- </tr>
- </tbody>
- </table>
-
- <table id="part-corr-results-probeset" style="display:none;">
- <thead>
- <tr>
- <th></th>
- <th>Index</th>
- <th>Record</th>
- <th>Gene ID</th>
- <th>Homologene ID</th>
- <th>Symbol</th>
- <th>Description</th>
- <th>Chr</th>
- <th>Megabase</th>
- <th>Mean Expr</th>
- <th>N</th>
- <th>Sample Partial {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
- <th>Sample p(partial {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%})</th>
- <th>Sample {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
- <th>Sample p({%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%})</th>
- <th>delta {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
- <th>Lit Corr</th>
- <th>Tissue {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
- <th>Tissue p({%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%})</th>
- </tr>
- </thead>
-
- <tbody>
- <tr class="template-probeset-results-row">
- <td></td>
- <td data-column-heading="Index"></td>
- <td data-column-heading="_"></td>
- <td data-column-heading="Record"></td>
- <td data-column-heading="Gene ID"></td>
- <td data-column-heading="Homologene ID"></td>
- <td data-column-heading="Symbol"></td>
- <td data-column-heading="Description"></td>
- <td data-column-heading="Chr"></td>
- <td data-column-heading="Megabase"></td>
- <td data-column-heading="Mean Expr"></td>
- <td data-column-heading="N"></td>
- <td data-column-heading="Sample Partial {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}"></td>
- <td data-column-heading="Sample p(partial {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%})"></td>
- <td data-column-heading="Sample {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}"></td>
- <td data-column-heading="Sample p({%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%})"></td>
- <td data-column-heading="delta {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}"></td>
- <td data-column-heading="Lit Corr"></td>
- <td data-column-heading="Tissue {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}"></td>
- <td data-column-heading="Tissue p({%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%})"></td>
- </tr>
- </tbody>
- </table>
- </div>
- <div id="part-corr-error">
- </div>
-</div>
-</div>
-{%endblock%}
-
-{%block js%}
-{%if step == "select-corr-method":%}
-<script type="text/javascript"
- src="/static/new/javascript/partial_correlations.js"></script>
-<script language="javascript" type="text/javascript"
- src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
-{%endif%}
-{%endblock%}
diff --git a/wqflask/wqflask/templates/partial_correlations/pcorrs_error.html b/wqflask/wqflask/templates/partial_correlations/pcorrs_error.html
new file mode 100644
index 00000000..36847f57
--- /dev/null
+++ b/wqflask/wqflask/templates/partial_correlations/pcorrs_error.html
@@ -0,0 +1,54 @@
+{% extends "base.html" %}
+{% block title %}Error: {{message}}{% endblock %}
+{% block content %}
+<!-- Start of body -->
+
+<div class="col-md-8">
+<div class="form-group has-error">
+ <div class="control-label" for="inputError1">
+
+ <img src="/static/gif/error/{{ error_image }}">
+
+ <h1>ERROR</h1>
+
+ <p>
+ This error is not what we wanted to see. Unfortunately errors
+ are part of all software systems and we need to resolve this
+ together.
+ </p>
+ <p>
+ <b>It is important to report this ERROR so we can fix it for everyone</b>.
+ </p>
+
+ <p>
+ Report to the GeneNetwork team by recording the steps you take
+ to reproduce this ERROR. Next to those steps, copy-paste below
+ stack trace, either as
+ a <a href="https://github.com/genenetwork/genenetwork2/issues/new">new
+ issue</a> or E-mail this full page to one of the developers
+ directly.
+ </p>
+ </div>
+
+ <p>
+ (GeneNetwork error: {{message[:128]}})
+ </p>
+
+ <p>
+ To check if this already a known issue, search the
+ <a href="https://github.com/genenetwork/genenetwork2/issues">issue
+ tracker</a>.
+ </p>
+
+ <a href="#Stack" class="btn btn-default" data-toggle="collapse">Toggle full stack trace</a>
+ <div id="Stack" class="collapse">
+ <pre>
+ GeneNetwork {{ version }} {% for line in stack %} {{ line }}
+ {% endfor %}
+ </pre>
+ </div>
+</div>
+</div>
+
+
+{% endblock %}
diff --git a/wqflask/wqflask/templates/partial_correlations/pcorrs_poll_results.html b/wqflask/wqflask/templates/partial_correlations/pcorrs_poll_results.html
new file mode 100644
index 00000000..47acc294
--- /dev/null
+++ b/wqflask/wqflask/templates/partial_correlations/pcorrs_poll_results.html
@@ -0,0 +1,15 @@
+{%extends "base.html"%}
+
+{%block title%}Partial Correlations:{%endblock%}
+
+{%block css%}
+<meta http-equiv="refresh"
+ content="10;URL=/partial_correlations/{{command_id}}">
+{%endblock%}
+
+{%block content%}
+
+<p>Computing partial correlations...</p>
+<img src="/static/gif/waitAnima2.gif"
+ alt="Image indicating computation of partial correlations is ongoing" />
+{%endblock%}
diff --git a/wqflask/wqflask/templates/partial_correlations/pcorrs_results_presentation.html b/wqflask/wqflask/templates/partial_correlations/pcorrs_results_presentation.html
new file mode 100644
index 00000000..c109f24b
--- /dev/null
+++ b/wqflask/wqflask/templates/partial_correlations/pcorrs_results_presentation.html
@@ -0,0 +1,249 @@
+{%extends "base.html"%}
+
+{%block title%}Partial Correlations:{%endblock%}
+
+{%block css%}
+<link rel="stylesheet" type="text/css" href="/static/new/css/partial_correlations.css" />
+<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/trait_list.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+{%endblock%}
+
+{%block content%}
+<p>
+ <strong>Primary Trait</strong><br /><br />
+ <a href="{{url_for(
+ 'show_trait_page',
+ trait_id=primary['trait_name'],
+ dataset=primary['dataset_name'])}}"
+ title="Link to trait data for trait {{primary['trait_name']}}">
+ {{primary["dataset_type"]}}/{{primary["trait_name"]}}
+ [{{primary["symbol"] }} on Chr {{primary["chr"]}} @ {{primary["mb"]}}]:
+ {{primary["description"]}}
+ </a> --- FROM: {{primary["dataset_name"]}}
+</p>
+<p><strong>Control Traits</strong><br /><br />
+ {%for trait in controls:%}
+ <a href="{{url_for(
+ 'show_trait_page',
+ trait_id=trait['trait_name'],
+ dataset=trait['dataset_name'])}}"
+ title="Link to trait data for trait {{trait['trait_name']}}">
+ {{trait["dataset_type"]}}/{{trait["trait_name"]}}
+ [{{trait["symbol"] }} on Chr {{trait["chr"]}} @ {{trait["mb"]}}]:
+ {{trait["description"]}}
+ </a> --- FROM: {{trait["dataset_name"]}}<br />
+ {%endfor%}
+</p>
+
+<div id="partial-correlation-results">
+ {%if dataset_type == "Publish":%}
+ <table id="part-corr-results-publish"
+ class="table-hover table-striped cell-border"
+ style="float: left;">
+ <thead>
+ <tr>
+ <th></th>
+ <th>Index</th>
+ <th>Record</th>
+ <th>Phenotype</th>
+ <th>Authors</th>
+ <th>Year</th>
+ <th>N</th>
+ <th>Partial {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
+ <th>p(partial {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%})</th>
+ <th>{%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
+ <th>p({%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%})</th>
+ <th>delta {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {%for trait in correlations:%}
+ <tr class="results-row">
+ <td></td>
+ <td data-column-heading="Index"></td>
+ <td data-column-heading="Record">
+ <a href="{{url_for(
+ 'show_trait_page',
+ trait_id=trait['trait_name'],
+ dataset=trait['dataset_name'])}}"
+ title="Link to trait data for trait {{trait['trait_name']}}">
+ {{trait["trait_name"]}}
+ </a>
+ </td>
+ <td data-column-heading="Phenotype">
+ {{trait["post_publication_description"]}}</td>
+ <td data-column-heading="Authors">{{trait["authors"]}}</td>
+ <td data-column-heading="Year">{{trait["year"]}}</td>
+ <td data-column-heading="N">{{trait["noverlap"]}}</td>
+ <td data-column-heading="Partial {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
+ {{format_number(trait.get("partial_corr"))}}
+ </td>
+ <td data-column-heading="p(partial {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%})">
+ {{format_number(trait.get("partial_corr_p_value"))}}
+ </td>
+ <td data-column-heading="{%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
+ {{format_number(trait.get("corr"))}}
+ </td>
+ <td data-column-heading="p({%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%})">
+ {{format_number(trait.get("corr_p_value"))}}
+ </td>
+ <td data-column-heading="delta {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
+ {{format_number(trait.get("delta"))}}
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ {%endif%}
+
+ {%if dataset_type == "Geno":%}
+ <table id="part-corr-results-geno"
+ class="table-hover table-striped cell-border"
+ style="float: left;">
+ <thead>
+ <tr>
+ <th></th>
+ <th>Index</th>
+ <th>Locus</th>
+ <th>Chr</th>
+ <th>Megabase</th>
+ <th>N</th>
+ <th>Partial {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
+ <th>p(partial {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%})</th>
+ <th>{%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
+ <th>p({%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%})</th>
+ <th>delta {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {%for trait in correlations:%}
+ <tr class="results-row">
+ <td></td>
+ <td data-column-heading="Index"></td>
+ <td data-column-heading="Locus">
+ <a href="{{url_for(
+ 'show_trait_page',
+ trait_id=trait['trait_name'],
+ dataset=trait['dataset_name'])}}"
+ title="Link to trait data for trait {{trait['trait_name']}}">
+ {{trait["trait_name"]}}
+ </a>
+ </td>
+ <td data-column-heading="Chr">{{trait["chr"]}}</td>
+ <td data-column-heading="Megabase">{{trait["mb"]}}</td>
+ <td data-column-heading="N">{{trait["noverlap"]}}</td>
+ <td data-column-heading="Partial {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
+ {{format_number(trait.get("partial_corr"))}}
+ </td>
+ <td data-column-heading="p(partial {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%})">
+ {{format_number(trait.get("partial_corr_p_value"))}}
+ </td>
+ <td data-column-heading="{%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
+ {{format_number(trait.get("corr"))}}
+ </td>
+ <td data-column-heading="p({%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%})">
+ {{format_number(trait.get("corr_p_value"))}}
+ </td>
+ <td data-column-heading="delta {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
+ {{format_number(trait.get("delta"))}}
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ {%endif%}
+
+ {%if dataset_type == "ProbeSet":%}
+ <table id="part-corr-results-probeset"
+ class="table-hover table-striped cell-border"
+ style="float: left;">
+ <thead>
+ <tr>
+ <th></th>
+ <th>Index</th>
+ <th>Record</th>
+ <th>Gene ID</th>
+ <th>Homologene ID</th>
+ <th>Symbol</th>
+ <th>Description</th>
+ <th>Chr</th>
+ <th>Megabase</th>
+ <th>Mean Expr</th>
+ <th>N</th>
+ <th>Sample Partial {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
+ <th>Sample p(partial {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%})</th>
+ <th>Sample {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
+ <th>Sample p({%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%})</th>
+ <th>delta {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
+ <th>Lit Corr</th>
+ <th>Tissue {%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%}</th>
+ <th>Tissue p({%if "spearman" in (method | lower):%}rho{%else:%}r{%endif%})</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {%for trait in correlations:%}
+ <tr class="results-row">
+ <td></td>
+ <td data-column-heading="Index"></td>
+ <td data-column-heading="Record">
+ <a href="{{url_for(
+ 'show_trait_page',
+ trait_id=trait['trait_name'],
+ dataset=trait['dataset_name'])}}"
+ title="Link to trait data for trait {{trait['trait_name']}}">
+ {{trait["trait_name"]}}
+ </a>
+ </td>
+ <td data-column-heading="Gene ID">{{trait["geneid"]}}</td>
+ <td data-column-heading="Homologene ID">{{trait["homologeneid"]}}</td>
+ <td data-column-heading="Symbol">{{trait["symbol"]}}</td>
+ <td data-column-heading="Description">{{trait["description"]}}</td>
+ <td data-column-heading="Chr">{{trait["chr"]}}</td>
+ <td data-column-heading="Megabase">{{trait["mb"]}}</td>
+ <td data-column-heading="Mean Expr">{{trait["mean_expr"]}}</td>
+ <td data-column-heading="N">{{trait["noverlap"]}}</td>
+ <td data-column-heading="Sample Partial {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
+ {{format_number(trait.get("partial_corr"))}}
+ </td>
+ <td data-column-heading="Sample p(partial {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%})">
+ {{format_number(trait.get("partial_corr_p_value"))}}
+ </td>
+ <td data-column-heading="Sample {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
+ {{format_number(trait.get("corr"))}}
+ </td>
+ <td data-column-heading="Sample p({%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%})">
+ {{format_number(trait.get("corr_p_value"))}}
+ </td>
+ <td data-column-heading="delta {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
+ {{format_number(trait.get("delta"))}}
+ </td>
+ <td data-column-heading="Lit Corr">
+ {{format_number(trait.get("l_corr"))}}
+ </td>
+ <td data-column-heading="Tissue {%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%}">
+ {{format_number(trait.get("tissue_corr"))}}
+ </td>
+ <td data-column-heading="Tissue p({%if 'spearman' in (method | lower):%}rho{%else:%}r{%endif%})">
+ {{format_number(trait.get("tissue_p_value"))}}
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ {%endif%}
+
+</div>
+{%endblock%}
+
+{%block js%}
+{%if step == "select-corr-method":%}
+<script type="text/javascript"
+ src="/static/new/javascript/partial_correlations.js"></script>
+<script language="javascript" type="text/javascript"
+ src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+{%endif%}
+{%endblock%}
diff --git a/wqflask/wqflask/templates/partial_correlations/pcorrs_select_operations.html b/wqflask/wqflask/templates/partial_correlations/pcorrs_select_operations.html
new file mode 100644
index 00000000..e541f31b
--- /dev/null
+++ b/wqflask/wqflask/templates/partial_correlations/pcorrs_select_operations.html
@@ -0,0 +1,146 @@
+{%extends "base.html"%}
+
+{%block title%}Partial Correlations:{%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('js', filename='DataTablesExtensions/buttonStyles/css/buttons.dataTables.min.css')}}">
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/trait_list.css" />
+<link rel="stylesheet" type="text/css"
+ href="/static/new/css/partial_correlations.css" />
+{%endblock%}
+
+{%block content%}
+<form id="pcorrs-form"
+ method="POST"
+ action="{{url_for('partial_correlations')}}">
+ {%with messages = get_flashed_messages(with_categories=true)%}
+ {%if messages:%}
+ <ul class=flashes>
+ {%for category, message in messages:%}
+ <li class="{{category}}">{{message}}</li>
+ {%endfor%}
+ </ul>
+ {%endif%}
+ {%endwith%}
+
+ <input type="hidden" value="{{trait_list_str}}" name="trait_list">
+ <table id="pcorrs_traits_table" class="table-hover table-striped cell-border">
+ <thead>
+ <tr>
+ <th>Primary (X)</th>
+ <th>Controls (Z)</th>
+ <th>Ignored</th>
+ <th>Dataset</th>
+ <th>Trait ID</th>
+ <th>Symbol</th>
+ <th>Description</th>
+ <th>Location</th>
+ <th>Mean</th>
+ <th>Max LRS</th>
+ <th>Max LRS Location Chr and Mb</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {%for trait in traits:%}
+ <tr>
+ <td>
+ <input type="radio" name="trait_{{trait['trait_name']}}"
+ id="trait_{{trait['trait_name']}}"
+ value="primary_{{trait['trait_name']}}">
+ </td>
+ <td>
+ <input type="radio" name="trait_{{trait['trait_name']}}"
+ id="trait_{{trait['trait_name']}}"
+ value="controls_{{trait['trait_name']}}">
+ </td>
+ <td>
+ <input type="radio" name="trait_{{trait['trait_name']}}"
+ id="trait_{{trait['trait_name']}}"
+ value="ignored_{{trait['trait_name']}}" checked="checked">
+ </td>
+ <td>{{trait.get("dataset", "_")}}
+ <td>{{trait.get("trait_name", "_")}}</td>
+ <td>{{trait.get("symbol", "_")}}</td>
+ <td>{{trait.get("description", "_")}}</td>
+ <td>{{trait.get("location", "_")}}</td>
+ <td>{{trait.get("mean", "_")}}</td>
+ <td>{{trait.get("lrs", "_")}}</td>
+ <td>{{trait.get("lrs_location", "_")}}</td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+
+ <div class="form-group">
+ <label for="corr-method-input" class="form-label">Compute</label>
+ <select id="corr-method-input" required="required" name="method"
+ class="form-control">
+ <option value="Genetic Correlation, Pearson's r">
+ Genetic Correlation, Pearson's r</option>
+ <option value="Genetic Correlation, Spearman's rho">
+ Genetic Correlation, Spearman's rho</option>
+ <option value="SGO Literature Correlation">
+ SGO Literature Correlation</option>
+ <option value="Tissue Correlation, Pearson's r">
+ Tissue Correlation, Pearson's r</option>
+ <option value="Tissue Correlation, Spearman's rho">
+ Tissue Correlation, Spearman's rho</option>
+ </select>
+ </div>
+
+ <div class="form-group">
+ <label for="target-db-input" class="form-label">Choose Database</label>
+ <select id="target-db-input" required="required" name="target_db"
+ class="form-control">
+ {%if target_dbs:%}
+ {%for item in target_dbs:%}
+ {%if "description" in item.keys():%}
+ <option value="{{item['value']}}">{{item['description']}}</option>
+ {%else:%}
+ {%for group, opts in item.items()%}
+ {%if opts | length > 0:%}
+ <optgroup label="{{group}} ------">
+ {%for item2 in opts:%}
+ <option value="{{item2['value']}}">{{item2['description']}}</option>
+ {%endfor%}
+ </optgroup>
+ {%endif%}
+ {%endfor%}
+ {%endif%}
+ {%endfor%}
+ {%endif%}
+ </select>
+ </div>
+
+ <div class="form-group">
+ <label for="criteria-input" class="form-label">Return</label>
+ <select id="criteria-input" required="required" name="criteria" size="1"
+ class="form-control">
+ <option value="100">top 100</option>
+ <option value="200">top 200</option>
+ <option value="500" selected="selected">top 500</option>
+ <option value="1000">top 1000</option>
+ <option value="2000">top 2000</option>
+ <option value="5000">top 5000</option>
+ <option value="10000">top 10000</option>
+ <option value="15000">top 15000</option>
+ <option value="20000">top 20000</option>
+ </select>
+ </div>
+
+ <button type="submit" class="btn btn-primary" name="submit"
+ value="Run Partial Correlations">
+ Run Partial Correlations
+ </button>
+</form>
+{%endblock%}
+
+{%block js%}
+<script type="text/javascript"
+ src="/static/new/javascript/partial_correlations.js"></script>
+{%endblock%}
diff --git a/wqflask/wqflask/templates/tool_buttons.html b/wqflask/wqflask/templates/tool_buttons.html
index 3ee5be19..c3927495 100644
--- a/wqflask/wqflask/templates/tool_buttons.html
+++ b/wqflask/wqflask/templates/tool_buttons.html
@@ -33,3 +33,10 @@
<button id="comp_bar_chart" class="btn btn-primary submit_special" data-url="/comparison_bar_chart" title="Comparison Bar Chart" >
Comparison Bar Chart
</button>
+
+<button id="partial-correlations"
+ class="btn btn-primary submit_special"
+ data-url="{{url_for('partial_correlations')}}"
+ title="Run partial correlations with the selected traits">
+ Partial Correlations
+</button>