From 17defa03f395aa9895b524ef3125e138b3987507 Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Tue, 17 Sep 2024 16:57:39 -0500 Subject: Display some genotype information. --- uploader/genotypes/models.py | 41 +++++++ uploader/genotypes/views.py | 39 ++++++- uploader/templates/genotypes/index.html | 8 -- uploader/templates/genotypes/list-genotypes.html | 142 +++++++++++++++++++++++ 4 files changed, 220 insertions(+), 10 deletions(-) create mode 100644 uploader/genotypes/models.py create mode 100644 uploader/templates/genotypes/list-genotypes.html (limited to 'uploader') diff --git a/uploader/genotypes/models.py b/uploader/genotypes/models.py new file mode 100644 index 0000000..53c5fb8 --- /dev/null +++ b/uploader/genotypes/models.py @@ -0,0 +1,41 @@ +"""Functions for handling genotypes.""" +from typing import Optional + +import MySQLdb as mdb +from MySQLdb.cursors import DictCursor + +from uploader.db_utils import debug_query + +def genocode_by_population( + conn: mdb.Connection, population_id: int) -> tuple[dict, ...]: + """Get the allele/genotype codes.""" + with conn.cursor(cursorclass=DictCursor) as cursor: + cursor.execute("SELECT * FROM GenoCode WHERE InbredSetId=%s", + (population_id,)) + return tuple(dict(item) for item in cursor.fetchall()) + + +def genotype_markers_count(conn: mdb.Connection, species_id: int) -> int: + """Find the total count of the genotype markers for a species.""" + with conn.cursor(cursorclass=DictCursor) as cursor: + cursor.execute( + "SELECT COUNT(Name) AS markers_count FROM Geno WHERE SpeciesId=%s", + (species_id,)) + return int(cursor.fetchone()["markers_count"]) + + +def genotype_markers( + conn: mdb.Connection, + species_id: int, + offset: int = 0, + limit: Optional[int] = None +) -> tuple[dict, ...]: + """Retrieve markers from the database.""" + _query = "SELECT * FROM Geno WHERE SpeciesId=%s" + if bool(limit) and limit > 0: + _query = _query + f" LIMIT {limit} OFFSET {offset}" + + with conn.cursor(cursorclass=DictCursor) as cursor: + cursor.execute(_query, (species_id,)) + debug_query(cursor) + return tuple(dict(row) for row in cursor.fetchall()) diff --git a/uploader/genotypes/views.py b/uploader/genotypes/views.py index 885e008..0618949 100644 --- a/uploader/genotypes/views.py +++ b/uploader/genotypes/views.py @@ -7,13 +7,17 @@ from flask import (flash, render_template, current_app as app) -from uploader.datautils import order_by_family from uploader.authorisation import require_login from uploader.db_utils import database_connection from uploader.species.models import all_species, species_by_id +from uploader.datautils import safe_int, order_by_family, enumerate_sequence from uploader.population.models import (populations_by_species, population_by_species_and_id) +from .models import (genotype_markers, + genotype_markers_count, + genocode_by_population) + genotypesbp = Blueprint("genotypes", __name__) @genotypesbp.route("populations/genotypes", methods=["GET"]) @@ -72,4 +76,35 @@ def select_population(species_id: int): @require_login def list_genotypes(species_id: int, population_id: int): """List genotype details for species and population.""" - return f"Would list geno info for population {population_id} from species {species_id}" + with database_connection(app.config["SQL_URI"]) as conn: + species = species_by_id(conn, species_id) + if not bool(species): + flash("Invalid species provided!", "alert-danger") + return redirect(url_for("species.populations.genotypes.index")) + + population = population_by_species_and_id( + conn, species_id, population_id) + if not bool(population): + flash("Invalid population selected!", "alert-danger") + return redirect(url_for( + "species.populations.genotypes.select_population", + species_id=species_id)) + + start_from = safe_int(request.args.get("start_from") or 0) + if start_from < 0: + start_from = 0 + count = safe_int(request.args.get("count") or 20) + markers = enumerate_sequence( + genotype_markers(conn, species_id, offset=start_from, limit=count), + start=start_from+1) + return render_template("genotypes/list-genotypes.html", + species=species, + population=population, + genocode=genocode_by_population( + conn, population_id), + total_markers=genotype_markers_count( + conn, species_id), + start_from=start_from, + count=count, + markers=markers, + activelink="list-genotypes") diff --git a/uploader/templates/genotypes/index.html b/uploader/templates/genotypes/index.html index 9ffea73..e749f5a 100644 --- a/uploader/templates/genotypes/index.html +++ b/uploader/templates/genotypes/index.html @@ -25,12 +25,4 @@ {{select_species_form(url_for("species.populations.genotypes.index"), species)}} - -
+ The genotype encoding used for the "{{population.FullName}}" population from + the "{{species.FullName}}" species is as shown in the table below. +
+Allele Type | +Allele Symbol | +Allele Value | +||||
---|---|---|---|---|---|---|
{{row.AlleleType}} | +{{row.AlleleSymbol}} | +{{row.DatabaseValue if row.DatabaseValue is not none else "NULL"}} | +||||
+ + There is no explicit genotype encoding defined for this population. + | +
+ There are a total of {{total_markers}} genotype markers for this species. +
+# | +Marker Name | +Chr | ++ Location (Mb) | +Source | +Source2 | +|
---|---|---|---|---|---|---|
{{marker.sequence_number}} | +{{marker.Marker_Name}} | +{{marker.Chr}} | +{{marker.Mb}} | +{{marker.Source}} | +{{marker.Source2}} | +|
+ + No markers to display! + | +