diff options
author | Frederick Muriuki Muriithi | 2022-05-06 15:30:10 +0300 |
---|---|---|
committer | Frederick Muriuki Muriithi | 2022-05-06 15:32:45 +0300 |
commit | 3687600b70c8b3850f8e35513f3fb3a30316c721 (patch) | |
tree | 8de043f9fda1416425d29ea47b3b1128e6e16cec | |
parent | 95a1f96e74461fdeef14a331bc37fa5b850571f5 (diff) | |
download | genenetwork2-3687600b70c8b3850f8e35513f3fb3a30316c721.tar.gz |
Compute pcorrs with selected target traits
Modify the code to request computation of partial correlations with
selected traits rather than a complete dataset.
3 files changed, 182 insertions, 18 deletions
diff --git a/wqflask/wqflask/partial_correlations_views.py b/wqflask/wqflask/partial_correlations_views.py index 41bbe7d7..40c5132b 100644 --- a/wqflask/wqflask/partial_correlations_views.py +++ b/wqflask/wqflask/partial_correlations_views.py @@ -116,8 +116,20 @@ def controls_error(args): "of three control traits"),))} return args -def target_db_error(args): - if not args["target_db"]: +def target_traits_error(args, with_target_traits): + target_traits_present = ( + (args.get("target_traits") is not None) and + (len(args["target_traits"]) > 0)) + if with_target_traits and not target_traits_present: + return { + **args, + "errors": ( + args.get("errors", tuple()) + + (("You must provide at least one target trait"),))} + return args + +def target_db_error(args, with_target_db: bool): + if with_target_db and not args["target_db"]: return { **args, "errors": ( @@ -151,17 +163,24 @@ def criteria_error(args): args.get("errors", tuple()) + ("Invalid return number provided",))} -def errors(args): - return criteria_error(method_error(target_db_error(controls_error( - primary_error(args))))) +def errors(args, with_target_db: bool): + return criteria_error( + method_error( + target_traits_error( + target_db_error( + controls_error(primary_error(args)), + with_target_db), + not with_target_db))) def __classify_args(acc, item): if item[1].startswith("primary_"): return { **acc, - "primary_trait": (acc.get("primary_trait", tuple()) + (item,))} + "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[1].startswith("targets_"): + return {**acc, "target_traits": (acc.get("target_traits", tuple()) + (item,))} if item[0] == "target_db": return {**acc, "target_db": item[1]} if item[0] == "method": @@ -179,7 +198,10 @@ def __build_args(raw_form, traits): (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"])] + (name[1][9:] for name in args["control_traits"])], + "target_traits": [ + item for item in traits if item["trait_name"] in + (name[1][8:] for name in args["target_traits"])] } def parse_trait(trait_str): @@ -204,13 +226,31 @@ def render_error(error_message): "partial_correlations/pcorrs_error.html", message = error_message) +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}" + def handle_200_response(response): - if response["status"] == "success": + if response["status"] == "queued": return redirect( url_for( "poll_partial_correlation_results", command_id=response["results"]), code=303) + if response["status"] == "success": + return render_template( + "partial_correlations/pcorrs_results_with_target_traits.html", + primary = response["results"]["results"]["primary_trait"], + controls = response["results"]["results"]["control_traits"], + pcorrs = sorted( + response["results"]["results"]["correlations"], + key = lambda item: item["partial_corr_p_value"]), + method = response["results"]["results"]["method"], + enumerate = enumerate, + format_number = __format_number) return render_error(response["results"]) def handle_response(response): @@ -227,12 +267,34 @@ def partial_correlations(): parse_trait(trait) for trait in form.get("trait_list").split(";;;")) - if form.get("submit") == "Run Partial Correlations": - args = errors(__build_args(form, traits)) + submit = form.get("submit") + + if submit in ("with_target_pearsons", "with_target_spearmans"): + method = "pearsons" if "pearsons" in submit else "spearmans" + args = { + **errors(__build_args(form, traits), with_target_db=False), + "method": method + } + if len(args.get("errors", [])) == 0: + post_data = { + **args, + "primary_trait": args["primary_trait"][0], + "with_target_db": False + } + return handle_response(requests.post( + url=f"{GN_SERVER_URL}api/correlation/partial", + json=post_data)) + + for error in args["errors"]: + flash(error, "alert-danger") + + if submit == "Run Partial Correlations": + args = errors(__build_args(form, traits), with_target_db=True) if len(args.get("errors", [])) == 0: post_data = { **args, - "primary_trait": args["primary_trait"][0] + "primary_trait": args["primary_trait"][0], + "with_target_db": False } return handle_response(requests.post( url=f"{GN_SERVER_URL}api/correlation/partial", @@ -251,12 +313,6 @@ def partial_correlations(): 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/pcorrs_results_presentation.html", diff --git a/wqflask/wqflask/templates/partial_correlations/pcorrs_results_with_target_traits.html b/wqflask/wqflask/templates/partial_correlations/pcorrs_results_with_target_traits.html new file mode 100644 index 00000000..acea8f60 --- /dev/null +++ b/wqflask/wqflask/templates/partial_correlations/pcorrs_results_with_target_traits.html @@ -0,0 +1,108 @@ +{%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%} +<div class="container"> + <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> + + <table id="part-corr-results-publish" + class="table-hover table-striped cell-border dataTable"> + <thead> + <tr> + <th>_</th> + <th>Index</th> + <th>Database</th> + <th>Record</th> + <th>Symbol</th> + <th>Description</th> + <th>N</th> + {%if method == "spearmans":%} + <th>Partial rho</th> + <th>p(partial rho)</th> + <th>rho</th> + <th>p(rho)</th> + <th>delta rho</th> + {%else:%} + <th>Partial r</th> + <th>p(partial r)</th> + <th>r</th> + <th>p(r)</th> + <th>delta r</th> + {%endif%} + </tr> + </thead> + + <tbody> + {%for idx, trait in enumerate(pcorrs, start=1):%} + <tr> + <td> + <input type="checkbox" name="chk_{{trait['trait_name']}}" + value="{{trait['trait_fullname']}}"> + </td> + <td>{{idx}}</td> + <td>{{trait["dataset_name"]}}</td> + <td>{{trait["trait_name"]}}</td> + <td>{{trait["symbol"]}}</td> + <td>{{trait["description"]}}</td> + <td>{{trait["noverlap"]}}</td> + <td>{{format_number(trait["partial_corr"])}}</td> + <td>{{format_number(trait["partial_corr_p_value"])}}</td> + <td>{{format_number(trait["corr"])}}</td> + <td>{{format_number(trait["corr_p_value"])}}</td> + <td>{{format_number(trait["delta"])}}</td> + </tr> + {%else:%} + <tr> + <td colspan="12"> + No correlations were computed + </td> + </tr> + {%endfor%} + </tbody> + </table> + +</div> +{%endblock%} + +{%block js%} +<!-- + <script type="text/javascript" + src="/static/new/javascript/partial_correlations.js"></script> +--> +{%endblock%} diff --git a/wqflask/wqflask/templates/partial_correlations/pcorrs_select_operations.html b/wqflask/wqflask/templates/partial_correlations/pcorrs_select_operations.html index e1e392c6..fc60aa3e 100644 --- a/wqflask/wqflask/templates/partial_correlations/pcorrs_select_operations.html +++ b/wqflask/wqflask/templates/partial_correlations/pcorrs_select_operations.html @@ -66,7 +66,7 @@ <td> <input type="radio" name="trait_{{trait['trait_name']}}" id="trait_{{trait['trait_name']}}" - value="target_{{trait['trait_name']}}" checked="checked" /> + value="targets_{{trait['trait_name']}}" checked="checked" /> </td> <td> <input type="radio" name="trait_{{trait['trait_name']}}" |