From d491be2057843921cc67bd1c4b1ae612d9f15d34 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Tue, 17 Aug 2021 11:42:20 +0300 Subject: Fix obvious linting errors * Fix linting errors that do not change the function of the code. --- gn3/api/correlation.py | 4 ++-- gn3/api/general.py | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'gn3/api') diff --git a/gn3/api/correlation.py b/gn3/api/correlation.py index a3e366e..46121f8 100644 --- a/gn3/api/correlation.py +++ b/gn3/api/correlation.py @@ -79,7 +79,7 @@ def compute_tissue_corr(corr_method="pearson"): target_tissues_dict = tissue_input_data["target_tissues_dict"] results = compute_tissue_correlation(primary_tissue_dict=primary_tissue_dict, - target_tissues_data=target_tissues_dict, - corr_method=corr_method) + target_tissues_data=target_tissues_dict, + corr_method=corr_method) return jsonify(results) diff --git a/gn3/api/general.py b/gn3/api/general.py index 86fb7b7..69ec343 100644 --- a/gn3/api/general.py +++ b/gn3/api/general.py @@ -13,7 +13,8 @@ general = Blueprint("general", __name__) @general.route("/version") def version(): - return jsonify("1.0") + """Get API version.""" + return jsonify("1.0") @general.route("/metadata/upload/", methods=["POST"], strict_slashes=False) -- cgit v1.2.3 From 8854e3070f32bed95cb489eb36e7f258c02ec46e Mon Sep 17 00:00:00 2001 From: Alexander Kabui Date: Thu, 16 Sep 2021 09:32:42 +0300 Subject: add initial endpoint for wgcna --- gn3/api/wgcna.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 gn3/api/wgcna.py (limited to 'gn3/api') diff --git a/gn3/api/wgcna.py b/gn3/api/wgcna.py new file mode 100644 index 0000000..a3bacdd --- /dev/null +++ b/gn3/api/wgcna.py @@ -0,0 +1,13 @@ +"""endpoint to run wgcna analysis""" +from flask import Blueprint +from flask import request + +wgcna = Blueprint("wgcna", __name__) + + +@wgcna.route("/run_wgcna", methods=["POST"]) +def run_wgcna(): + + _wgcna_data = request.json + + return "success", 200 -- cgit v1.2.3 From 056171a0a2f127e90ab803b74635495fb0c079a2 Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Thu, 16 Sep 2021 13:06:04 +0300 Subject: Intergrate the heatmap generation with the API Issue: https://github.com/genenetwork/gn-gemtext-threads/blob/main/topics/gn1-migration-to-gn2/clustering.gmi * Intergrate the heatmap generation code on the /api/heatmaps/clustered endpoint. The endpoint should take a json query of the form: {"traits_names": [ ... ] } where the "traits_name" value is a list of the full names of traits. A sample query to the endpoint could be something like the following: curl -i -X POST "http://localhost:8080/api/heatmaps/clustered" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "traits_names": [ "UCLA_BXDBXH_CARTILAGE_V2::ILM103710672", "UCLA_BXDBXH_CARTILAGE_V2::ILM2260338", "UCLA_BXDBXH_CARTILAGE_V2::ILM3140576", "UCLA_BXDBXH_CARTILAGE_V2::ILM5670577", "UCLA_BXDBXH_CARTILAGE_V2::ILM2070121", "UCLA_BXDBXH_CARTILAGE_V2::ILM103990541", "UCLA_BXDBXH_CARTILAGE_V2::ILM1190722", "UCLA_BXDBXH_CARTILAGE_V2::ILM6590722", "UCLA_BXDBXH_CARTILAGE_V2::ILM4200064", "UCLA_BXDBXH_CARTILAGE_V2::ILM3140463" ] }' which should respond with a json response containing the raw binary string for the png format and possibly another for the svg format. --- gn3/api/heatmaps.py | 28 ++++++++++++++++++++++++++++ gn3/app.py | 2 ++ 2 files changed, 30 insertions(+) create mode 100644 gn3/api/heatmaps.py (limited to 'gn3/api') diff --git a/gn3/api/heatmaps.py b/gn3/api/heatmaps.py new file mode 100644 index 0000000..cac9c71 --- /dev/null +++ b/gn3/api/heatmaps.py @@ -0,0 +1,28 @@ +from flask import jsonify +from flask import request +from flask import Blueprint +from gn3.heatmaps import build_heatmap +from gn3.db_utils import database_connector + +heatmaps = Blueprint("heatmaps", __name__) + +@heatmaps.route("/clustered", methods=("POST",)) +def clustered_heatmaps(): + heatmap_request = request.get_json() + traits_names = heatmap_request.get("traits_names", tuple()) + if len(traits_names) < 1: + return jsonify({ + "message": "You need to provide at least one trait name." + }), 400 + conn, _cursor = database_connector() + _heatmap_file, heatmap_fig = build_heatmap(traits_names, conn) + + # stream the heatmap data somehow here. + # Can plotly actually stream the figure data in a way that can be used on + # remote end to display the image without necessarily being html? + return jsonify( + { + "query": heatmap_request, + "output_png": heatmap_fig.to_image(format="png"), + "output_svg": heatmap_fig.to_image(format="svg") + }), 200 diff --git a/gn3/app.py b/gn3/app.py index 046b5de..b4b08d0 100644 --- a/gn3/app.py +++ b/gn3/app.py @@ -7,6 +7,7 @@ from flask import Flask from gn3.api.gemma import gemma from gn3.api.rqtl import rqtl from gn3.api.general import general +from gn3.api.heatmaps import heatmaps from gn3.api.correlation import correlation from gn3.api.data_entry import data_entry @@ -30,6 +31,7 @@ def create_app(config: Union[Dict, str, None] = None) -> Flask: app.register_blueprint(general, url_prefix="/api/") app.register_blueprint(gemma, url_prefix="/api/gemma") app.register_blueprint(rqtl, url_prefix="/api/rqtl") + app.register_blueprint(heatmaps, url_prefix="/api/heatmaps") app.register_blueprint(correlation, url_prefix="/api/correlation") app.register_blueprint(data_entry, url_prefix="/api/dataentry") return app -- cgit v1.2.3 From f53a8a98206b4e8aedbf4b86e49f41ea140c9c6a Mon Sep 17 00:00:00 2001 From: Alexander Kabui Date: Thu, 16 Sep 2021 14:02:13 +0300 Subject: pass user input to call script --- gn3/api/wgcna.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'gn3/api') diff --git a/gn3/api/wgcna.py b/gn3/api/wgcna.py index a3bacdd..5d49493 100644 --- a/gn3/api/wgcna.py +++ b/gn3/api/wgcna.py @@ -1,13 +1,21 @@ """endpoint to run wgcna analysis""" from flask import Blueprint from flask import request +from flask import current_app + +from gn3.computations.wgcna import call_wgcna_script wgcna = Blueprint("wgcna", __name__) @wgcna.route("/run_wgcna", methods=["POST"]) def run_wgcna(): + """run wgcna:output should be a json with a the data""" + + wgcna_data = request.json + + wgcna_script = current_app.config["WGCNA_RSCRIPT"] - _wgcna_data = request.json + results = call_wgcna_script(wgcna_script, wgcna_data) - return "success", 200 + return results, 200 -- cgit v1.2.3 From 8ac3194f06084dfe5d0cfb141f178d83d937fcc3 Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Fri, 17 Sep 2021 10:35:15 +0300 Subject: Return path to generated filename for now Issue: https://github.com/genenetwork/gn-gemtext-threads/blob/main/topics/gn1-migration-to-gn2/clustering.gmi * To help with demonstrating that the code is producing the expected output, for now, we return the path to the generated html file that displays the interactive heatmap. At this point, it is mostly useful in the development environment. Moving forward, we might have to actually stream the raw html, or if we can get the Kaleido library packaged for GNU Guix, stream the images binary data instead. --- gn3/api/heatmaps.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'gn3/api') diff --git a/gn3/api/heatmaps.py b/gn3/api/heatmaps.py index cac9c71..f053241 100644 --- a/gn3/api/heatmaps.py +++ b/gn3/api/heatmaps.py @@ -20,9 +20,10 @@ def clustered_heatmaps(): # stream the heatmap data somehow here. # Can plotly actually stream the figure data in a way that can be used on # remote end to display the image without necessarily being html? - return jsonify( - { - "query": heatmap_request, - "output_png": heatmap_fig.to_image(format="png"), - "output_svg": heatmap_fig.to_image(format="svg") - }), 200 + # return jsonify( + # { + # "query": heatmap_request, + # "output_png": heatmap_fig.to_image(format="png"), + # "output_svg": heatmap_fig.to_image(format="svg") + # }), 200 + return jsonify({"output_filename": _heatmap_file}), 200 -- cgit v1.2.3 From b7fb10586b956a8b0389e7925e4c0cff28cde82f Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Mon, 20 Sep 2021 06:36:00 +0300 Subject: Return only the data Issue: https://github.com/genenetwork/gn-gemtext-threads/blob/main/topics/gn1-migration-to-gn2/clustering.gmi * gn3/api/heatmaps.py: Parse incoming data to build up correct trait names and respond with only the computed heatmap data. * gn3/heatmaps.py: Return only the computed data for heatmaps and clustering. Since GN3 is supposed to handle only the data, and db-access, this commit ensures that GN3 responds to the client with only the computed heatmap data, and does not try to generate the heatmaps themselves. The generation of the heatmaps will be delegated to the UI clients, such as GeneNetwork2. --- gn3/api/heatmaps.py | 18 ++++++------------ gn3/heatmaps.py | 25 +++++++++++++++++-------- 2 files changed, 23 insertions(+), 20 deletions(-) (limited to 'gn3/api') diff --git a/gn3/api/heatmaps.py b/gn3/api/heatmaps.py index f053241..eea3ebe 100644 --- a/gn3/api/heatmaps.py +++ b/gn3/api/heatmaps.py @@ -15,15 +15,9 @@ def clustered_heatmaps(): "message": "You need to provide at least one trait name." }), 400 conn, _cursor = database_connector() - _heatmap_file, heatmap_fig = build_heatmap(traits_names, conn) - - # stream the heatmap data somehow here. - # Can plotly actually stream the figure data in a way that can be used on - # remote end to display the image without necessarily being html? - # return jsonify( - # { - # "query": heatmap_request, - # "output_png": heatmap_fig.to_image(format="png"), - # "output_svg": heatmap_fig.to_image(format="svg") - # }), 200 - return jsonify({"output_filename": _heatmap_file}), 200 + def setup_trait_fullname(trait): + name_parts = trait.split(":") + return "{dataset_name}::{trait_name}".format( + dataset_name=trait[1], trait_name=trait[0]) + traits_fullnames = [parse_trait_fullname(trait) for trait in traits_names] + return jsonify(build_heatmap(traits_fullnames, conn)), 200 diff --git a/gn3/heatmaps.py b/gn3/heatmaps.py index c4fc67d..205a3b3 100644 --- a/gn3/heatmaps.py +++ b/gn3/heatmaps.py @@ -199,17 +199,26 @@ def build_heatmap(traits_names, conn: Any): zip(traits_ids, [traits[idx]["trait_fullname"] for idx in traits_order])) - return generate_clustered_heatmap( - process_traits_data_for_heatmap( + # return generate_clustered_heatmap( + # process_traits_data_for_heatmap( + # organised, traits_ids, chromosome_names), + # clustered, + # "single_heatmap_{}".format(random_string(10)), + # y_axis=tuple( + # ordered_traits_names[traits_ids[order]] + # for order in traits_order), + # y_label="Traits", + # x_axis=chromosome_names, + # x_label="Chromosomes") + return { + "clustering_data": clustered, + "heatmap_data": process_traits_data_for_heatmap( organised, traits_ids, chromosome_names), - clustered, - "single_heatmap_{}".format(random_string(10)), - y_axis=tuple( + "traits": tuple( ordered_traits_names[traits_ids[order]] for order in traits_order), - y_label="Traits", - x_axis=chromosome_names, - x_label="Chromosomes") + "chromosomes": chromosome_names + } def compute_traits_order(slink_data, neworder: tuple = tuple()): """ -- cgit v1.2.3 From 8442204492a28153e995f3147e06c9758cd3bd28 Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Mon, 20 Sep 2021 08:43:38 +0300 Subject: Enable Cross-Origin Resource Sharing Issue: https://github.com/genenetwork/gn-gemtext-threads/blob/main/topics/gn1-migration-to-gn2/clustering.gmi * gn3/api/heatmaps.py: Fix bugs in data parsing * gn3/app.py: enable CORS * gn3/settings.py: add flask-cors configurations * guix.scm: Add flask-cors dependency For easier testing of the heatmaps generation feature, this commit activates the cross-origin resource sharing for all "localhost" origins. --- gn3/api/heatmaps.py | 4 ++-- gn3/app.py | 7 +++++++ gn3/settings.py | 12 ++++++++++++ guix.scm | 3 ++- 4 files changed, 23 insertions(+), 3 deletions(-) (limited to 'gn3/api') diff --git a/gn3/api/heatmaps.py b/gn3/api/heatmaps.py index eea3ebe..43ac580 100644 --- a/gn3/api/heatmaps.py +++ b/gn3/api/heatmaps.py @@ -15,9 +15,9 @@ def clustered_heatmaps(): "message": "You need to provide at least one trait name." }), 400 conn, _cursor = database_connector() - def setup_trait_fullname(trait): + def parse_trait_fullname(trait): name_parts = trait.split(":") return "{dataset_name}::{trait_name}".format( - dataset_name=trait[1], trait_name=trait[0]) + dataset_name=name_parts[1], trait_name=name_parts[0]) traits_fullnames = [parse_trait_fullname(trait) for trait in traits_names] return jsonify(build_heatmap(traits_fullnames, conn)), 200 diff --git a/gn3/app.py b/gn3/app.py index b4b08d0..6b4c57e 100644 --- a/gn3/app.py +++ b/gn3/app.py @@ -11,6 +11,7 @@ from gn3.api.heatmaps import heatmaps from gn3.api.correlation import correlation from gn3.api.data_entry import data_entry +from flask_cors import CORS def create_app(config: Union[Dict, str, None] = None) -> Flask: """Create a new flask object""" @@ -18,6 +19,12 @@ def create_app(config: Union[Dict, str, None] = None) -> Flask: # Load default configuration app.config.from_object("gn3.settings") + CORS( + app, + origins=app.config["CORS_ORIGINS"], + allow_headers=app.config["CORS_HEADERS"], + supports_credentials=True, intercept_exceptions=False) + # Load environment configuration if "GN3_CONF" in os.environ: app.config.from_envvar('GN3_CONF') diff --git a/gn3/settings.py b/gn3/settings.py index a08f846..9d7bba3 100644 --- a/gn3/settings.py +++ b/gn3/settings.py @@ -31,3 +31,15 @@ REAPER_COMMAND = "{}/bin/qtlreaper".format(os.environ.get("GUIX_ENVIRONMENT")) # genotype files GENOTYPE_FILES = os.environ.get( "GENOTYPE_FILES", "{}/genotype_files/genotype".format(os.environ.get("HOME"))) + +# CROSS-ORIGIN SETUP +CORS_ORIGINS = [ + "http://localhost:*", + "http://127.0.0.1:*" +] + +CORS_HEADERS = [ + "Content-Type", + "Authorization", + "Access-Control-Allow-Credentials" +] diff --git a/guix.scm b/guix.scm index 8e1cf79..fb97142 100644 --- a/guix.scm +++ b/guix.scm @@ -106,7 +106,8 @@ ("r-stringi" ,r-stringi) ("python-plotly" ,python-plotly) ("python-pandas" ,python-pandas) - ("rust-qtlreaper" ,rust-qtlreaper))) + ("rust-qtlreaper" ,rust-qtlreaper) + ("python-flask-cors" ,python-flask-cors))) (build-system python-build-system) (home-page "https://github.com/genenetwork/genenetwork3") (synopsis "GeneNetwork3 API for data science and machine learning.") -- cgit v1.2.3 From 6f7c60e6c438ada9a3b9032c8e4509351384e04f Mon Sep 17 00:00:00 2001 From: Alexander Kabui Date: Wed, 22 Sep 2021 00:49:22 +0300 Subject: jsonify results --- gn3/api/wgcna.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'gn3/api') diff --git a/gn3/api/wgcna.py b/gn3/api/wgcna.py index 5d49493..89784c4 100644 --- a/gn3/api/wgcna.py +++ b/gn3/api/wgcna.py @@ -2,6 +2,7 @@ from flask import Blueprint from flask import request from flask import current_app +from flask import jsonify from gn3.computations.wgcna import call_wgcna_script @@ -18,4 +19,4 @@ def run_wgcna(): results = call_wgcna_script(wgcna_script, wgcna_data) - return results, 200 + return jsonify(results), 200 -- cgit v1.2.3 From 920be820e9cefe1dcde86d9a252f098c67a2bb8b Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Wed, 22 Sep 2021 07:03:53 +0300 Subject: Return serialized plotly figure Issue: https://github.com/genenetwork/gn-gemtext-threads/blob/main/topics/gn1-migration-to-gn2/clustering.gmi * gn3/api/heatmaps.py: Serialize the figure to JSON * gn3/heatmaps.py: Return the figure object Serialize the Plotly figure into JSON, and return that, so that it can be used on the client to display the image. --- gn3/api/heatmaps.py | 8 +++++++- gn3/heatmaps.py | 27 ++++++++------------------- 2 files changed, 15 insertions(+), 20 deletions(-) (limited to 'gn3/api') diff --git a/gn3/api/heatmaps.py b/gn3/api/heatmaps.py index 43ac580..0493f8a 100644 --- a/gn3/api/heatmaps.py +++ b/gn3/api/heatmaps.py @@ -1,3 +1,4 @@ +import io from flask import jsonify from flask import request from flask import Blueprint @@ -20,4 +21,9 @@ def clustered_heatmaps(): return "{dataset_name}::{trait_name}".format( dataset_name=name_parts[1], trait_name=name_parts[0]) traits_fullnames = [parse_trait_fullname(trait) for trait in traits_names] - return jsonify(build_heatmap(traits_fullnames, conn)), 200 + + with io.StringIO() as io_str: + _filename, figure = build_heatmap(traits_fullnames, conn) + figure.write_json(io_str) + fig_json = io_str.getvalue() + return fig_json, 200 diff --git a/gn3/heatmaps.py b/gn3/heatmaps.py index 205a3b3..cd93b3f 100644 --- a/gn3/heatmaps.py +++ b/gn3/heatmaps.py @@ -187,38 +187,27 @@ def build_heatmap(traits_names, conn: Any): genotype_filename, traits_filename, separate_nperm_output=True) qtlresults = parse_reaper_main_results(main_output) - # permudata = parse_reaper_permutation_results(permutations_output) organised = organise_reaper_main_results(qtlresults) traits_ids = [# sort numerically, but retain the ids as strings str(i) for i in sorted({int(row["ID"]) for row in qtlresults})] chromosome_names = sorted( {row["Chr"] for row in qtlresults}, key=chromosome_sorter_key_fn) - # loci_names = sorted({row["Locus"] for row in qtlresults}) ordered_traits_names = dict( zip(traits_ids, [traits[idx]["trait_fullname"] for idx in traits_order])) - # return generate_clustered_heatmap( - # process_traits_data_for_heatmap( - # organised, traits_ids, chromosome_names), - # clustered, - # "single_heatmap_{}".format(random_string(10)), - # y_axis=tuple( - # ordered_traits_names[traits_ids[order]] - # for order in traits_order), - # y_label="Traits", - # x_axis=chromosome_names, - # x_label="Chromosomes") - return { - "clustering_data": clustered, - "heatmap_data": process_traits_data_for_heatmap( + return generate_clustered_heatmap( + process_traits_data_for_heatmap( organised, traits_ids, chromosome_names), - "traits": tuple( + clustered, + "single_heatmap_{}".format(random_string(10)), + y_axis=tuple( ordered_traits_names[traits_ids[order]] for order in traits_order), - "chromosomes": chromosome_names - } + y_label="Traits", + x_axis=chromosome_names, + x_label="Chromosomes") def compute_traits_order(slink_data, neworder: tuple = tuple()): """ -- cgit v1.2.3 From 5892ffc7488b0c9cbb4ea08fd5c5f8648e0baea8 Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Wed, 22 Sep 2021 07:06:14 +0300 Subject: Update check: Heatmaps need at least 2 items Issue: https://github.com/genenetwork/gn-gemtext-threads/blob/main/topics/gn1-migration-to-gn2/clustering.gmi * Update the check to look for at least 2 traits before trying to generate the heatmap. --- gn3/api/heatmaps.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gn3/api') diff --git a/gn3/api/heatmaps.py b/gn3/api/heatmaps.py index 0493f8a..1022a35 100644 --- a/gn3/api/heatmaps.py +++ b/gn3/api/heatmaps.py @@ -11,9 +11,9 @@ heatmaps = Blueprint("heatmaps", __name__) def clustered_heatmaps(): heatmap_request = request.get_json() traits_names = heatmap_request.get("traits_names", tuple()) - if len(traits_names) < 1: + if len(traits_names) < 2: return jsonify({ - "message": "You need to provide at least one trait name." + "message": "You need to provide at least two trait names." }), 400 conn, _cursor = database_connector() def parse_trait_fullname(trait): -- cgit v1.2.3 From cd7f301688fd9780df1f842f8bd2b7602775ba1f Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Wed, 22 Sep 2021 07:53:53 +0300 Subject: Fix pylint errors * Add missing function and module docstrings * Remove unused imports * Fix import order * Rework some code sections to fix issues * Disable some pylint errors. --- gn3/api/heatmaps.py | 8 ++++++++ gn3/app.py | 5 +++-- gn3/computations/qtlreaper.py | 8 ++++++++ gn3/db/genotypes.py | 1 + gn3/db/traits.py | 2 +- gn3/heatmaps.py | 28 ++++++++++++++++------------ 6 files changed, 37 insertions(+), 15 deletions(-) (limited to 'gn3/api') diff --git a/gn3/api/heatmaps.py b/gn3/api/heatmaps.py index 1022a35..fe47aee 100644 --- a/gn3/api/heatmaps.py +++ b/gn3/api/heatmaps.py @@ -1,3 +1,7 @@ +""" +Module to hold the entrypoint functions that generate heatmaps +""" + import io from flask import jsonify from flask import request @@ -9,6 +13,10 @@ heatmaps = Blueprint("heatmaps", __name__) @heatmaps.route("/clustered", methods=("POST",)) def clustered_heatmaps(): + """ + Parses the incoming data and responds with the JSON-serialized plotly figure + representing the clustered heatmap. + """ heatmap_request = request.get_json() traits_names = heatmap_request.get("traits_names", tuple()) if len(traits_names) < 2: diff --git a/gn3/app.py b/gn3/app.py index 6b4c57e..8badb65 100644 --- a/gn3/app.py +++ b/gn3/app.py @@ -3,7 +3,10 @@ import os from typing import Dict from typing import Union + from flask import Flask +from flask_cors import CORS + from gn3.api.gemma import gemma from gn3.api.rqtl import rqtl from gn3.api.general import general @@ -11,8 +14,6 @@ from gn3.api.heatmaps import heatmaps from gn3.api.correlation import correlation from gn3.api.data_entry import data_entry -from flask_cors import CORS - def create_app(config: Union[Dict, str, None] = None) -> Flask: """Create a new flask object""" app = Flask(__name__) diff --git a/gn3/computations/qtlreaper.py b/gn3/computations/qtlreaper.py index 377db9b..5d17fed 100644 --- a/gn3/computations/qtlreaper.py +++ b/gn3/computations/qtlreaper.py @@ -87,11 +87,17 @@ def run_reaper( return (output_filename, permu_output_filename) def chromosome_sorter_key_fn(val): + """ + Useful for sorting the chromosomes + """ if isinstance(val, int): return val return ord(val) def organise_reaper_main_results(parsed_results): + """ + Provide the results of running reaper in a format that is easier to use. + """ def __organise_by_chromosome(chr_name, items): chr_items = [item for item in items if item["Chr"] == chr_name] return { @@ -129,12 +135,14 @@ def parse_reaper_main_results(results_file): lines = infile.readlines() def __parse_column_float_value(value): + # pylint: disable=W0702 try: return float(value) except: return value def __parse_column_int_value(value): + # pylint: disable=W0702 try: return int(value) except: diff --git a/gn3/db/genotypes.py b/gn3/db/genotypes.py index 9d052d9..919c539 100644 --- a/gn3/db/genotypes.py +++ b/gn3/db/genotypes.py @@ -115,6 +115,7 @@ def parse_genotype_marker(line: str, geno_obj: dict, parlist: list): Reworks https://github.com/genenetwork/genenetwork1/blob/master/web/webqtl/utility/gen_geno_ob.py#L143-L190 """ + # pylint: disable=W0702 marker_row = [item.strip() for item in line.split("\t")] geno_table = { geno_obj["mat"]: -1, geno_obj["pat"]: 1, geno_obj["het"]: 0, diff --git a/gn3/db/traits.py b/gn3/db/traits.py index bfe887e..747ed27 100644 --- a/gn3/db/traits.py +++ b/gn3/db/traits.py @@ -46,7 +46,7 @@ def update_sample_data(conn: Any, count: Union[int, str]): """Given the right parameters, update sample-data from the relevant table.""" - # pylint: disable=[R0913, R0914] + # pylint: disable=[R0913, R0914, C0103] STRAIN_ID_SQL: str = "UPDATE Strain SET Name = %s WHERE Id = %s" PUBLISH_DATA_SQL: str = ("UPDATE PublishData SET value = %s " "WHERE StrainId = %s AND Id = %s") diff --git a/gn3/heatmaps.py b/gn3/heatmaps.py index cd93b3f..9d82fb2 100644 --- a/gn3/heatmaps.py +++ b/gn3/heatmaps.py @@ -3,29 +3,28 @@ This module will contain functions to be used in computation of the data used to generate various kinds of heatmaps. """ +from functools import reduce from typing import Any, Dict, Sequence + import numpy as np -from functools import reduce -from gn3.settings import TMPDIR import plotly.graph_objects as go import plotly.figure_factory as ff +from plotly.subplots import make_subplots + +from gn3.settings import TMPDIR from gn3.random import random_string from gn3.computations.slink import slink -from plotly.subplots import make_subplots from gn3.computations.correlations2 import compute_correlation from gn3.db.genotypes import ( - build_genotype_file, load_genotype_samples, parse_genotype_file) + build_genotype_file, load_genotype_samples) from gn3.db.traits import ( - retrieve_trait_data, - retrieve_trait_info, - generate_traits_filename) + retrieve_trait_data, retrieve_trait_info) from gn3.computations.qtlreaper import ( run_reaper, generate_traits_file, chromosome_sorter_key_fn, parse_reaper_main_results, - organise_reaper_main_results, - parse_reaper_permutation_results) + organise_reaper_main_results) def export_trait_data( trait_data: dict, strainlist: Sequence[str], dtype: str = "val", @@ -159,13 +158,13 @@ def build_heatmap(traits_names, conn: Any): PARAMETERS: TODO: Elaborate on the parameters here... """ + # pylint: disable=[R0914] threshold = 0 # webqtlConfig.PUBLICTHRESH traits = [ retrieve_trait_info(threshold, fullname, conn) for fullname in traits_names] traits_data_list = [retrieve_trait_data(t, conn) for t in traits] genotype_filename = build_genotype_file(traits[0]["riset"]) - # genotype = parse_genotype_file(genotype_filename) strains = load_genotype_samples(genotype_filename) exported_traits_data_list = [ export_trait_data(td, strains) for td in traits_data_list] @@ -336,6 +335,7 @@ def generate_clustered_heatmap( Generate a dendrogram, and heatmaps for each chromosome, and put them all into one plot. """ + # pylint: disable=[R0913, R0914] num_cols = 1 + len(x_axis) fig = make_subplots( rows=1, @@ -359,14 +359,18 @@ def generate_clustered_heatmap( "height": 800, "xaxis": { "mirror": False, - "showgrid": True + "showgrid": True, + "title": x_label + }, + "yaxis": { + "title": y_label } }) x_axes_layouts = { "xaxis{}".format(i+1 if i > 0 else ""): { "mirror": False, - "showticklabels": True if i == 0 else False, + "showticklabels": i == 0, "ticks": "outside" if i == 0 else "" } for i in range(num_cols)} -- cgit v1.2.3 From 62a5047be6cee5f692d44f97410cab11a01e3396 Mon Sep 17 00:00:00 2001 From: Alexander Kabui Date: Thu, 23 Sep 2021 16:05:17 +0300 Subject: minor fixes for endpoint --- gn3/api/wgcna.py | 3 +++ gn3/computations/wgcna.py | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'gn3/api') diff --git a/gn3/api/wgcna.py b/gn3/api/wgcna.py index 89784c4..fa044cf 100644 --- a/gn3/api/wgcna.py +++ b/gn3/api/wgcna.py @@ -19,4 +19,7 @@ def run_wgcna(): results = call_wgcna_script(wgcna_script, wgcna_data) + if results.get("data") is None: + return jsonify(results), 401 + return jsonify(results), 200 diff --git a/gn3/computations/wgcna.py b/gn3/computations/wgcna.py index e9b76e8..436a888 100644 --- a/gn3/computations/wgcna.py +++ b/gn3/computations/wgcna.py @@ -44,6 +44,5 @@ def call_wgcna_script(rscript_path: str, request_data: dict): "data": json.load(outputfile), **run_cmd_results } - # return json.load(outputfile) except Exception as error: raise error -- cgit v1.2.3 From a9fc9814760d205674904f8feb700eadae480fb1 Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Mon, 27 Sep 2021 05:25:58 +0300 Subject: Remove unnecessary variable. Issue: https://github.com/genenetwork/gn-gemtext-threads/blob/main/topics/gn1-migration-to-gn2/clustering.gmi * Fix issue according to review https://github.com/genenetwork/genenetwork3/pull/37#discussion_r714549781 --- gn3/api/heatmaps.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'gn3/api') diff --git a/gn3/api/heatmaps.py b/gn3/api/heatmaps.py index fe47aee..62ca2ad 100644 --- a/gn3/api/heatmaps.py +++ b/gn3/api/heatmaps.py @@ -17,8 +17,7 @@ def clustered_heatmaps(): Parses the incoming data and responds with the JSON-serialized plotly figure representing the clustered heatmap. """ - heatmap_request = request.get_json() - traits_names = heatmap_request.get("traits_names", tuple()) + traits_names = request.get_json().get("traits_names", tuple()) if len(traits_names) < 2: return jsonify({ "message": "You need to provide at least two trait names." -- cgit v1.2.3