aboutsummaryrefslogtreecommitdiff
path: root/uploader
diff options
context:
space:
mode:
authorFrederick Muriuki Muriithi2025-07-08 16:05:40 -0500
committerFrederick Muriuki Muriithi2025-07-08 16:05:40 -0500
commit3f658b0af6d3cf84a686c8d7eb948929520e6323 (patch)
tree021c05b42c551417e117b4965ce64813b4d50781 /uploader
parent7316e4a3bacaa1c4984fb2068fac1de9f839edf4 (diff)
downloadgn-uploader-3f658b0af6d3cf84a686c8d7eb948929520e6323.tar.gz
Fix entry/selection of population families.HEADmain
Populations can be grouped into families for presentation in the menus. They can also be left ungrouped. These "families" are general categories of data, whose only effect is to present the selection of the populations from the menus in a more organised form. The families can also differ from species to species, though there are some very general categories that span multiple (all?) species. This commit takes all the above into consideration, relaxing the entry constraints and making entry of the families a lot more flexible.
Diffstat (limited to 'uploader')
-rw-r--r--uploader/population/models.py22
-rw-r--r--uploader/population/views.py4
-rw-r--r--uploader/templates/populations/create-population.html39
3 files changed, 44 insertions, 21 deletions
diff --git a/uploader/population/models.py b/uploader/population/models.py
index d78a821..4d95065 100644
--- a/uploader/population/models.py
+++ b/uploader/population/models.py
@@ -26,13 +26,23 @@ def populations_by_species(conn: mdb.Connection, speciesid) -> tuple:
return tuple()
+__GENERIC_POPULATION_FAMILIES__ = (
+ "Reference Populations (replicate average, SE, N)",
+ "Crosses and Heterogeneous Stock (individuals)",
+ "Groups Without Genotypes")
-def population_families(conn) -> tuple:
+def population_families(conn, species_id: int) -> tuple[str]:
"""Fetch the families under which populations are grouped."""
with conn.cursor(cursorclass=DictCursor) as cursor:
+ paramstr = ", ".join(["%s"] * len(__GENERIC_POPULATION_FAMILIES__))
cursor.execute(
- "SELECT DISTINCT(Family) FROM InbredSet WHERE Family IS NOT NULL")
- return tuple(row["Family"] for row in cursor.fetchall())
+ "SELECT DISTINCT(Family) FROM InbredSet "
+ "WHERE SpeciesId=%s "
+ "AND Family IS NOT NULL "
+ f"AND Family NOT IN ({paramstr})",
+ (species_id, *__GENERIC_POPULATION_FAMILIES__))
+ return __GENERIC_POPULATION_FAMILIES__ + tuple(
+ row["Family"] for row in cursor.fetchall())
def population_genetic_types(conn) -> tuple:
@@ -47,9 +57,11 @@ def population_genetic_types(conn) -> tuple:
def save_population(cursor: mdb.cursors.Cursor, population_details: dict) -> dict:
"""Save the population details to the db."""
cursor.execute("SELECT DISTINCT(Family), FamilyOrder FROM InbredSet "
- "WHERE Family IS NOT NULL AND Family != '' "
+ "WHERE SpeciesId=%s "
+ "AND Family IS NOT NULL AND Family != '' "
"AND FamilyOrder IS NOT NULL "
- "ORDER BY FamilyOrder ASC")
+ "ORDER BY FamilyOrder ASC",
+ (population_details["SpeciesId"],))
_families = {
row["Family"]: int(row["FamilyOrder"])
for row in cursor.fetchall()
diff --git a/uploader/population/views.py b/uploader/population/views.py
index 270dd5f..87a33d9 100644
--- a/uploader/population/views.py
+++ b/uploader/population/views.py
@@ -100,7 +100,7 @@ def create_population(species_id: int):
return render_template(
"populations/create-population.html",
species=species,
- families = population_families(conn),
+ families = population_families(conn, species["SpeciesId"]),
genetic_types = population_genetic_types(conn),
mapping_methods=(
{"id": "0", "value": "No mapping support"},
@@ -153,7 +153,7 @@ def create_population(species_id: int):
"FullName": population_fullname,
"InbredSetCode": request.form.get("population_code") or None,
"Description": request.form.get("population_description") or None,
- "Family": request.form.get("population_family") or None,
+ "Family": request.form.get("population_family").strip() or None,
"MappingMethodId": request.form.get("population_mapping_method_id"),
"GeneticType": request.form.get("population_genetic_type") or None
})
diff --git a/uploader/templates/populations/create-population.html b/uploader/templates/populations/create-population.html
index c0c4f45..007b6bf 100644
--- a/uploader/templates/populations/create-population.html
+++ b/uploader/templates/populations/create-population.html
@@ -154,24 +154,35 @@
{%else%}
class="form-group"
{%endif%}>
- <label for="select-population-family" class="form-label">Family</label>
- <select id="select-population-family"
- name="population_family"
- class="form-control"
- required="required">
- <option value="">Please select a family</option>
+ <label for="txt-population-family" class="form-label">Family</label>
+ <input type="text"
+ id="txt-population-family"
+ name="population_family"
+ class="form-control"
+ list="families-list" />
+ <datalist id="families-list">
{%for family in families%}
- <option value="{{family}}"
- {%if error_values.population_family == family%}
- selected="selected"
- {%endif%}>{{family}}</option>
+ <option value="{{family}}">{{family}}</option>
{%endfor%}
- </select>
+ </datalist>
<small class="form-text text-muted">
<p>
- This is a rough grouping of the populations in GeneNetwork into lists
- of common types of populations.
- </p>
+ This is <strong>optional</strong> metadata. It is used to group
+ populations into "families" for presentation in the menus.
+ {%if families | length > 0%}
+ Examples of currently existing families are:
+ <ul>
+ {%for family in families[0:7]%}
+ <li>{{family}}</li>
+ {%endfor%}
+ <li>etc.</li>
+ </ul>
+ {%endif%}
+
+ You can
+ {%if families|length>0%} select from existing families, or {%endif%}
+ create a new family by typing in the input box above. You can also
+ leave the family blank.</p>
</small>
</div>