Feature/SUPeR expansion (expand other 13 DBs from NIE pseudobulk to other DBs for MVP) - #331
Merged
asherpasha merged 4 commits intoSep 22, 2026
Conversation
…abase api/models/umap_dynamic.py follows efp_dynamic.py: UMAP_DATABASES maps each database to its species, and a factory builds the coords and expression models per database with unique class names. Only arabidopsis_NIE_umap is registered here, so this is a pure refactor. UMAPUtils.get_tables is now a lookup against that registry and returns the same dict, so the routes and responses are untouched. The escaped database name is wrapped in str() before the lookup. Proof of no behaviour change: tests/resources/test_umap_gene_expression.py passes without a single edit.
26 fixture dumps generated from the full dumps from prod that I checked myself: 3 genes per pseudobulk database carrying all of that database's rows per gene including Mean_CTRL, and 8 cells per UMAP database with each gene's expression trimmed to those cells. Every UMAP gene keeps at least one gap cell, so a server that filled in zeros would fail the tests. Each file keeps its source dump's header, DDL and footer verbatim; only the data rows were cut down. Filenames follow the NIE convention: <db>_dump.sql for pseudobulk and <db>.sql for UMAP. Verified before wiring: every CREATE DATABASE name matches its filename, and every rows-per-gene matches the manifest and the dataset table. fixture_manifest.json stays uncommitted.
Each entry copies arabidopsis_NIE_pseudobulk field for field; only species and gene_id_pattern differ, and only for rice_OW_pseudobulk. The expression endpoint is catalog-driven, so no endpoint code changes. pseudobulk_std.assigned_databases goes 1 -> 14. databases stays ASCII-sorted at 207 entries. UMAP databases get no catalog entry: they have no sample_data table, so an entry would build a model for a table that does not exist. schema_verified / schema_source are copied from NIE but so far rest on the dump files, not prod. Confirm with verify_master_against_prod.py after IT loads the databases, before merging. test_gene_expression.py's expected set is now the explicit list of all 14 pseudobulk databases, written out rather than derived from the catalog so the test still fails if the catalog gains an unintended pseudobulk_std entry.
UMAP_DATABASES gains the 13 new databases with their species. Routes, response shapes and the existing NIE tests are untouched. tests/resources/test_superviewer_databases.py drives both endpoints from literal tables, with a subTest per database and gene. The literals were taken from the committed fixtures; the tests never read the manifest. Pseudobulk: every fixture gene returns its database's full row count with the name/value/value_std keys and exactly one Mean_CTRL carrying its stored values. Several databases share a row count, so the Mean_CTRL values are what catch a bind pointing at the wrong database. UMAP: coordinates return exactly the fixture cells, and each gene returns exactly its non-zero cells, so a server filling in gap cells would fail.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Registers 13 more SUPeR Viewer dataset pairs alongside
arabidopsis_NIE_*, which shipped in #330. Pseudobulk databases are catalog entries only; UMAP databases move from a hand-written model file to a registry dict (umap_dynamic.py) that essentially is the same Model simply 'renamed'. First @asherpasha you'll need to upload the full DB set and then we can merge this PR in (I'll do some testing as well).1. Summary
Four commits, each reviewable on its own.
d6a605capi/models/arabidopsis_NIE_umap.pyand theif/elifinUMAPUtils.get_tableswithapi/models/umap_dynamic.py: aUMAP_DATABASESdict mapping database → species, and a factory that builds the coords and expression models per database. Modelled onefp_dynamic.py. Onlyarabidopsis_NIE_umapis registered here.6f871f1SQLALCHEMY_BINDSentry inconfig/BAR_API.cfgand one seed line inconfig/init.shper database.496ebb8combined_master.json, each copyingarabidopsis_NIE_pseudobulkfield for field exceptspecies/gene_id_pattern(different only forrice_OW_pseudobulk).pseudobulk_std.assigned_databases1 → 14. Updates the expected set intest_gene_expression.pyto the explicit 14 names.bafa6fetests/resources/test_superviewer_databases.py.d6a605cis behaviour-preserving.tests/resources/test_umap_gene_expression.pyis byte-identical todevand still passes, so the refactor changed no route, response or error.UMAP databases get no catalog entry: they have no
sample_datatable, so an entry would build a model for a table that doesn't exist. The registry dict is a code-level list instead.Test literals in
test_superviewer_databases.pywere taken from the committed fixtures and are checked againstfixture_manifest.json; the tests never read the manifest at runtime. Suite from an empty MySQL seeded only throughinit.sh: 122 passed, 91 subtests passed, 3 failed. The 3 failures aredev's existing baseline (mfinderexit 127, two Redis refusals onlocalhost) and this PR touches none of them. flake8 clean.Both endpoints were also exercised directly against a local instance (47 requests): row counts and
Mean_CTRLvalues match the fixtures for all 14 pseudobulk databases, and across all 13 UMAP databases every expression key is a coordinates key with no gap cell ever returned. That is fixture data, so it does not substitute for the staging check in the merge gate.2. Merge checks
Do not merge on staging until both pass. Both need the 26 databases on prod first; I can run them.
verify_master_against_prod.pyon staging server MySQL against liveinformation_schema. The 13 new entries copyschema_verified: trueandschema_source: "prod_information_schema"from the NIE entry, but so far those claims rest on the dump files, not on prod. The script covers only the 13 pseudobulk entries — the UMAP databases aren't catalogued, so nothing verifies them this way.Mean_CTRLvalueandvalue_stdmust equal the literals intests/resources/test_superviewer_databases.py. For each new UMAP database, the coordinates response and each fixture gene's response must return 200.3. Databases (reference)
26 new databases. Names are case-sensitive; note the capitalised
OW.4. Known data gaps/inconsistences, not addressed here
Counts below come from a full-dump scan (21 Sept 2026), not from anything in this PR. The committed fixtures use pattern-valid gene keys only, so none of this affects the tests.
shoot_zhang— 9,570 symbol-keyed genes, some containing spaces or slashes. Not reachable through the API's gene ID pattern. Separately, the UMAP route declares<string:gene_id>, which does not match slashes, so a slash-bearing key is rejected by Flask routing (404) before any handler runs. The pseudobulk route uses<path:gene_id>and has no such limit.root_shahan— 21,437 lncRNA keys (AthLNC+ six digits), plus 7ATMG…-Nduplicates. Real loci with no AGI, so not reachable through the Arabidopsis pattern.NIE— 6,423 symbol-keyed genes; 11 AGI keys carrying 138 rows (two genes each); onenanrow in the UMAP table.seed_martin— somedata_bot_idvalues end in an apostrophe, e.g.3DAP ii1'(integument-prime names). The committed fixture has 3 such values across 9 rows. They're backslash-escaped in the dumps, so anything parsing a dump or rendering sample names must handle them — a naive single-quote parser silently drops those rows.Reaching the symbol- and lncRNA-keyed genes needs a decision about gene ID patterns that would affect 30+ databases, so it's deliberately left out of this PR. Note that widening a pattern alone would not be sufficient for slash-bearing keys on the UMAP endpoint — its route converter would have to change too.
5. Contributor note
docker-compose.ymlbind-mounts onlyapi/,tests/andconfig/databases/.combined_master.json,config/BAR_API.cfgandconfig/init.share baked into the image, andapp.pyruns without a reloader. After changing any of those three, rebuild:Otherwise local tests run against stale copies — the usual symptom is a newly catalogued database returning
"Invalid species or gene ID".