Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/apis/catalog/brc-analytics-catalog/common/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export interface BRCDataCatalogGenome {
accession: string;
annotationStatus: string | null;
chromosomes: number | null;
commonName: string | null;
commonNames: string[];
coverage: string | null;
galaxyDatacacheUrl: string | null;
gcPercent: number | null;
Expand Down Expand Up @@ -50,7 +50,7 @@ export interface BRCDataCatalogGenome {
export interface BRCDataCatalogOrganism {
assemblyCount: number;
assemblyTaxonomyIds: string[];
commonName: string | null;
commonNames: string[];
genomes: BRCDataCatalogGenome[];
ncbiTaxonomyId: string;
otherTaxa: string[] | null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,15 +161,16 @@ export const buildChromosomes = (
};

/**
* Build props for the common name cell.
* Build props for the common names cell.
* @param entity - Organism or genome entity.
* @returns Props to be used for the cell.
* @returns Props for the NTagCell component.
*/
export const buildCommonName = (
export const buildCommonNames = (
entity: BRCDataCatalogOrganism | BRCDataCatalogGenome
): ComponentProps<typeof BasicCell> => {
): ComponentProps<typeof NTagCell> => {
return {
value: entity.commonName,
label: "common names",
values: entity.commonNames,
};
};

Expand Down
2 changes: 1 addition & 1 deletion app/views/WorkflowsView/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export type BaseWorkflowAssembly = Pick<
* at runtime but only typed on site-specific WorkflowEntity extensions.
*/
export type WorkflowAssembly = BaseWorkflowAssembly & {
commonName: string;
commonNames: string[];
taxonomicLevelRealm: string;
};

Expand Down
23 changes: 12 additions & 11 deletions app/views/WorkflowsView/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,18 @@ function findAssemblyByTaxonomyId(
}

/**
* Returns the common name of the assembly, or "Any" if the assembly is undefined.
* `commonName` is only present on BRC assemblies; GA2 assemblies will return "Any".
* Returns "null" as a string when the assembly exists but commonName is null.
* Returns the common names of the assembly, or ["Any"] if the assembly is undefined.
* `commonNames` is only present on BRC assemblies; GA2 assemblies will return ["Any"].
* Returns ["None"] when the assembly exists but has no common names.
* Each name becomes its own filter facet bucket.
* @param assembly - Assembly.
* @returns The common name, "null", or "Any".
* @returns The list of common names, ["None"], or ["Any"].
*/
function getCommonName(assembly: AssemblyContract | undefined): string {
// A missing commonName field (GA2 assemblies) reads as "Any"; a present-but-
// null commonName (BRC) reads as the string "null".
if (!assembly || assembly.commonName === undefined) return "Any";
return assembly.commonName ?? "null";
function getCommonNames(assembly: AssemblyContract | undefined): string[] {
// A missing commonNames field (GA2 assemblies) reads as ["Any"]; a present-but-
// empty commonNames (BRC) reads as ["None"].
if (!assembly || assembly.commonNames === undefined) return ["Any"];
return assembly.commonNames.length ? assembly.commonNames : ["None"];
}

/**
Expand Down Expand Up @@ -188,15 +189,15 @@ function indexAssemblyByTaxonomyId(

/**
* Maps an Assembly to the workflow assembly fields.
* Includes all taxonomy fields plus site-specific fields (commonName, taxonomicLevelRealm)
* Includes all taxonomy fields plus site-specific fields (commonNames, taxonomicLevelRealm)
* which are present at runtime for all sites but only typed on site-specific WorkflowEntity extensions.
* If the assembly is undefined, returns default values for the properties.
* @param assembly - The assembly to map.
* @returns Assembly object for the WorkflowEntity.
*/
function mapAssembly(assembly: Assembly | undefined): WorkflowAssembly {
return {
commonName: getCommonName(assembly),
commonNames: getCommonNames(assembly),
taxonomicLevelClass: assembly?.taxonomicLevelClass ?? "Any",
taxonomicLevelDomain: assembly?.taxonomicLevelDomain ?? "Any",
taxonomicLevelFamily: assembly?.taxonomicLevelFamily ?? "Any",
Expand Down
4 changes: 2 additions & 2 deletions backend/api/app/services/catalog_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def search_organisms(self, query: str, limit: int = 10) -> List[Dict[str, Any]]:
for field in (
"taxonomicLevelSpecies",
"taxonomicLevelGenus",
"commonName",
"commonNames",
"ncbiTaxonomyId",
"taxonomicGroup",
"taxonomicLevelStrain",
Expand All @@ -137,7 +137,7 @@ def _condense_organism(self, org: Dict[str, Any]) -> Dict[str, Any]:
"ncbiTaxonomyId": org.get("ncbiTaxonomyId"),
"species": org.get("taxonomicLevelSpecies"),
"genus": org.get("taxonomicLevelGenus"),
"commonName": org.get("commonName"),
"commonNames": org.get("commonNames"),
"assemblyCount": org.get("assemblyCount"),
"taxonomicGroup": org.get("taxonomicGroup"),
"strain": org.get("taxonomicLevelStrain"),
Expand Down
13 changes: 9 additions & 4 deletions backend/api/app/services/tools/catalog_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,16 @@ def search_organisms(self, query: str, limit: int = 10) -> List[Dict[str, Any]]:
results = []
for org in self.organisms:
species = (org.get("taxonomicLevelSpecies") or "").lower()
common = (org.get("commonName") or "").lower()
commons = [(name or "").lower() for name in org.get("commonNames") or []]
tax_id = str(org.get("ncbiTaxonomyId") or "")
genus = (org.get("taxonomicLevelGenus") or "").lower()

if q in species or q in common or q == tax_id or q in genus:
if (
q in species
or any(q in common for common in commons)
or q == tax_id
or q in genus
):
results.append(self._summarize_organism(org))
if len(results) >= limit:
break
Expand Down Expand Up @@ -165,8 +170,8 @@ def find_organism_exact(self, name: Any) -> Optional[Dict[str, Any]]:
for org in self.organisms:
candidates = {
(org.get("taxonomicLevelSpecies") or "").lower(),
(org.get("commonName") or "").lower(),
str(org.get("ncbiTaxonomyId") or "").lower(),
*((common or "").lower() for common in org.get("commonNames") or []),
}
Comment thread
hunterckx marked this conversation as resolved.
candidates.discard("")
if q in candidates:
Expand All @@ -185,7 +190,7 @@ def _summarize_organism(self, org: Dict[str, Any]) -> Dict[str, Any]:

return {
"species": org.get("taxonomicLevelSpecies"),
"common_name": org.get("commonName"),
"common_names": org.get("commonNames"),
"taxonomy_id": str(org.get("ncbiTaxonomyId")),
"assembly_count": org.get("assemblyCount", len(genomes)),
"reference_assembly_count": len(ref_genomes),
Expand Down
6 changes: 3 additions & 3 deletions backend/api/app/services/tools/catalog_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def __post_init__(self) -> None:
"chromosomes": NUMERIC,
"strainName": SCALAR,
"coverage": SCALAR,
"commonName": SCALAR,
"commonNames": LIST,
"geneModelUrl": SCALAR,
},
# ploidy is intentionally omitted from display — it's an organism-level
Expand All @@ -163,7 +163,7 @@ def __post_init__(self) -> None:
source="organisms.json",
fields={
"ncbiTaxonomyId": SCALAR,
"commonName": SCALAR,
"commonNames": LIST,
"assemblyCount": NUMERIC,
"priority": SCALAR,
"priorityPathogenName": SCALAR,
Expand All @@ -180,7 +180,7 @@ def __post_init__(self) -> None:
display=(
"ncbiTaxonomyId",
"taxonomicLevelSpecies",
"commonName",
"commonNames",
"assemblyCount",
),
# Most relevant first: best-covered organisms (most assemblies), with the
Expand Down
14 changes: 10 additions & 4 deletions backend/api/tests/test_catalog_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"taxonomicLevelSpecies": "Plasmodium falciparum",
"taxonomicLevelGenus": "Plasmodium",
"taxonomicLevelFamily": "Plasmodiidae",
"commonName": "malaria parasite",
"commonNames": ["malaria parasite"],
"assemblyCount": 2,
"taxonomicGroup": ["Apicomplexa"],
"genomes": [
Expand Down Expand Up @@ -53,7 +53,7 @@
"taxonomicLevelSpecies": "Saccharomyces cerevisiae",
"taxonomicLevelGenus": "Saccharomyces",
"taxonomicLevelFamily": "Saccharomycetaceae",
"commonName": "yeast",
"commonNames": ["yeast", "brewer's yeast"],
"assemblyCount": 1,
"taxonomicGroup": ["Fungi"],
"genomes": [
Expand Down Expand Up @@ -160,6 +160,12 @@ def test_search_by_common_name(self, catalog):
assert len(results) == 1
assert results[0]["taxonomy_id"] == "559292"

def test_search_by_secondary_common_name(self, catalog):
# Matches on a non-primary common name from the full list.
results = catalog.search_organisms("brewer")
assert len(results) == 1
assert results[0]["taxonomy_id"] == "559292"

def test_search_by_taxonomy_id(self, catalog):
results = catalog.search_organisms("5833")
assert len(results) == 1
Expand Down Expand Up @@ -417,7 +423,7 @@ def test_missing_scope_defaults_to_assembly(self, tmp_path):
"ncbiTaxonomyId": 562,
"taxonomicLevelSpecies": "Escherichia coli",
"taxonomicLevelGenus": "Escherichia",
"commonName": "E. coli",
"commonNames": ["E. coli"],
"assemblyCount": 1,
"taxonomicGroup": ["Bacteria"],
"genomes": [
Expand All @@ -439,7 +445,7 @@ def test_missing_scope_defaults_to_assembly(self, tmp_path):
"ncbiTaxonomyId": 559292,
"taxonomicLevelSpecies": "Saccharomyces cerevisiae",
"taxonomicLevelGenus": "Saccharomyces",
"commonName": "yeast",
"commonNames": ["yeast"],
"assemblyCount": 1,
"taxonomicGroup": ["Fungi"],
"genomes": [
Expand Down
14 changes: 7 additions & 7 deletions backend/api/tests/test_catalog_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,26 +476,26 @@ def organism_con():
taxonomicLevelSpecies VARCHAR,
taxonomicLevelGenus VARCHAR,
taxonomicLevelDomain VARCHAR,
commonName VARCHAR,
commonNames VARCHAR[],
assemblyCount BIGINT,
taxonomicGroup VARCHAR[]
)
"""
)
rows = [
# taxid, species, genus, domain, common, assemblyCount, group
# taxid, species, genus, domain, commonNames, assemblyCount, group
(
"7165",
"Anopheles gambiae",
"Anopheles",
"Eukaryota",
"mosquito",
["mosquito", "African malaria mosquito"],
12,
["Inv"],
),
("7173", "Anopheles stephensi", "Anopheles", "Eukaryota", None, 5, ["Inv"]),
("62324", "Anopheles funestus", "Anopheles", "Eukaryota", None, 3, ["Inv"]),
("5476", "Candida albicans", "Candida", "Eukaryota", None, 8, ["Fungi"]),
("7173", "Anopheles stephensi", "Anopheles", "Eukaryota", [], 5, ["Inv"]),
("62324", "Anopheles funestus", "Anopheles", "Eukaryota", [], 3, ["Inv"]),
("5476", "Candida albicans", "Candida", "Eukaryota", [], 8, ["Fungi"]),
]
c.executemany("INSERT INTO organism VALUES (?, ?, ?, ?, ?, ?, ?)", rows)
yield c
Expand Down Expand Up @@ -539,7 +539,7 @@ def test_organism_clade_list_is_bounded(organism_con):
assert set(out["rows"][0]) == {
"ncbiTaxonomyId",
"taxonomicLevelSpecies",
"commonName",
"commonNames",
"assemblyCount",
}

Expand Down
2 changes: 1 addition & 1 deletion backend/tests/test_catalog_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def test_search_by_genus(self, catalog):
def test_search_by_common_name(self, catalog):
results = catalog.search_organisms("malaria")
assert len(results) > 0
names = [r.get("commonName") or "" for r in results]
names = [name for r in results for name in (r.get("commonNames") or [])]
assert any("malaria" in n.lower() for n in names)

def test_search_by_taxonomy_id(self, catalog):
Expand Down
Loading
Loading