From 4130373db071b094b042ccf70f1f6e09d432993d Mon Sep 17 00:00:00 2001 From: DannyArends Date: Fri, 11 Sep 2015 16:05:59 +0200 Subject: Adding an empty HTML results template for WCGNA --- wqflask/wqflask/templates/wcgna_results.html | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 wqflask/wqflask/templates/wcgna_results.html (limited to 'wqflask') diff --git a/wqflask/wqflask/templates/wcgna_results.html b/wqflask/wqflask/templates/wcgna_results.html new file mode 100644 index 00000000..b74b84ae --- /dev/null +++ b/wqflask/wqflask/templates/wcgna_results.html @@ -0,0 +1,9 @@ +{% extends "base.html" %} +{% block title %}WCGNA results{% endblock %} + +{% block content %} +
+

WCGNA results

+
+{% endblock %} + -- cgit v1.2.3 From cbbe7e8bd625f94809c8423bc5d8fdafa2646042 Mon Sep 17 00:00:00 2001 From: DannyArends Date: Fri, 11 Sep 2015 17:08:15 +0200 Subject: Comment out some excessive stdout spam --- wqflask/base/data_set.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wqflask') diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index e2db9ad7..427fd991 100755 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -89,7 +89,7 @@ class Dataset_Types(object): for group in data['datasets'][species]: for dataset_type in data['datasets'][species][group]: for dataset in data['datasets'][species][group][dataset_type]: - print("dataset is:", dataset) + #print("dataset is:", dataset) short_dataset_name = dataset[0] if dataset_type == "Phenotypes": -- cgit v1.2.3 From 7303dc04e7d129d6751d2875f5841da102bf6fd8 Mon Sep 17 00:00:00 2001 From: DannyArends Date: Fri, 11 Sep 2015 17:49:02 +0200 Subject: Adding a custom wgcna route in gn2, and adding a button to the collections/view.html --- wqflask/wqflask/templates/collections/view.html | 12 ++++++++++++ wqflask/wqflask/templates/wcgna_results.html | 9 --------- wqflask/wqflask/templates/wgcna_results.html | 9 +++++++++ wqflask/wqflask/views.py | 4 ++++ 4 files changed, 25 insertions(+), 9 deletions(-) delete mode 100644 wqflask/wqflask/templates/wcgna_results.html create mode 100644 wqflask/wqflask/templates/wgcna_results.html (limited to 'wqflask') diff --git a/wqflask/wqflask/templates/collections/view.html b/wqflask/wqflask/templates/collections/view.html index 29c65058..f3e9f1b9 100755 --- a/wqflask/wqflask/templates/collections/view.html +++ b/wqflask/wqflask/templates/collections/view.html @@ -38,6 +38,18 @@ +
+ {% if uc %} + + {% endif %} + +
+ +
+
{% if uc %} diff --git a/wqflask/wqflask/templates/wcgna_results.html b/wqflask/wqflask/templates/wcgna_results.html deleted file mode 100644 index b74b84ae..00000000 --- a/wqflask/wqflask/templates/wcgna_results.html +++ /dev/null @@ -1,9 +0,0 @@ -{% extends "base.html" %} -{% block title %}WCGNA results{% endblock %} - -{% block content %} -
-

WCGNA results

-
-{% endblock %} - diff --git a/wqflask/wqflask/templates/wgcna_results.html b/wqflask/wqflask/templates/wgcna_results.html new file mode 100644 index 00000000..b74b84ae --- /dev/null +++ b/wqflask/wqflask/templates/wgcna_results.html @@ -0,0 +1,9 @@ +{% extends "base.html" %} +{% block title %}WCGNA results{% endblock %} + +{% block content %} +
+

WCGNA results

+
+{% endblock %} + diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 3cff9a0c..acbbf203 100755 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -174,6 +174,10 @@ def help(): doc = docs.Docs("help") return render_template("docs.html", **doc.__dict__) +@app.route("/wgcna", methods=('POST',)) +def wcgna(): + return render_template("wgcna_results.html") + @app.route("/news") def news_route(): newsobject = news.News() -- cgit v1.2.3 From 17c9b0f9130c2ccd3b050cd9929f9ca6d3ab7307 Mon Sep 17 00:00:00 2001 From: DannyArends Date: Fri, 11 Sep 2015 17:53:39 +0200 Subject: Seems I always turn around the G and C --- wqflask/wqflask/templates/wgcna_results.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wqflask') diff --git a/wqflask/wqflask/templates/wgcna_results.html b/wqflask/wqflask/templates/wgcna_results.html index b74b84ae..2226f90c 100644 --- a/wqflask/wqflask/templates/wgcna_results.html +++ b/wqflask/wqflask/templates/wgcna_results.html @@ -3,7 +3,7 @@ {% block content %}
-

WCGNA results

+

WGCNA Results

{% endblock %} -- cgit v1.2.3 From 1109861a705eaf1dc1efb865a852f87860d0bcac Mon Sep 17 00:00:00 2001 From: DannyArends Date: Fri, 11 Sep 2015 18:16:01 +0200 Subject: Adding empty WGCNA class, and creating it in views.py --- wqflask/wqflask/views.py | 7 ++++++- wqflask/wqflask/wgcna/__init__.py | 0 wqflask/wqflask/wgcna/wgcna_analysis.py | 12 ++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100755 wqflask/wqflask/wgcna/__init__.py create mode 100644 wqflask/wqflask/wgcna/wgcna_analysis.py (limited to 'wqflask') diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index acbbf203..cd186078 100755 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -46,6 +46,9 @@ from wqflask.interval_mapping import interval_mapping from wqflask.correlation import show_corr_results from wqflask.correlation_matrix import show_corr_matrix from wqflask.correlation import corr_scatter_plot + +from wqflask.wgcna import wgcna_analysis + from utility import temp_data from base import webqtlFormData @@ -176,6 +179,8 @@ def help(): @app.route("/wgcna", methods=('POST',)) def wcgna(): + print("In wgcna, request.form is:", request.form) + template_vars = wgcna_analysis.WGCNA(request.form) return render_template("wgcna_results.html") @app.route("/news") @@ -327,7 +332,7 @@ def marker_regression_page(): 'mapmethod_rqtl_geno', 'mapmodel_rqtl_geno' ) - print("Random Print too see if it is running:", initial_start_vars) + print("Marker regression called with initial_start_vars:", initial_start_vars) start_vars = {} for key, value in initial_start_vars.iteritems(): if key in wanted or key.startswith(('value:')): diff --git a/wqflask/wqflask/wgcna/__init__.py b/wqflask/wqflask/wgcna/__init__.py new file mode 100755 index 00000000..e69de29b diff --git a/wqflask/wqflask/wgcna/wgcna_analysis.py b/wqflask/wqflask/wgcna/wgcna_analysis.py new file mode 100644 index 00000000..824b943c --- /dev/null +++ b/wqflask/wqflask/wgcna/wgcna_analysis.py @@ -0,0 +1,12 @@ + + +class WGCNA(object): + def __init__(self, start_vars): + print("Initialization of WGCNA") + + def run_wgcna(self): + print("Starting WGCNA analysis") + + def process_wgcna_results(self, results): + print("Processing WGCNA output") + -- cgit v1.2.3 From 1263f44f7ddfaeeed5e32bfb30248e3ce5cf3adf Mon Sep 17 00:00:00 2001 From: DannyArends Date: Fri, 11 Sep 2015 18:27:21 +0200 Subject: Start R and load the WGCNA library in wgcna_analysis.py --- wqflask/wqflask/wgcna/wgcna_analysis.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'wqflask') diff --git a/wqflask/wqflask/wgcna/wgcna_analysis.py b/wqflask/wqflask/wgcna/wgcna_analysis.py index 824b943c..45c87d3f 100644 --- a/wqflask/wqflask/wgcna/wgcna_analysis.py +++ b/wqflask/wqflask/wgcna/wgcna_analysis.py @@ -1,3 +1,33 @@ +# WGCNA analysis for GN2 +# Author / Maintainer: Danny Arends + +from numpy import * +from pandas import * + +import scipy as sp # SciPy +import rpy2.robjects as ro # R Objects +import pandas.rpy.common as com # R common functions + +from rpy2.robjects.packages import importr +utils = importr("utils") + +## Get pointers to some common R functions +r_library = ro.r["library"] # Map the library function +r_options = ro.r["options"] # Map the options function +r_read_csv = ro.r["read.csv"] # Map the read.csv function +r_dim = ro.r["dim"] # Map the dim function +r_c = ro.r["c"] # Map the c function +r_seq = ro.r["seq"] # Map the seq function +r_table = ro.r["table"] # Map the table function +r_names = ro.r["names"] # Map the names function +r_png = ro.r["png"] # Map the png function for plotting +r_dev_off = ro.r["dev.off"] # Map the dev.off function + + +#TODO: This should only be done once, since it is quite expensive +print(r_library("WGCNA")) # Load WGCNA +print(r_options(stringsAsFactors = False)) + class WGCNA(object): -- cgit v1.2.3 From 376d7b935a6496386bc7a906f1ed67215aeb1428 Mon Sep 17 00:00:00 2001 From: DannyArends Date: Fri, 11 Sep 2015 20:02:29 +0200 Subject: Some more work on the analysis --- wqflask/wqflask/wgcna/wgcna_analysis.py | 39 ++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 13 deletions(-) (limited to 'wqflask') diff --git a/wqflask/wqflask/wgcna/wgcna_analysis.py b/wqflask/wqflask/wgcna/wgcna_analysis.py index 45c87d3f..5b6c1c1b 100644 --- a/wqflask/wqflask/wgcna/wgcna_analysis.py +++ b/wqflask/wqflask/wgcna/wgcna_analysis.py @@ -20,23 +20,36 @@ r_c = ro.r["c"] # Map the c function r_seq = ro.r["seq"] # Map the seq function r_table = ro.r["table"] # Map the table function r_names = ro.r["names"] # Map the names function +r_sink = ro.r["sink"] # Map the sink function +r_file = ro.r["file"] # Map the file function r_png = ro.r["png"] # Map the png function for plotting r_dev_off = ro.r["dev.off"] # Map the dev.off function - -#TODO: This should only be done once, since it is quite expensive -print(r_library("WGCNA")) # Load WGCNA -print(r_options(stringsAsFactors = False)) - - - class WGCNA(object): - def __init__(self, start_vars): + def __init__(self): print("Initialization of WGCNA") - - def run_wgcna(self): - print("Starting WGCNA analysis") - - def process_wgcna_results(self, results): + log = r_file("/tmp/genenetwork_wcgna.log", open = "wt") + #r_sink(log) # Uncomment the r_sink() commands to log output from stdout/stderr to a file + #r_sink(log, type = "message") + r_library("WGCNA") # Load WGCNA - Should only be done once, since it is quite expensive + r_options(stringsAsFactors = False) + print("Initialization of WGCNA done, package loaded in R session") + r_enableWGCNAThreads = ro.r["enableWGCNAThreads"] # Map the enableWGCNAThreads function + r_pickSoftThreshold = ro.r["pickSoftThreshold"] # Map the pickSoftThreshold function + r_blockwiseModules = ro.r["blockwiseModules"] # Map the blockwiseModules function + r_labels2colors = ro.r["labels2colors"] # Map the labels2colors function + r_plotDendroAndColors = ro.r["plotDendroAndColors"] # Map the plotDendroAndColors function + print("Obtained pointers to WGCNA functions") + + def run_analysis(self, requestform): + print("Starting WGCNA analysis on dataset") + results = {} + + def process_results(self, results): print("Processing WGCNA output") + template_vars = {} + template_vars["result"] = "OK" + #r_sink(type = "message") # This restores R output to the stdout/stderr + #r_sink() # We should end the Rpy session more or less + return(dict(template_vars)) -- cgit v1.2.3 From 51faf9a4c018e45e738c6a1fe3e4ea7f05702f56 Mon Sep 17 00:00:00 2001 From: DannyArends Date: Fri, 11 Sep 2015 20:04:30 +0200 Subject: Figured out how those flask templates work, analysis broken down into 3 parts, WGCNA R package installs and loads succesfully in the gn2-docker image --- wqflask/wqflask/templates/wgcna_results.html | 1 + wqflask/wqflask/views.py | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'wqflask') diff --git a/wqflask/wqflask/templates/wgcna_results.html b/wqflask/wqflask/templates/wgcna_results.html index 2226f90c..5d654e94 100644 --- a/wqflask/wqflask/templates/wgcna_results.html +++ b/wqflask/wqflask/templates/wgcna_results.html @@ -4,6 +4,7 @@ {% block content %}

WGCNA Results

+ {{result}}
{% endblock %} diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index cd186078..cb7caf51 100755 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -180,8 +180,10 @@ def help(): @app.route("/wgcna", methods=('POST',)) def wcgna(): print("In wgcna, request.form is:", request.form) - template_vars = wgcna_analysis.WGCNA(request.form) - return render_template("wgcna_results.html") + wgcna = wgcna_analysis.WGCNA() # Start R, load the package and pointers and create the analysis + wgcnaA = wgcna.run_analysis(request.form) # Start the analysis, a wgcnaA object should be a separate long running thread + result = wgcna.process_results(wgcnaA) # After the analysis is finished store the result + return render_template("wgcna_results.html", **result) # Display them using the template @app.route("/news") def news_route(): -- cgit v1.2.3 From c02ef0ffd87e064a728886d7032fb2161948986d Mon Sep 17 00:00:00 2001 From: DannyArends Date: Fri, 11 Sep 2015 21:31:13 +0200 Subject: More fiddling with templates --- wqflask/wqflask/templates/wgcna_results.html | 2 +- wqflask/wqflask/wgcna/wgcna_analysis.py | 27 ++++++++++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) (limited to 'wqflask') diff --git a/wqflask/wqflask/templates/wgcna_results.html b/wqflask/wqflask/templates/wgcna_results.html index 5d654e94..77de3604 100644 --- a/wqflask/wqflask/templates/wgcna_results.html +++ b/wqflask/wqflask/templates/wgcna_results.html @@ -4,7 +4,7 @@ {% block content %}

WGCNA Results

- {{result}} + Phenotypes used as input: {% for k in result %} {{k[0].name}} {% endfor %}
{% endblock %} diff --git a/wqflask/wqflask/wgcna/wgcna_analysis.py b/wqflask/wqflask/wgcna/wgcna_analysis.py index 5b6c1c1b..c9709781 100644 --- a/wqflask/wqflask/wgcna/wgcna_analysis.py +++ b/wqflask/wqflask/wgcna/wgcna_analysis.py @@ -8,6 +8,8 @@ import scipy as sp # SciPy import rpy2.robjects as ro # R Objects import pandas.rpy.common as com # R common functions +from utility import helper_functions + from rpy2.robjects.packages import importr utils = importr("utils") @@ -34,21 +36,32 @@ class WGCNA(object): r_library("WGCNA") # Load WGCNA - Should only be done once, since it is quite expensive r_options(stringsAsFactors = False) print("Initialization of WGCNA done, package loaded in R session") - r_enableWGCNAThreads = ro.r["enableWGCNAThreads"] # Map the enableWGCNAThreads function - r_pickSoftThreshold = ro.r["pickSoftThreshold"] # Map the pickSoftThreshold function - r_blockwiseModules = ro.r["blockwiseModules"] # Map the blockwiseModules function - r_labels2colors = ro.r["labels2colors"] # Map the labels2colors function - r_plotDendroAndColors = ro.r["plotDendroAndColors"] # Map the plotDendroAndColors function + self.r_enableWGCNAThreads = ro.r["enableWGCNAThreads"] # Map the enableWGCNAThreads function + self.r_pickSoftThreshold = ro.r["pickSoftThreshold"] # Map the pickSoftThreshold function + self.r_blockwiseModules = ro.r["blockwiseModules"] # Map the blockwiseModules function + self.r_labels2colors = ro.r["labels2colors"] # Map the labels2colors function + self.r_plotDendroAndColors = ro.r["plotDendroAndColors"] # Map the plotDendroAndColors function print("Obtained pointers to WGCNA functions") def run_analysis(self, requestform): print("Starting WGCNA analysis on dataset") - results = {} + self.r_enableWGCNAThreads() # Enable multi threading + self.trait_db_list = [trait.strip() for trait in requestform['trait_list'].split(',')] + print("Retrieved phenotype data from database", requestform['trait_list']) + helper_functions.get_trait_db_obs(self, self.trait_db_list) + self.results = {} + for t in self.trait_list: + strains = [] + for s in t[0].data: + strains.append(s) + self.results[t] = strains + + print("Retrieved phenotype data from database") def process_results(self, results): print("Processing WGCNA output") template_vars = {} - template_vars["result"] = "OK" + template_vars["result"] = self.results #r_sink(type = "message") # This restores R output to the stdout/stderr #r_sink() # We should end the Rpy session more or less return(dict(template_vars)) -- cgit v1.2.3 From c766c1a8c6ccd9f5531ae46d7c7c91f0f1f4fa43 Mon Sep 17 00:00:00 2001 From: DannyArends Date: Fri, 11 Sep 2015 21:32:32 +0200 Subject: Removing import pandas from code --- wqflask/wqflask/wgcna/wgcna_analysis.py | 3 --- 1 file changed, 3 deletions(-) (limited to 'wqflask') diff --git a/wqflask/wqflask/wgcna/wgcna_analysis.py b/wqflask/wqflask/wgcna/wgcna_analysis.py index c9709781..37a37313 100644 --- a/wqflask/wqflask/wgcna/wgcna_analysis.py +++ b/wqflask/wqflask/wgcna/wgcna_analysis.py @@ -2,11 +2,8 @@ # Author / Maintainer: Danny Arends from numpy import * -from pandas import * - import scipy as sp # SciPy import rpy2.robjects as ro # R Objects -import pandas.rpy.common as com # R common functions from utility import helper_functions -- cgit v1.2.3 From 48d09ede615d6c836b5f11e096d000f7f177041f Mon Sep 17 00:00:00 2001 From: DannyArends Date: Sat, 19 Sep 2015 13:06:48 +0200 Subject: 2 templates, 1 for user input and 1 for showing the results --- wqflask/wqflask/templates/collections/view.html | 2 +- wqflask/wqflask/templates/wgcna_setup.html | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 wqflask/wqflask/templates/wgcna_setup.html (limited to 'wqflask') diff --git a/wqflask/wqflask/templates/collections/view.html b/wqflask/wqflask/templates/collections/view.html index f3e9f1b9..5450f903 100755 --- a/wqflask/wqflask/templates/collections/view.html +++ b/wqflask/wqflask/templates/collections/view.html @@ -38,7 +38,7 @@ -
+ {% if uc %} {% endif %} diff --git a/wqflask/wqflask/templates/wgcna_setup.html b/wqflask/wqflask/templates/wgcna_setup.html new file mode 100644 index 00000000..caf42fdb --- /dev/null +++ b/wqflask/wqflask/templates/wgcna_setup.html @@ -0,0 +1,23 @@ +{% extends "base.html" %} +{% block title %}WCGNA analysis{% endblock %} + +{% block content %} + +
+ +

WGCNA analysis parameters

+ Phenotypes used as input: {{request.form}} + + + + + + + + +
Soft threshold:
Power:
Minimum module size:
TOMtype:
mergeCutHeight:
+ +
+
+{% endblock %} + -- cgit v1.2.3 From b62b1c8e1d93bcd637ea531efbe55f8aa7aa6656 Mon Sep 17 00:00:00 2001 From: DannyArends Date: Sat, 19 Sep 2015 13:07:58 +0200 Subject: Adding views and passing the trait_list information from setup to results --- wqflask/wqflask/views.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'wqflask') diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 89302120..73899316 100755 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -177,13 +177,19 @@ def help(): doc = docs.Docs("help") return render_template("docs.html", **doc.__dict__) -@app.route("/wgcna", methods=('POST',)) -def wcgna(): +@app.route("/wgcna_setup", methods=('POST',)) +def wcgna_setup(): + print("In wgcna, request.form is:", request.form) # We are going to get additional user input for the analysis + return render_template("wgcna_setup.html", **request.form) # Display them using the template + +@app.route("/wgcna_results", methods=('POST',)) +def wcgna_results(): print("In wgcna, request.form is:", request.form) - wgcna = wgcna_analysis.WGCNA() # Start R, load the package and pointers and create the analysis - wgcnaA = wgcna.run_analysis(request.form) # Start the analysis, a wgcnaA object should be a separate long running thread - result = wgcna.process_results(wgcnaA) # After the analysis is finished store the result - return render_template("wgcna_results.html", **result) # Display them using the template + wgcna = wgcna_analysis.WGCNA() # Start R, load the package and pointers and create the analysis + wgcnaA = wgcna.run_analysis(request.form) # Start the analysis, a wgcnaA object should be a separate long running thread + result = wgcna.process_results(wgcnaA) # After the analysis is finished store the result + return render_template("wgcna_results.html", **result) # Display them using the template + @app.route("/news") def news_route(): -- cgit v1.2.3 From 60a6b72d8f739afaac6a282ea20f713e4fc5487d Mon Sep 17 00:00:00 2001 From: DannyArends Date: Sat, 19 Sep 2015 13:15:49 +0200 Subject: Adding a todo list to the code, for issue: genenetwork/genenetwork2#119 --- wqflask/wqflask/wgcna/wgcna_analysis.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'wqflask') diff --git a/wqflask/wqflask/wgcna/wgcna_analysis.py b/wqflask/wqflask/wgcna/wgcna_analysis.py index 37a37313..84cdc241 100644 --- a/wqflask/wqflask/wgcna/wgcna_analysis.py +++ b/wqflask/wqflask/wgcna/wgcna_analysis.py @@ -54,6 +54,12 @@ class WGCNA(object): self.results[t] = strains print("Retrieved phenotype data from database") + # TODO: + # Load data into R + # Calculate a good soft threshold + # Create block wise modules using WGCNA + # How many modules and how many gene per module ? + # Show the iconic WCGNA plot of the modules in the hanging tree def process_results(self, results): print("Processing WGCNA output") -- cgit v1.2.3 From b01dea7b79e47203a8554a74fa3ad46d71060135 Mon Sep 17 00:00:00 2001 From: DannyArends Date: Sun, 20 Sep 2015 12:11:09 +0200 Subject: Updating the WGCNA setup and results templates --- wqflask/wqflask/templates/wgcna_results.html | 12 ++++++++++-- wqflask/wqflask/templates/wgcna_setup.html | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'wqflask') diff --git a/wqflask/wqflask/templates/wgcna_results.html b/wqflask/wqflask/templates/wgcna_results.html index 77de3604..79c321e5 100644 --- a/wqflask/wqflask/templates/wgcna_results.html +++ b/wqflask/wqflask/templates/wgcna_results.html @@ -2,9 +2,17 @@ {% block title %}WCGNA results{% endblock %} {% block content %} -
+

WGCNA Results

- Phenotypes used as input: {% for k in result %} {{k[0].name}} {% endfor %} + Phenotype / Module table: + + + {% for k in result %} + + {% endfor %} +
PhenotypeModuleWeight
{{k[0].name}}  
+ WGCNA module plot +
{% endblock %} diff --git a/wqflask/wqflask/templates/wgcna_setup.html b/wqflask/wqflask/templates/wgcna_setup.html index caf42fdb..821e4954 100644 --- a/wqflask/wqflask/templates/wgcna_setup.html +++ b/wqflask/wqflask/templates/wgcna_setup.html @@ -3,7 +3,7 @@ {% block content %}
-
+

WGCNA analysis parameters

Phenotypes used as input: {{request.form}} -- cgit v1.2.3 From b47cd2fca0c9a835b15288aa4959867eaeb00f5a Mon Sep 17 00:00:00 2001 From: DannyArends Date: Sun, 20 Sep 2015 12:12:04 +0200 Subject: Transfering data from python to R for WGCNA analysis using Rpy2 --- wqflask/wqflask/wgcna/wgcna_analysis.py | 50 ++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 10 deletions(-) (limited to 'wqflask') diff --git a/wqflask/wqflask/wgcna/wgcna_analysis.py b/wqflask/wqflask/wgcna/wgcna_analysis.py index 84cdc241..5316fcd4 100644 --- a/wqflask/wqflask/wgcna/wgcna_analysis.py +++ b/wqflask/wqflask/wgcna/wgcna_analysis.py @@ -1,9 +1,10 @@ # WGCNA analysis for GN2 # Author / Maintainer: Danny Arends - +import sys from numpy import * import scipy as sp # SciPy import rpy2.robjects as ro # R Objects +import rpy2.rinterface as ri from utility import helper_functions @@ -16,6 +17,13 @@ r_options = ro.r["options"] # Map the options function r_read_csv = ro.r["read.csv"] # Map the read.csv function r_dim = ro.r["dim"] # Map the dim function r_c = ro.r["c"] # Map the c function +r_cat = ro.r["cat"] # Map the cat function +r_paste = ro.r["paste"] # Map the paste function +r_unlist = ro.r["unlist"] # Map the unlist function +r_unique = ro.r["unique"] # Map the unique function +r_length = ro.r["length"] # Map the length function +r_matrix = ro.r["matrix"] # Map the matrix function +r_list = ro.r["list"] # Map the list function r_seq = ro.r["seq"] # Map the seq function r_table = ro.r["table"] # Map the table function r_names = ro.r["names"] # Map the names function @@ -46,25 +54,47 @@ class WGCNA(object): self.trait_db_list = [trait.strip() for trait in requestform['trait_list'].split(',')] print("Retrieved phenotype data from database", requestform['trait_list']) helper_functions.get_trait_db_obs(self, self.trait_db_list) - self.results = {} - for t in self.trait_list: - strains = [] - for s in t[0].data: - strains.append(s) - self.results[t] = strains - print("Retrieved phenotype data from database") + self.input = {} # self.input contains the phenotype values we need to send to R + strains = [] # All the strains we have data for (contains duplicates) + traits = [] # All the traits we have data for (should not contain duplicates) + for trait in self.trait_list: + traits.append(trait[0].name) + self.input[trait[0].name] = {} + for strain in trait[0].data: + strains.append(strain) + self.input[trait[0].name][strain] = trait[0].data[strain].value + + # Transfer the load data from python to R + uStrainsR = r_unique(ro.Vector(strains)) # Unique strains in R vector + uTraitsR = r_unique(ro.Vector(traits)) # Unique traits in R vector + + r_cat("The number of unique strains:", r_length(uStrainsR), "\n") + r_cat("The number of unique traits:", r_length(uTraitsR), "\n") + + # rM is the datamatrix holding all the data in R /rows = strains columns = traits + rM = ro.r.matrix(ri.NA_Real, nrow=r_length(uStrainsR), ncol=r_length(uTraitsR), dimnames = r_list(uStrainsR, uTraitsR)) + for t in uTraitsR: + trait = t[0] # R uses vectors every single element is a vector + for s in uStrainsR: + strain = s[0] # R uses vectors every single element is a vector + rM.rx[strain, trait] = self.input[trait].get(strain) # Update the matrix location + print(trait, strain, " in python: ", self.input[trait].get(strain), "in R:", rM.rx(strain,trait)[0]) + sys.stdout.flush() + # TODO: - # Load data into R + self.results = {} # Calculate a good soft threshold # Create block wise modules using WGCNA # How many modules and how many gene per module ? # Show the iconic WCGNA plot of the modules in the hanging tree + sys.stdout.flush() def process_results(self, results): print("Processing WGCNA output") template_vars = {} - template_vars["result"] = self.results + template_vars["input"] = self.input + template_vars["results"] = self.results #r_sink(type = "message") # This restores R output to the stdout/stderr #r_sink() # We should end the Rpy session more or less return(dict(template_vars)) -- cgit v1.2.3 From c3787a404f64b1d77387d5156be1ad3271a08dee Mon Sep 17 00:00:00 2001 From: DannyArends Date: Sun, 20 Sep 2015 12:51:08 +0200 Subject: Display the results from WGCNA updated --- wqflask/wqflask/templates/wgcna_results.html | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'wqflask') diff --git a/wqflask/wqflask/templates/wgcna_results.html b/wqflask/wqflask/templates/wgcna_results.html index 79c321e5..9592c25f 100644 --- a/wqflask/wqflask/templates/wgcna_results.html +++ b/wqflask/wqflask/templates/wgcna_results.html @@ -7,12 +7,17 @@ Phenotype / Module table: - {% for k in result %} - + {% for k in results['network'] %} + {% endfor %}
PhenotypeModuleWeight
{{k[0].name}}  
{{k}}  
- WGCNA module plot - +

WGCNA module plot

+ + Embedded Image
{% endblock %} -- cgit v1.2.3 From 30f314c1572aeea2576c54c5c4c8f304932a5303 Mon Sep 17 00:00:00 2001 From: DannyArends Date: Sun, 20 Sep 2015 12:52:16 +0200 Subject: Now able to run WGCNA analysis on a user defined collection, still lots of todos --- wqflask/wqflask/wgcna/wgcna_analysis.py | 37 +++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) (limited to 'wqflask') diff --git a/wqflask/wqflask/wgcna/wgcna_analysis.py b/wqflask/wqflask/wgcna/wgcna_analysis.py index 5316fcd4..74bb6f8e 100644 --- a/wqflask/wqflask/wgcna/wgcna_analysis.py +++ b/wqflask/wqflask/wgcna/wgcna_analysis.py @@ -6,6 +6,11 @@ import scipy as sp # SciPy import rpy2.robjects as ro # R Objects import rpy2.rinterface as ri +from base import webqtlConfig # For paths and stuff + +import base64 +import array + from utility import helper_functions from rpy2.robjects.packages import importr @@ -22,8 +27,8 @@ r_paste = ro.r["paste"] # Map the paste function r_unlist = ro.r["unlist"] # Map the unlist function r_unique = ro.r["unique"] # Map the unique function r_length = ro.r["length"] # Map the length function -r_matrix = ro.r["matrix"] # Map the matrix function -r_list = ro.r["list"] # Map the list function +r_list = ro.r.list # Map the list function +r_matrix = ro.r.matrix # Map the matrix function r_seq = ro.r["seq"] # Map the seq function r_table = ro.r["table"] # Map the table function r_names = ro.r["names"] # Map the names function @@ -82,19 +87,43 @@ class WGCNA(object): print(trait, strain, " in python: ", self.input[trait].get(strain), "in R:", rM.rx(strain,trait)[0]) sys.stdout.flush() - # TODO: + # TODO: Get the user specified parameters + self.results = {} # Calculate a good soft threshold + powers = r_c(r_c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), r_seq(12, 20, 2)) + sft = self.r_pickSoftThreshold(rM, powerVector = powers, verbose = 5) + # Create block wise modules using WGCNA + network = self.r_blockwiseModules(rM, power = 6, verbose = 3) + + self.results['network'] = network + # How many modules and how many gene per module ? - # Show the iconic WCGNA plot of the modules in the hanging tree + print(r_table(network[1])) + + # The iconic WCGNA plot of the modules in the hanging tree + self.results['imgurl'] = webqtlConfig.TMPDIR + "WGCNAoutput.png" + r_png(self.results['imgurl']) + mergedColors = self.r_labels2colors(network[1]) + self.r_plotDendroAndColors(network[5][0], mergedColors, "Module colors",dendroLabels = False, hang = 0.03, addGuide = True, guideHang = 0.05) + r_dev_off() sys.stdout.flush() + def render_image(self, results): + print("pre-loading imgage results:", self.results['imgurl']) + imgfile = open(self.results['imgurl'], 'rb') + imgdata = imgfile.read() + imgB64 = imgdata.encode("base64") + bytesarray = array.array('B', imgB64) + self.results['imgdata'] = bytesarray + def process_results(self, results): print("Processing WGCNA output") template_vars = {} template_vars["input"] = self.input template_vars["results"] = self.results + self.render_image(results) #r_sink(type = "message") # This restores R output to the stdout/stderr #r_sink() # We should end the Rpy session more or less return(dict(template_vars)) -- cgit v1.2.3 From 8a5dbce3273ba296a342054e2b2c23866006b5b4 Mon Sep 17 00:00:00 2001 From: DannyArends Date: Sun, 20 Sep 2015 13:05:37 +0200 Subject: Using the webqtlConfig.TMPDIR constant and the webqtlUtil.genRandStr function --- wqflask/wqflask/templates/wgcna_results.html | 2 +- wqflask/wqflask/views.py | 2 +- wqflask/wqflask/wgcna/wgcna_analysis.py | 14 +++++++++----- 3 files changed, 11 insertions(+), 7 deletions(-) (limited to 'wqflask') diff --git a/wqflask/wqflask/templates/wgcna_results.html b/wqflask/wqflask/templates/wgcna_results.html index 9592c25f..b8a4a4f5 100644 --- a/wqflask/wqflask/templates/wgcna_results.html +++ b/wqflask/wqflask/templates/wgcna_results.html @@ -12,7 +12,7 @@ {% endfor %}

WGCNA module plot

- + Embedded Image module table --- wqflask/wqflask/templates/wgcna_results.html | 32 ++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'wqflask') diff --git a/wqflask/wqflask/templates/wgcna_results.html b/wqflask/wqflask/templates/wgcna_results.html index b8a4a4f5..077238a5 100644 --- a/wqflask/wqflask/templates/wgcna_results.html +++ b/wqflask/wqflask/templates/wgcna_results.html @@ -4,13 +4,33 @@ {% block content %}

WGCNA Results

- Phenotype / Module table: - - - {% for k in results['network'] %} - - {% endfor %} +

Soft threshold table

+
PhenotypeModuleWeight
{{k}}  
+ + {% for r in range(powers[0][0]|length) %} + + {% for c in range(powers[0]|length) %} + + {% endfor %} + + {% endfor %}
PowerSFT.R.sqslopetruncated.R.sqmean.kmedian.kmax.kAnalysis
{{powers[0][c][r]|round(3)}}
+ +

Phenotype / Module table

+ + debug: {{results['network']|length}} + debug: {{results['network'][0]|length}} + {{phenotypes[0][0]}} + + + {% for r in range(results['network'][0]|length) %} + + + + + {% endfor %} +
PhenotypeModule
{{phenotypes[r][0]}}{{results['network'][0][r]}}
+

WGCNA module plot

Embedded Image

WGCNA Results

-

Soft threshold table

+ Analysis found {{results['nmod']}} modules when scanning {{results['nphe']}} phenotypes, measured on {{results['nstr']}} strains.
+ Additional parameters settings: +
    +
  • Soft thresholds checked = {{results['requestform']['SoftThresholds']}}
  • +
  • Power used for this analysis = {{results['Power']}}
  • +
  • TomType = {{results['requestform']['TOMtype']}}
  • +
  • Minimum module size = {{results['requestform']['MinModuleSize'] }}
  • +
  • mergeCutHeight = {{results['requestform']['mergeCutHeight'] }}
  • +
+ +

Soft threshold table

{% for r in range(powers[0][0]|length) %} - + {% if powers[0][1][r] > 0.85 %} + + {% elif powers[0][1][r] > 0.75 %} + + {% else %} + + {% endif %} {% for c in range(powers[0]|length) %} {% endfor %} - + + {% endif %} + {% endfor %}
PowerSFT.R.sqslopetruncated.R.sqmean.kmedian.kmax.kAnalysis
{{powers[0][c][r]|round(3)}}
+ {% if powers[0][1][r] > 0.75 %} +
+

WGCNA module plot

+
+ Embedded Image -

Phenotype / Module table

- debug: {{results['network']|length}} - debug: {{results['network'][0]|length}} - {{phenotypes[0][0]}} +

Phenotype / Module table

- {% for r in range(results['network'][0]|length) %} + {% for r in range(results['nphe']) %} - + {% endfor %}
PhenotypeModule
{{phenotypes[r][0]}}{{results['phenotypes'][r][0]}} {{results['network'][0][r]}}
-

WGCNA module plot

- - Embedded Image +

Module eigen genes

+ + + {% for m in range(results['nmod']) %} + + {% endfor %} + + {% for r in range(results['nstr']) %} + + + {% for m in range(results['nmod']) %} + + {% endfor %} + + {% endfor %} +
Phenotype
{{results['strains'][r][0]}}{{results['network'][2][m][r]}}
{% endblock %} diff --git a/wqflask/wqflask/templates/wgcna_setup.html b/wqflask/wqflask/templates/wgcna_setup.html index 821e4954..49181938 100644 --- a/wqflask/wqflask/templates/wgcna_setup.html +++ b/wqflask/wqflask/templates/wgcna_setup.html @@ -6,17 +6,22 @@

WGCNA analysis parameters

- Phenotypes used as input: {{request.form}} - + {% if request.form['trait_list'].split(",")|length <= 4 %} + +

ERROR: Too few phenotypes as input

+ Please make sure you select enough phenotypes / genes to perform WGCNA, + your collection needs to contain at least 4 different phenotypes. You provided {{request.form['trait_list'].split(',')|length}} phenotypes as input + {% else %} + - - - - - + + + +
Soft threshold:
Power:
Minimum module size:
TOMtype:
mergeCutHeight:
Soft threshold:
Minimum module size:
TOMtype:
mergeCutHeight:
+ {% endif %}
{% endblock %} -- cgit v1.2.3 From 03c8f0c27b55a2aca93b925ac92cd3650ea6131a Mon Sep 17 00:00:00 2001 From: DannyArends Date: Thu, 8 Oct 2015 10:51:06 +0200 Subject: User inputs are now passed to the algorithm, and power is tested, and autoselected. We need to discuss which parameters we want to expose to the user. --- wqflask/wqflask/wgcna/wgcna_analysis.py | 38 +++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 9 deletions(-) (limited to 'wqflask') diff --git a/wqflask/wqflask/wgcna/wgcna_analysis.py b/wqflask/wqflask/wgcna/wgcna_analysis.py index 0cf4eeaf..b5e01ece 100644 --- a/wqflask/wqflask/wgcna/wgcna_analysis.py +++ b/wqflask/wqflask/wgcna/wgcna_analysis.py @@ -28,12 +28,14 @@ r_paste = ro.r["paste"] # Map the paste function r_unlist = ro.r["unlist"] # Map the unlist function r_unique = ro.r["unique"] # Map the unique function r_length = ro.r["length"] # Map the length function +r_unlist = ro.r["unlist"] # Map the unlist function r_list = ro.r.list # Map the list function r_matrix = ro.r.matrix # Map the matrix function r_seq = ro.r["seq"] # Map the seq function r_table = ro.r["table"] # Map the table function r_names = ro.r["names"] # Map the names function r_sink = ro.r["sink"] # Map the sink function +r_is_NA = ro.r["is.na"] # Map the is.na function r_file = ro.r["file"] # Map the file function r_png = ro.r["png"] # Map the png function for plotting r_dev_off = ro.r["dev.off"] # Map the dev.off function @@ -74,7 +76,6 @@ class WGCNA(object): # Transfer the load data from python to R uStrainsR = r_unique(ro.Vector(strains)) # Unique strains in R vector uTraitsR = r_unique(ro.Vector(traits)) # Unique traits in R vector - self.phenotypes = uTraitsR r_cat("The number of unique strains:", r_length(uStrainsR), "\n") r_cat("The number of unique traits:", r_length(uTraitsR), "\n") @@ -86,29 +87,49 @@ class WGCNA(object): for s in uStrainsR: strain = s[0] # R uses vectors every single element is a vector rM.rx[strain, trait] = self.input[trait].get(strain) # Update the matrix location - print(trait, strain, " in python: ", self.input[trait].get(strain), "in R:", rM.rx(strain,trait)[0]) + #print(trait, strain, " in python: ", self.input[trait].get(strain), "in R:", rM.rx(strain,trait)[0]) sys.stdout.flush() # TODO: Get the user specified parameters self.results = {} - # Calculate a good soft threshold - powers = r_c(r_c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), r_seq(12, 20, 2)) - self.sft = self.r_pickSoftThreshold(rM, powerVector = powers, verbose = 5) + self.results['nphe'] = r_length(uTraitsR)[0] + self.results['nstr'] = r_length(uStrainsR)[0] + self.results['phenotypes'] = uTraitsR + self.results['strains'] = uStrainsR + self.results['requestform'] = requestform + + # Calculate soft threshold if the user specified the SoftThreshold variable + if requestform.get('SoftThresholds') is not None: + powers = [int(threshold.strip()) for threshold in requestform['SoftThresholds'].rstrip().split(",")] + rpow = r_unlist(r_c(powers)) + print "SoftThresholds: {} == {}".format(powers, rpow) + self.sft = self.r_pickSoftThreshold(rM, powerVector = rpow, verbose = 5) + + print "PowerEstimate: {}".format(self.sft[0]) + self.results['PowerEstimate'] = self.sft[0] + if r_is_NA(self.sft[0]): + self.results['Power'] = 1 + else: + self.results['Power'] = self.sft[0][0] + else: + # The user clicked a button, so no soft threshold selection, just use the value the user gives + self.results['Power'] = requestform.get('Power') # Create block wise modules using WGCNA - network = self.r_blockwiseModules(rM, power = 6, verbose = 3) + network = self.r_blockwiseModules(rM, power = self.results['Power'], TOMType = requestform['TOMtype'], minModuleSize = requestform['MinModuleSize'], verbose = 3) # Save the network for the GUI self.results['network'] = network # How many modules and how many gene per module ? - print(r_table(network[1])) + print "WGCNA found {} modules".format(r_table(network[1])) + self.results['nmod'] = r_length(r_table(network[1]))[0] # The iconic WCGNA plot of the modules in the hanging tree self.results['imgurl'] = webqtlUtil.genRandStr("WGCNAoutput_") + ".png" self.results['imgloc'] = webqtlConfig.TMPDIR + self.results['imgurl'] - r_png(self.results['imgloc']) + r_png(self.results['imgloc'], width=1000, height=600) mergedColors = self.r_labels2colors(network[1]) self.r_plotDendroAndColors(network[5][0], mergedColors, "Module colors", dendroLabels = False, hang = 0.03, addGuide = True, guideHang = 0.05) r_dev_off() @@ -126,7 +147,6 @@ class WGCNA(object): print("Processing WGCNA output") template_vars = {} template_vars["input"] = self.input - template_vars["phenotypes"] = self.phenotypes template_vars["powers"] = self.sft[1:] # Results from the soft threshold analysis template_vars["results"] = self.results self.render_image(results) -- cgit v1.2.3 From b4370bebdb1f33184ffa22038cbc5d877edde5c6 Mon Sep 17 00:00:00 2001 From: DannyArends Date: Thu, 8 Oct 2015 10:55:11 +0200 Subject: Adding more comments --- wqflask/wqflask/wgcna/wgcna_analysis.py | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'wqflask') diff --git a/wqflask/wqflask/wgcna/wgcna_analysis.py b/wqflask/wqflask/wgcna/wgcna_analysis.py index b5e01ece..1174ce47 100644 --- a/wqflask/wqflask/wgcna/wgcna_analysis.py +++ b/wqflask/wqflask/wgcna/wgcna_analysis.py @@ -87,17 +87,15 @@ class WGCNA(object): for s in uStrainsR: strain = s[0] # R uses vectors every single element is a vector rM.rx[strain, trait] = self.input[trait].get(strain) # Update the matrix location - #print(trait, strain, " in python: ", self.input[trait].get(strain), "in R:", rM.rx(strain,trait)[0]) + #DEBUG: print(trait, strain, " in python: ", self.input[trait].get(strain), "in R:", rM.rx(strain,trait)[0]) sys.stdout.flush() - # TODO: Get the user specified parameters - self.results = {} - self.results['nphe'] = r_length(uTraitsR)[0] - self.results['nstr'] = r_length(uStrainsR)[0] - self.results['phenotypes'] = uTraitsR - self.results['strains'] = uStrainsR - self.results['requestform'] = requestform + self.results['nphe'] = r_length(uTraitsR)[0] # Number of phenotypes/traits + self.results['nstr'] = r_length(uStrainsR)[0] # Number of strains + self.results['phenotypes'] = uTraitsR # Traits used + self.results['strains'] = uStrainsR # Strains used in the analysis + self.results['requestform'] = requestform # Store the user specified parameters for the output page # Calculate soft threshold if the user specified the SoftThreshold variable if requestform.get('SoftThresholds') is not None: @@ -109,14 +107,14 @@ class WGCNA(object): print "PowerEstimate: {}".format(self.sft[0]) self.results['PowerEstimate'] = self.sft[0] if r_is_NA(self.sft[0]): - self.results['Power'] = 1 + self.results['Power'] = 1 # No power could be estimated else: - self.results['Power'] = self.sft[0][0] + self.results['Power'] = self.sft[0][0] # Use the estimated power else: - # The user clicked a button, so no soft threshold selection, just use the value the user gives - self.results['Power'] = requestform.get('Power') + # The user clicked a button, so no soft threshold selection + self.results['Power'] = requestform.get('Power') # Use the power value the user gives - # Create block wise modules using WGCNA + # Create the block wise modules using WGCNA network = self.r_blockwiseModules(rM, power = self.results['Power'], TOMType = requestform['TOMtype'], minModuleSize = requestform['MinModuleSize'], verbose = 3) # Save the network for the GUI -- cgit v1.2.3 From 8f25786a98447039362f74b8a37dbeacf5f07156 Mon Sep 17 00:00:00 2001 From: DannyArends Date: Thu, 8 Oct 2015 11:38:29 +0200 Subject: Minor, adding a better check for NA --- wqflask/wqflask/wgcna/wgcna_analysis.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'wqflask') diff --git a/wqflask/wqflask/wgcna/wgcna_analysis.py b/wqflask/wqflask/wgcna/wgcna_analysis.py index 1174ce47..ba806b6d 100644 --- a/wqflask/wqflask/wgcna/wgcna_analysis.py +++ b/wqflask/wqflask/wgcna/wgcna_analysis.py @@ -106,7 +106,8 @@ class WGCNA(object): print "PowerEstimate: {}".format(self.sft[0]) self.results['PowerEstimate'] = self.sft[0] - if r_is_NA(self.sft[0]): + if self.sft[0][0] == "NA": + print "No power is suitable for the analysis, just use 1" self.results['Power'] = 1 # No power could be estimated else: self.results['Power'] = self.sft[0][0] # Use the estimated power -- cgit v1.2.3 From bde835abcd76b495da82b4e107ac5e20e5663e05 Mon Sep 17 00:00:00 2001 From: DannyArends Date: Thu, 8 Oct 2015 11:42:27 +0200 Subject: Using the correct NA from Rpy2 --- wqflask/wqflask/wgcna/wgcna_analysis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wqflask') diff --git a/wqflask/wqflask/wgcna/wgcna_analysis.py b/wqflask/wqflask/wgcna/wgcna_analysis.py index ba806b6d..a714319d 100644 --- a/wqflask/wqflask/wgcna/wgcna_analysis.py +++ b/wqflask/wqflask/wgcna/wgcna_analysis.py @@ -106,7 +106,7 @@ class WGCNA(object): print "PowerEstimate: {}".format(self.sft[0]) self.results['PowerEstimate'] = self.sft[0] - if self.sft[0][0] == "NA": + if self.sft[0][0] is ri.NA_Integer: print "No power is suitable for the analysis, just use 1" self.results['Power'] = 1 # No power could be estimated else: -- cgit v1.2.3