4848 blank_value ,
4949)
5050
51- GBIF_BACKBONE_RANKS = [
51+ ALL_BACKBONE_RANKS = [
52+ "domain" ,
53+ "superkingdom" ,
5254 "kingdom" ,
5355 "phylum" ,
5456 "class" ,
5961 "subspecies" ,
6062]
6163
62- # Possible top level ranks one of which must be provided
63- SEQ_TOP_RANKS = [ "domain" , "superkingdom" , "kingdom" ]
64+ # GBIF backbone doesn't include the two highest-level ranks ("domain", "superkingdom")
65+ GBIF_BACKBONE_RANKS = ALL_BACKBONE_RANKS [ 2 : ]
6466
65- # List of additional ranks (in descending order) can be used to describe the taxonomy
66- # further
67- SEQ_ADDITIONAL_RANKS = [
68- "phylum" ,
69- "class" ,
70- "order" ,
71- "family" ,
72- "genus" ,
73- "species" ,
74- ]
67+ # For sequenced taxonomy the top level rank can be any of the top three ranks ("domain",
68+ # "superkingdom", "kingdom")
69+ SEQ_TOP_RANKS = ALL_BACKBONE_RANKS [0 :3 ]
70+
71+ # Sequenced taxonomy can then also include anything else as a backbone rank apart from
72+ # subspecies
73+ SEQ_ADDITIONAL_RANKS = ALL_BACKBONE_RANKS [3 :- 1 ]
7574
7675# NBCI name regex
7776NCBI_prefix_re = re .compile ("^[a-z]__" )
@@ -1392,7 +1391,10 @@ def repeat_names(self) -> set[str]:
13921391
13931392
13941393def taxon_index_to_text (
1395- taxa : list [dict ], html : bool = False , indent_width : int = 4
1394+ taxa : list [dict ],
1395+ html : bool = False ,
1396+ indent_width : int = 4 ,
1397+ lowest_taxa : str | None = None ,
13961398) -> str | tags .div :
13971399 """Render a taxon index as text or html.
13981400
@@ -1404,6 +1406,8 @@ def taxon_index_to_text(
14041406 taxa: A list of taxon dictionaries containing the taxa for a dataset.
14051407 html: Render as html or text.
14061408 indent_width: The indentation width to use for successive taxonomic ranks.
1409+ lowest_taxa: The lowest taxonomic rank that the index renders, if no rank is
1410+ provided then the index is rendered for all ranks.
14071411
14081412 Returns:
14091413 Either a HTML or text representation of the taxa tree.
@@ -1468,8 +1472,26 @@ def _format_name(tx: dict, use_html: bool = html):
14681472 if first_nm != taxon ["worksheet_name" ]:
14691473 surp_tx_ids .append (idx )
14701474
1475+ # Eliminate any taxa with ranks below the minimum
1476+ if lowest_taxa :
1477+ # Check that the lowest rank appears in the full set of taxa
1478+ if lowest_taxa not in ALL_BACKBONE_RANKS :
1479+ raise ValueError (
1480+ f"Rank provided to render taxa tree down to { lowest_taxa } is not a "
1481+ f"backbone rank! Should be one of: { ALL_BACKBONE_RANKS } "
1482+ )
1483+
1484+ # Generate the full list of ranks that should be rendered
1485+ rendered_ranks = ALL_BACKBONE_RANKS [: ALL_BACKBONE_RANKS .index (lowest_taxa ) + 1 ]
1486+
1487+ # Then add any taxa that have ranks that aren't in the list of rendered ranks to
1488+ # the superfluous taxa index
1489+ for idx , taxon in enumerate (taxa ):
1490+ if taxon ["taxon_rank" ] not in rendered_ranks :
1491+ surp_tx_ids .append (idx )
1492+
14711493 # Delete taxa that are superfluous by index
1472- for index in sorted (surp_tx_ids , reverse = True ):
1494+ for index in sorted (set ( surp_tx_ids ) , reverse = True ):
14731495 del taxa [index ]
14741496
14751497 # group taxa by their parent id
0 commit comments