diff options
author | Pjotr Prins | 2017-03-05 11:26:06 +0000 |
---|---|---|
committer | Pjotr Prins | 2017-03-05 11:26:06 +0000 |
commit | 4e95808ebb8bfdfae0f2a16ee54c0b2ae0664c68 (patch) | |
tree | 0bafe00bb816320f8c7f25ec1af3db30522baeda | |
parent | 1c72c2ff02eb571368051464543caf0b44521666 (diff) | |
parent | 1c9914b07559fa3706f469c94112806455053613 (diff) | |
download | genenetwork2-4e95808ebb8bfdfae0f2a16ee54c0b2ae0664c68.tar.gz |
Merge auwerx
-rw-r--r-- | wqflask/wqflask/auwerx/__init__.py | 0 | ||||
-rw-r--r-- | wqflask/wqflask/auwerx/ephewas_analysis.py | 83 | ||||
-rw-r--r-- | wqflask/wqflask/auwerx/mediation_analysis.py | 40 | ||||
-rw-r--r-- | wqflask/wqflask/auwerx/phewas_analysis.py | 132 | ||||
-rw-r--r-- | wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js | 19 | ||||
-rw-r--r-- | wqflask/wqflask/templates/ephewas_analysis.html | 15 | ||||
-rw-r--r-- | wqflask/wqflask/templates/mediation_analysis.html | 15 | ||||
-rw-r--r-- | wqflask/wqflask/templates/phewas_analysis.html | 41 | ||||
-rw-r--r-- | wqflask/wqflask/templates/show_trait.html | 17 | ||||
-rw-r--r-- | wqflask/wqflask/templates/show_trait_PheWAS_tools.html | 109 | ||||
-rw-r--r-- | wqflask/wqflask/views.py | 22 |
11 files changed, 490 insertions, 3 deletions
diff --git a/wqflask/wqflask/auwerx/__init__.py b/wqflask/wqflask/auwerx/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/wqflask/wqflask/auwerx/__init__.py diff --git a/wqflask/wqflask/auwerx/ephewas_analysis.py b/wqflask/wqflask/auwerx/ephewas_analysis.py new file mode 100644 index 00000000..2f6d6061 --- /dev/null +++ b/wqflask/wqflask/auwerx/ephewas_analysis.py @@ -0,0 +1,83 @@ +# PheWAS analysis for GN2 +# Author / Maintainer: Li Hao & Danny Arends <Danny.Arends@gmail.com> +import sys +from numpy import * +import scipy as sp # SciPy +import rpy2.robjects as ro # R Objects +import rpy2.rinterface as ri + +from base.webqtlConfig import GENERATED_IMAGE_DIR +from utility import webqtlUtil # Random number for the image +from utility import genofile_parser # genofile_parser + +import base64 +import array +import csv +import itertools + +from base import data_set +from base import trait as TRAIT + +from utility import helper_functions +from utility.tools import locate + +from rpy2.robjects.packages import importr +utils = importr("utils") + +r_library = ro.r["library"] # Map the library function +r_options = ro.r["options"] # Map the options function +r_write_table = ro.r["write.table"] # Map the write.table function +r_head = ro.r["head"] # Map the head function +r_load = ro.r["load"] # Map the head function +r_colnames = ro.r["colnames"] # Map the colnames function +r_list = ro.r["list"] # Map the list function +r_c = ro.r["c"] # Map the c (combine) function +r_print = ro.r["print"] # Map the print function +r_seq = ro.r["seq"] # Map the rep (repeat) function + +class EPheWAS(object): + def __init__(self): + print("Initialization of ePheWAS") + print(r_library("auwerx")) # Load the auwerx package + self.r_create_Pheno_aligner = ro.r["create.Pheno_aligner"] # Map the create.Pheno_aligner function + self.r_data_gatherer = ro.r["data.gatherer"] # Map the data.gatherer function + print("Initialization of ePheWAS done !") + + def run_analysis(self, requestform): + print("Starting ePheWAS analysis on dataset") + genofilelocation = locate("BXD.geno", "genotype") # Get the location of the BXD genotypes + tissuealignerloc = locate("Tissue_color_aligner.csv", "auwerx") # Get the location of the Tissue_color_aligner + + # Get user parameters, trait_id and dataset, and store/update them in self + self.trait_id = requestform["trait_id"] + self.datasetname = requestform["dataset"] + self.dataset = data_set.create_dataset(self.datasetname) + + # Print some debug + print "self.trait_id:" + self.trait_id + "\n" + print "self.datasetname:" + self.datasetname + "\n" + print "self.dataset.type:" + self.dataset.type + "\n" + + # Load in the genotypes file *sigh* to make the markermap + parser = genofile_parser.ConvertGenoFile(genofilelocation) + parser.process_csv() + snpinfo = [] + for marker in parser.markers: + snpinfo.append(marker["name"]); + snpinfo.append(marker["chr"]); + snpinfo.append(marker["Mb"]); + + rnames = r_seq(1, len(parser.markers)) + # Create the snp aligner object out of the BXD genotypes + snpaligner = ro.r.matrix(snpinfo, nrow=len(parser.markers), dimnames = r_list(rnames, r_c("SNP", "Chr", "Pos")), ncol = 3, byrow=True) + + # Create the phenotype aligner object using R + phenoaligner = self.r_create_Pheno_aligner() + + print("Initialization of ePheWAS done !") + + def process_results(self, results): + print("Processing ePheWAS output") + template_vars = {} + return(dict(template_vars)) + diff --git a/wqflask/wqflask/auwerx/mediation_analysis.py b/wqflask/wqflask/auwerx/mediation_analysis.py new file mode 100644 index 00000000..48d02dc2 --- /dev/null +++ b/wqflask/wqflask/auwerx/mediation_analysis.py @@ -0,0 +1,40 @@ +# PheWAS analysis for GN2 +# Author / Maintainer: Li Hao & Danny Arends <Danny.Arends@gmail.com> +import sys +from numpy import * +import scipy as sp # SciPy +import rpy2.robjects as ro # R Objects +import rpy2.rinterface as ri + +from base.webqtlConfig import GENERATED_IMAGE_DIR +from utility import webqtlUtil # Random number for the image +from utility import genofile_parser # genofile_parser + +import base64 +import array +import csv +import itertools + +from base import data_set +from base import trait as TRAIT + +from utility import helper_functions +from utility.tools import locate + +from rpy2.robjects.packages import importr +utils = importr("utils") + +class Mediation(object): + def __init__(self): + print("Initialization of Mediation") + print("Initialization of Mediation done !") + + def run_analysis(self, requestform): + print("Starting Mediation analysis on dataset") + print("Initialization of Mediation done !") + + def process_results(self, results): + print("Processing Mediation output") + template_vars = {} + return(dict(template_vars)) + diff --git a/wqflask/wqflask/auwerx/phewas_analysis.py b/wqflask/wqflask/auwerx/phewas_analysis.py new file mode 100644 index 00000000..e9455fba --- /dev/null +++ b/wqflask/wqflask/auwerx/phewas_analysis.py @@ -0,0 +1,132 @@ +# PheWAS analysis for GN2 +# Author / Maintainer: Li Hao & Danny Arends <Danny.Arends@gmail.com> +import sys +from numpy import * +import scipy as sp # SciPy +import rpy2.robjects as ro # R Objects +import rpy2.rinterface as ri +from pprint import pprint + +from base.webqtlConfig import GENERATED_IMAGE_DIR +from utility import webqtlUtil # Random number for the image +from utility import genofile_parser # genofile_parser + +import base64 +import array +import csv +import itertools + +from base import data_set +from base import trait as TRAIT +from base.trait import GeneralTrait + +from utility import helper_functions +from utility.tools import locate + +r_library = ro.r["library"] # Map the library function +r_options = ro.r["options"] # Map the options function +r_write_table = ro.r["write.table"] # Map the write.table function +r_head = ro.r["head"] # Map the head function +r_load = ro.r["load"] # Map the head function +r_colnames = ro.r["colnames"] # Map the colnames function +r_list = ro.r["list"] # Map the list function +r_c = ro.r["c"] # Map the c (combine) function +r_print = ro.r["print"] # Map the print function +r_seq = ro.r["seq"] # Map the rep (repeat) function + +class PheWAS(object): + def __init__(self): + print("Initialization of PheWAS") + # TODO: Loading the package should only be done once, since it is quite expensive + print(r_library("auwerx")) # Load the auwerx package + self.r_create_Pheno_aligner = ro.r["create.Pheno_aligner"] # Map the create.Pheno_aligner function + self.r_calculate_all_pvalue_parallel = ro.r["calculate.all.pvalue.parallel"] # Map the calculate.all.pvalue.parallel function + self.r_PheWASManhattan = ro.r["PheWASManhattan"] # Map the PheWASManhattan function + self.r_Stop = ro.r["throwStopError"] # Map the PheWASManhattan function + self.r_PyLoadData = ro.r["PyLoadData"] # Map the load function + print("Initialization of PheWAS done !") + + def run_analysis(self, requestform): + print("Starting PheWAS analysis on dataset") + genofilelocation = locate("BXD.geno", "genotype") # Get the location of the BXD genotypes + precompfile = locate("PheWAS_pval_EMMA_norm.RData", "auwerx") # Get the location of the pre-computed EMMA results + + # Get user parameters, trait_id and dataset, and store/update them in self + self.trait_id = requestform["trait_id"] + self.datasetname = requestform["dataset"] + self.dataset = data_set.create_dataset(self.datasetname) + self.region = int(requestform["num_region"]) + self.mtadjust = str(requestform["sel_mtadjust"]) + + # Print some debug + print "self.trait_id:" + self.trait_id + "\n" + print "self.datasetname:" + self.datasetname + "\n" + print "self.dataset.type:" + self.dataset.type + "\n" + + # GN Magic ? + self.this_trait = GeneralTrait(dataset=self.dataset, name = self.trait_id, get_qtl_info = False, get_sample_info=False) + pprint(vars(self.this_trait)) + + # Set the values we need + self.chr = str(self.this_trait.chr); + self.mb = int(self.this_trait.mb); + + # print some debug + print "location:" + self.chr + ":" + str(self.mb) + "+/-" + str(self.region) + "\n" + + # Load in the genotypes file *sigh* to make the markermap + parser = genofile_parser.ConvertGenoFile(genofilelocation) + parser.process_csv() + snpinfo = [] + for marker in parser.markers: + snpinfo.append(marker["name"]); + snpinfo.append(marker["chr"]); + snpinfo.append(marker["Mb"]); + + rnames = r_seq(1, len(parser.markers)) + # Create the snp aligner object out of the BXD genotypes + snpaligner = ro.r.matrix(snpinfo, nrow=len(parser.markers), dimnames = r_list(rnames, r_c("SNP", "Chr", "Pos")), ncol = 3, byrow=True) + + # Create the phenotype aligner object using R + phenoaligner = self.r_create_Pheno_aligner() + + self.results = {} + self.results['imgurl1'] = webqtlUtil.genRandStr("phewas_") + ".png" + self.results['imgloc1'] = GENERATED_IMAGE_DIR + self.results['imgurl1'] + self.results['mtadjust'] = self.mtadjust + print("IMAGE AT:", self.results['imgurl1'] ) + print("IMAGE AT:", self.results['imgloc1'] ) + # Create the PheWAS plot (The gene/probe name, chromosome and gene/probe positions should come from the user input) + # TODO: generate the PDF in the temp folder, with a unique name + phewasres = self.r_PheWASManhattan("Test", precompfile, phenoaligner, snpaligner, "None", self.chr, self.mb, self.region, self.results['imgloc1'] , self.mtadjust) + self.results['phewas1'] = phewasres[0] + self.results['phewas2'] = phewasres[1] + self.results['tabulardata'] = phewasres[2] + self.results['R_debuglog'] = phewasres[3] + + #self.r_PheWASManhattan(allpvalues) + #self.r_Stop() + + print("Initialization of PheWAS done !") + + def loadImage(self, path, name): + print("pre-loading imgage results:", self.results[path]) + imgfile = open(self.results[path], 'rb') + imgdata = imgfile.read() + imgB64 = imgdata.encode("base64") + bytesarray = array.array('B', imgB64) + self.results[name] = bytesarray + + def render_image(self, results): + self.loadImage("imgloc1", "imgdata1") + + def process_results(self, results): + print("Processing PheWAS output") + # TODO: get the PDF in the temp folder, and display it to the user + template_vars = {} + template_vars["results"] = self.results + self.render_image(self.results) + template_vars["R_debuglog"] = self.results['R_debuglog'] + + return(dict(template_vars)) + diff --git a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js index d6cd8134..03602d07 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js +++ b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js @@ -222,6 +222,25 @@ }; })(this)); + + $("#phewas_compute").on("click", (function(_this) { + return function() { + return submit_special("/phewas"); + }; + })(this)); + + $("#ephewas_compute").on("click", (function(_this) { + return function() { + return submit_special("/ephewas"); + }; + })(this)); + + $("#mediation_compute").on("click", (function(_this) { + return function() { + return submit_special("/mediation"); + }; + })(this)); + $("#gemma_compute").on("click", (function(_this) { return function() { var form_data, url; diff --git a/wqflask/wqflask/templates/ephewas_analysis.html b/wqflask/wqflask/templates/ephewas_analysis.html new file mode 100644 index 00000000..f49ec44f --- /dev/null +++ b/wqflask/wqflask/templates/ephewas_analysis.html @@ -0,0 +1,15 @@ +{% extends "base.html" %} +{% block title %}PheWAS analysis{% endblock %} + +{% block content %} <!-- Start of body --> +<div class="container"> + <h1>ePheWAS analysis results</h1> + <h2>Top 10 ePheWAS hits</h2> + <table width="80%"> + <tr><th>Phenotype</th><th>Phenosome</th><th>Additional</th><th>LOD</th><th>LOD<sub>BH</sub></th></tr> + <tr><td>Phenotype 1</td><td>Phenosome 1</td><td>Additional 1</td><td>LOD 1</td><td>BH 1</td></tr> + </table> + <h2>Download all ePheWAS results</h2> + <a href="" class="btn submit_special btn-primary">Download CSV</a> <a href="" class="btn submit_special btn-primary">Download RData</a> +</div> +{% endblock %} diff --git a/wqflask/wqflask/templates/mediation_analysis.html b/wqflask/wqflask/templates/mediation_analysis.html new file mode 100644 index 00000000..2804a14f --- /dev/null +++ b/wqflask/wqflask/templates/mediation_analysis.html @@ -0,0 +1,15 @@ +{% extends "base.html" %} +{% block title %}PheWAS analysis{% endblock %} + +{% block content %} <!-- Start of body --> +<div class="container"> + <h1>Mediation analysis results</h1> + <h2>Top 10 Mediation hits</h2> + <table width="80%"> + <tr><th>With</th><th>Phenosome</th><th>Additional</th><th>LOD</th><th>LOD<sub>BH</sub></th></tr> + <tr><td>Phenotype</td><td>Phenosome</td><td>Additional 1</td><td>LOD 1</td><td>BH 1</td><td><a href="" class="btn submit_special btn-primary">Mediate</a></td></tr> + </table> + <h2>Download all Mediation results</h2> + <a href="" class="btn submit_special btn-primary">Download CSV</a> <a href="" class="btn submit_special btn-primary">Download RData</a> +</div> +{% endblock %} diff --git a/wqflask/wqflask/templates/phewas_analysis.html b/wqflask/wqflask/templates/phewas_analysis.html new file mode 100644 index 00000000..91c47a10 --- /dev/null +++ b/wqflask/wqflask/templates/phewas_analysis.html @@ -0,0 +1,41 @@ +{% extends "base.html" %} +{% block title %}PheWAS analysis{% endblock %} + +{% block content %} <!-- Start of body --> +<div class="container"> + <h1>PheWAS analysis results</h1> + <h3>R debug log</h3> + {% for i in range(results['R_debuglog']|length) %} + {{ results['R_debuglog'][i]}}<br> + {%- endfor %} + <h2>Top 5 PheWAS hits</h2> + <table width="100%"> + <tr><th>GN ID</th><th width="60%">Phenotype</th><th>Phenosome</th><th>LOD</th><th>LOD<sub>( {{ results['mtadjust'] }} )</sub></th></tr> + {% for r in range(5) %} + <tr> + {% for c in range(results['tabulardata']|length) %} + <td> + {% if c >= 3 %} + {{results['tabulardata'][c][r]|float|round(2)}} + {% else %} + {{results['tabulardata'][c][r]}} + {% endif %} + </td> + {%- endfor %} + {%- endfor %} + + </table> +<!-- {{ results['phewas1'] }} + {{ results['phewas2'] }} + {{ results['phewas3'] }} --> + <h2>Download PheWAS results</h2> + <a href="" class="btn submit_special btn-primary">Download CSV</a> <a href="" class="btn submit_special btn-primary">Download RData</a> + <h3>PheWAS manhattan plot</h3> + <a href="/tmp/{{ results['imgurl1'] }}"> + <img alt="Embedded Image" src="data:image/png;base64, + {% for elem in results['imgdata1'] -%} + {% print("%c"|format(elem)) %} + {%- endfor %} + " /></a> +</div> +{% endblock %} diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index 772c4314..d9566df1 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -93,12 +93,25 @@ </div> </div> <div class="panel panel-default"> - <div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#collapseFive" aria-expanded="true"> + <div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#collapseFive"> + <h3 class="panel-title"> + <span class="glyphicon glyphicon-chevron-down"></span> PheWAS + </h3> + </div> + <div id="collapseFive" class="panel-collapse collapse in"> + <div class="panel-body"> + {% include 'show_trait_PheWAS_tools.html' %} + </div> + <div id="alert_placeholder"></div> + </div> + </div> + <div class="panel panel-default"> + <div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#collapseSix" aria-expanded="true"> <h3 class="panel-title"> <span class="glyphicon glyphicon-chevron-up"></span> Review and Edit Data </h3> </div> - <div id="collapseFive" class="panel-collapse collapse" aria-expanded="true"> + <div id="collapseSix" class="panel-collapse collapse" aria-expanded="true"> <div class="panel-body"> {% include 'show_trait_edit_data.html' %} </div> diff --git a/wqflask/wqflask/templates/show_trait_PheWAS_tools.html b/wqflask/wqflask/templates/show_trait_PheWAS_tools.html new file mode 100644 index 00000000..c284c456 --- /dev/null +++ b/wqflask/wqflask/templates/show_trait_PheWAS_tools.html @@ -0,0 +1,109 @@ +<div> + <div class="col-xs-4"> + <div class="tabbable"> <!-- Only required for left/right tabs --> + + <ul class="nav nav-pills"> + <li class="active"> + <a href="#PheWAS" data-toggle="tab">PheWAS</a> + </li> + <li> + <a href="#ePheWAS" data-toggle="tab">ePheWAS</a> + </li> + <li> + <a href="#mediation" data-toggle="tab">Mediation</a> + </li> + + <div class="tab-content"> + <div class="tab-pane active" id="PheWAS"> + <div style="margin-top: 25px" class="form-horizontal"> + <br>PheWAS options: +<!-- + <div class="mapping_method_fields form-group"> + <label for="num_strain_limit" style="text-align:left;" class="col-xs-3 control-label">Strain limit</label> + <div style="margin-left: 20px;" class="col-xs-4 controls"> + <input name="num_strain_limit" value="15" type="text" class="form-control"> + </div> + </div> --> + <div class="mapping_method_fields form-group"> + <label for="num_region" style="text-align:left;" class="col-xs-3 control-label">Region size</label> + <div style="margin-left: 20px;" class="col-xs-4 controls"> + <input name="num_region" value="2" type="text" class="form-control"> + </div> + </div> + <div class="mapping_method_fields form-group"> + <label for="mtadjust" style="text-align:left;" class="col-xs-3 control-label">P adjustment</label> + <div style="margin-left: 20px;width: 225px;" class="col-xs-4 controls"> + <select name="sel_mtadjust" class="form-control"> + <option value="fdr">False Discovery Rate</option> + <option value="BH">Benjamini Hochberg</option> + <option value="holm">Holm</option> + <option value="hochberg">Hochberg</option> + <option value="hommel">Hommel</option> + <option value="bonferroni">Bonferroni</option> + + </select> + </div> + </div> + <div class="form-group"> + <div style="padding-left:15px;" class="controls"> + <button id="phewas_compute" class="btn btn-primary submit_special" title="Compute PheWAS"> + <i class="icon-ok-circle icon-white"></i> Compute + </button> + </div> + </div> + </div> + </div> <!-- end of the PheWAS tab --> + + <div class="tab-pane" id="ePheWAS"> + <div style="margin-top: 25px" class="form-horizontal"> + <br>ePheWAS options: + <div class="mapping_method_fields form-group"> + <label for="strain_limit" style="text-align:left;" class="col-xs-3 control-label">ePheWAS opt 1</label> + <div style="margin-left: 20px;" class="col-xs-4 controls"> + <input name="num_strain_limit" value="15" type="text" class="form-control"> + </div> + </div> + <div class="form-group"> + <div style="padding-left:15px;" class="controls"> + <button id="ephewas_compute" class="btn submit_special btn-primary" title="Compute ePheWAS"> + <i class="icon-ok-circle icon-white"></i> Compute + </button> + </div> + </div> + </div> + </div> <!-- end of the ePheWAS tab --> + + <div class="tab-pane" id="mediation"> + <div style="margin-top: 25px" class="form-horizontal"> + <br>Mediation options: + <div class="mapping_method_fields form-group"> + <label for="strain_limit" style="text-align:left;" class="col-xs-3 control-label">Mediation opt 1</label> + <div style="margin-left: 20px;" class="col-xs-4 controls"> + <input name="num_strain_limit" value="15" type="text" class="form-control"> + </div> + </div> + <div class="form-group"> + <div style="padding-left:15px;" class="controls"> + <button id="mediation_compute" class="btn submit_special btn-primary" title="Run mediation analysis"> + <i class="icon-ok-circle icon-white"></i> Compute + </button> + </div> + </div> + </div> + </div> <!-- end of the Mediation tab --> + + </div> + </ul> + </div> + </div> + <div class="col-xs-6"> + <dl> + <dt>Phewas</dt> + <dd>PLaceholder.</dd> + <dt>ePhewas</dt> + <dd>PLaceholder.</dd> + <dt>Mediation</dt> + <dd>PLaceholder.</dd> + </dl> + </div> +</div> diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index c3b91c6e..ee135d4c 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -51,7 +51,8 @@ from wqflask.correlation_matrix import show_corr_matrix from wqflask.correlation import corr_scatter_plot from wqflask.wgcna import wgcna_analysis from wqflask.ctl import ctl_analysis -#from wqflask.trait_submission import submit_trait +from wqflask.auwerx import phewas_analysis +from wqflask.auwerx import ephewas_analysis from utility import webqtlUtil from utility import temp_data @@ -265,6 +266,25 @@ def wcgna_results(): 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("/phewas", methods=('POST',)) +def phewas(): + logger.info("In phewas, request.form is:", request.form) # We are going to get additional user input for the analysis + phewasO = phewas_analysis.PheWAS() # Start R, load the package and pointers and create the analysis + phewasA = phewasO.run_analysis(request.form) + result = phewasO.process_results(phewasA) # After the analysis is finished store the result + return render_template("phewas_analysis.html", **result) # Display them using the template + +@app.route("/ephewas", methods=('POST',)) +def ephewas(): + logger.info("In ephewas, request.form is:", request.form) # We are going to get additional user input for the analysis + ephewasO = ephewas_analysis.EPheWAS() # Start R, load the package and pointers and create the analysis + return render_template("ephewas_analysis.html", **request.form) # Display them using the template + +@app.route("/mediation", methods=('POST',)) +def mediation(): + logger.info("In mediation, request.form is:", request.form) # We are going to get additional user input for the analysis + return render_template("mediation_analysis.html", **request.form) # Display them using the template + @app.route("/ctl_setup", methods=('POST',)) def ctl_setup(): logger.info("In ctl, request.form is:", request.form) # We are going to get additional user input for the analysis |