diff options
author | Frederick Muriuki Muriithi | 2024-01-17 11:41:43 +0300 |
---|---|---|
committer | Frederick Muriuki Muriithi | 2024-01-17 11:41:43 +0300 |
commit | 33e106334a212853842c30f8c595da1099c3d84e (patch) | |
tree | a9a073bc24e2cec54f346f67d0ad1f652a5894bf | |
parent | cde57e8faeb41df27587361dcf42e235545cacb3 (diff) | |
download | gn-uploader-33e106334a212853842c30f8c595da1099c3d84e.tar.gz |
UI: Select ProbeSet study.
-rw-r--r-- | qc_app/db/__init__.py | 2 | ||||
-rw-r--r-- | qc_app/db/datasets.py | 30 | ||||
-rw-r--r-- | qc_app/templates/rqtl2/select-probeset-dataset.html | 17 | ||||
-rw-r--r-- | qc_app/templates/rqtl2/select-probeset-study-id.html | 59 | ||||
-rw-r--r-- | qc_app/upload/rqtl2.py | 132 |
5 files changed, 199 insertions, 41 deletions
diff --git a/qc_app/db/__init__.py b/qc_app/db/__init__.py index 270f1a0..36e93e8 100644 --- a/qc_app/db/__init__.py +++ b/qc_app/db/__init__.py @@ -5,4 +5,4 @@ from .populations import ( population_by_id, populations_by_species, population_by_species_and_id) -from .datasets import geno_dataset_by_species_and_population +from .datasets import geno_datasets_by_species_and_population diff --git a/qc_app/db/datasets.py b/qc_app/db/datasets.py index 8122cfa..086c103 100644 --- a/qc_app/db/datasets.py +++ b/qc_app/db/datasets.py @@ -2,7 +2,7 @@ import MySQLdb as mdb from MySQLdb.cursors import DictCursor -def geno_dataset_by_species_and_population( +def geno_datasets_by_species_and_population( conn: mdb.Connection, speciesid: int, populationid: int) -> tuple[dict, ...]: @@ -21,3 +21,31 @@ def geno_dataset_by_id(conn: mdb.Connection, dataset_id: int) -> dict: cursor.execute("SELECT * FROM GenoFreeze WHERE Id=%s", (dataset_id,)) return dict(cursor.fetchone()) + +def probeset_studies_by_species_and_population( + conn: mdb.Connection, + speciesid: int, + populationid: int) -> tuple[dict, ...]: + """Retrieve all probesets""" + with conn.cursor(cursorclass=DictCursor) as cursor: + cursor.execute( + "SELECT pf.* FROM InbredSet AS iset INNER JOIN ProbeFreeze AS pf " + "ON iset.InbredSetId=pf.InbredSetId " + "WHERE iset.SpeciesId=%(sid)s AND iset.InbredSetId=%(pid)s", + {"sid": speciesid, "pid": populationid}) + return tuple(dict(row) for row in cursor.fetchall()) + +def probeset_datasets_by_study(conn: mdb.Connection, + studyid: int) -> tuple[dict, ...]: + """Retrieve all probeset databases by study.""" + with conn.cursor(cursorclass=DictCursor) as cursor: + cursor.execute("SELECT * FROM ProbeSetFreeze WHERE ProbeFreezeId=%s", + (studyid,)) + return tuple(dict(row) for row in cursor.fetchall()) + +def probe_study_by_id(conn: mdb.Connection, studyid: int) -> dict: + """Retrieve ProbeSet study by ID""" + with conn.cursor(cursorclass=DictCursor) as cursor: + cursor.execute("SELECT * FROM ProbeFreeze WHERE Id=%s", + (studyid,)) + return dict(cursor.fetchone()) diff --git a/qc_app/templates/rqtl2/select-probeset-dataset.html b/qc_app/templates/rqtl2/select-probeset-dataset.html new file mode 100644 index 0000000..c0c6401 --- /dev/null +++ b/qc_app/templates/rqtl2/select-probeset-dataset.html @@ -0,0 +1,17 @@ +{%extends "base.html"%} +{%from "flash_messages.html" import flash_messages%} + +{%block title%}Upload R/qtl2 Bundle{%endblock%} + +{%block contents%} +<h2 class="heading">Phenotype(ProbeSet) Dataset</h2> + +<div class="explainer"> + <p>The R/qtl2 bundle you uploaded contains (a) "<strong>pheno</strong>" + file(s). This data needs to be organised under a dataset..</p> + <p>This page gives you the ability to do that.</p> +</div> + +<p style="color: red; font-weight: bold;">Under Construction</p> + +{%endblock%} diff --git a/qc_app/templates/rqtl2/select-probeset-study-id.html b/qc_app/templates/rqtl2/select-probeset-study-id.html new file mode 100644 index 0000000..bb31fde --- /dev/null +++ b/qc_app/templates/rqtl2/select-probeset-study-id.html @@ -0,0 +1,59 @@ +{%extends "base.html"%} +{%from "flash_messages.html" import flash_messages%} + +{%block title%}Upload R/qtl2 Bundle{%endblock%} + +{%block contents%} +<h2 class="heading">Phenotype(ProbeSet) Study</h2> + +<div class="explainer"> + <p>The R/qtl2 bundle you uploaded contains (a) "<strong>pheno</strong>" + file(s). This data needs to be organised under a study.</p> + <p>This page gives you the ability to do that.</p> +</div> + +<form method="POST" + action="#"> + <legend class="heading">Select from existing ProbeSet datasets</legend> + + <input type="hidden" name="species_id" value="{{species.SpeciesId}}" /> + <input type="hidden" name="population_id" + value="{{population.InbredSetId}}" /> + <input type="hidden" name="rqtl2_bundle_file" + value="{{rqtl2_bundle_file}}" /> + <input type="hidden" name="geno-dataset-id" value="{{geno_dataset.Id}}" /> + + <fieldset> + <label for="select:probe-study">Study</label> + <select id="select:probe-study" + name="probe-study-id" + required="required" + {%if studies | length == 0%}disabled="disabled"{%endif%}> + <option value="">Select a study</option> + {%for study in studies%} + <option value={{study.Id}}> + {{study.Name}} + {%if study.FullName%} + -- ({{study.FullName}}) + {%endif%} + </option> + {%endfor%} + </select> + </fieldset> + + <fieldset> + <input type="submit" + value="select study" + class="btn btn-main form-col-2" /> + </fieldset> +</form> + +<p style="color:#FE3535; padding-left:20em; font-weight:bolder;">OR</p> + +<form method="POST" + action="#"> + <legend class="heading">Create new ProbeSet dataset</legend> + <strong style="color: red;font-weight:bold;">Under construction</strong> +</form> + +{%endblock%} diff --git a/qc_app/upload/rqtl2.py b/qc_app/upload/rqtl2.py index 6ddc83f..3411f98 100644 --- a/qc_app/upload/rqtl2.py +++ b/qc_app/upload/rqtl2.py @@ -25,7 +25,11 @@ from qc_app.db import ( populations_by_species, population_by_species_and_id,) from qc_app.db.datasets import ( - geno_dataset_by_id, geno_dataset_by_species_and_population) + geno_dataset_by_id, + geno_datasets_by_species_and_population, + + probeset_datasets_by_study, + probeset_studies_by_species_and_population) rqtl2 = Blueprint("rqtl2", __name__) @@ -199,44 +203,16 @@ def check_errors(conn, *args, **kwargs): pgsrc="error"), code=307) - return None - -@rqtl2.route(("/upload/species/<int:species_id>/population/<int:population_id>" - "/rqtl2-bundle/dataset-info"), - methods=["POST"]) -def select_dataset_info(species_id: int, population_id: int): - """ - If `geno` files exist in the R/qtl2 bundle, prompt user to provide the - dataset the genotypes belong to. - """ - form = request.form - with database_connection(app.config["SQL_URI"]) as conn: - error_page = check_errors(conn, "species", "population", "rqtl2_bundle_file") - if bool(error_page): - return error_page - - species = species_by_id(conn, species_id) - population = population_by_species_and_id( - conn, species_id, population_id) - thefile = fullpath(form["rqtl2_bundle_file"]) - with ZipFile(str(thefile), "r") as zfile: - cdata = r_qtl2.control_data(zfile) - if "geno" in cdata and not bool(form.get("geno-dataset-id")): - return render_template( - "rqtl2/select-geno-dataset.html", - species=species, - population=population, - rqtl2_bundle_file=thefile.name, - datasets=geno_dataset_by_species_and_population( - conn, species_id, population_id)) - - geno_dataset = geno_dataset_by_id( - conn, int(form["geno-dataset-id"])) + if ("probe-study-id" in args and + not bool(request.form.get("probe-study-id"))): + flash("No probeset study was selected!", "alert-error alert-rqtl2") + return redirect(url_for("upload.rqtl2.select_probeset_study", + species_id=species_id, + population_id=population_id, + pgsrc="error"), + code=307) - return render_template("rqtl2/summary-info.html", - species=species, - population=population, - geno_dataset=geno_dataset) + return None @rqtl2.route(("/upload/species/<int:species_id>/population/<int:population_id>" "/rqtl2-bundle/select-geno-dataset"), @@ -249,7 +225,7 @@ def select_geno_dataset(species_id: int, population_id: int): if bool(error): return error - geno_dset = geno_dataset_by_species_and_population( + geno_dset = geno_datasets_by_species_and_population( conn, species_id, population_id) if not bool(geno_dset): flash("No genotype dataset was provided!", @@ -321,3 +297,81 @@ def create_geno_dataset(species_id: int, population_id: int): conn, species_id, population_id), rqtl2_bundle_file=request.form["rqtl2_bundle_file"], geno_dataset={**new_dataset, "id": cursor.lastrowid}) + +@rqtl2.route(("/upload/species/<int:species_id>/population/<int:population_id>" + "/rqtl2-bundle/select-probeset-study"), + methods=["POST"]) +def select_probeset_study(species_id: int, population_id: int): + """Select or create a probeset study.""" + with database_connection(app.config["SQL_URI"]) as conn: + error = check_errors( + conn, "species", "population", "rqtl2_bundle_file", "geno-dataset", + "probe-study-id") + if bool(error): + return error + + summary_page = redirect(url_for("upload.rqtl2.select_dataset_info", + species=species_by_id(conn, species_id), + population=population_by_species_and_id( + conn, species_id, population_id)), + code=307) + if not bool(probe_study_by_id(conn, int(request.form["probe-study-id"]))): + flash("Invalid study selected!", "alert-error alert-rqtl2") + return summary_page + + return summary_page + +@rqtl2.route(("/upload/species/<int:species_id>/population/<int:population_id>" + "/rqtl2-bundle/dataset-info"), + methods=["POST"]) +def select_dataset_info(species_id: int, population_id: int): + """ + If `geno` files exist in the R/qtl2 bundle, prompt user to provide the + dataset the genotypes belong to. + """ + form = request.form + with database_connection(app.config["SQL_URI"]) as conn: + error_page = check_errors(conn, "species", "population", "rqtl2_bundle_file") + if bool(error_page): + return error_page + + species = species_by_id(conn, species_id) + population = population_by_species_and_id( + conn, species_id, population_id) + thefile = fullpath(form["rqtl2_bundle_file"]) + with ZipFile(str(thefile), "r") as zfile: + cdata = r_qtl2.control_data(zfile) + if "geno" in cdata and not bool(form.get("geno-dataset-id")): + return render_template( + "rqtl2/select-geno-dataset.html", + species=species, + population=population, + rqtl2_bundle_file=thefile.name, + datasets=geno_datasets_by_species_and_population( + conn, species_id, population_id)) + geno_dataset = geno_dataset_by_id(conn, int(form["geno-dataset-id"])) + + if "pheno" in cdata and not bool(form.get("probe-study-id")): + return render_template( + "rqtl2/select-probeset-study-id.html", + species=species, + population=population, + rqtl2_bundle_file=thefile.name, + geno_dataset=geno_dataset, + studies=probeset_studies_by_species_and_population( + conn, species_id, population_id)) + + if "pheno" in cdata and not bool(form.get("probe-dataset-id")): + return render_template( + "rqtl2/select-probeset-dataset.html", + species=species, + population=population, + rqtl2_bundle_file=thefile.name, + geno_dataset=geno_dataset, + datasets=probeset_datasets_by_study( + conn, int(form["probe-study-id"]))) + + return render_template("rqtl2/summary-info.html", + species=species, + population=population, + geno_dataset=geno_dataset) |