3d9c0012a395a31127c3af3459c4e28c48dda205
max
  Thu Sep 17 01:09:25 2026 -0700
uniprot otto: keep updating the classic assembly when a GenArk one appears

#Preview2 week - bugs introduced now will need a build patch to fix
getTaxIdDbs took the first assembly per taxon by orderKey. GenArk assemblies now
sort ahead of the classic ones, so the moment ARS_UCD2.0 appeared for cow, bosTau9
stopped being updated: its UniProt tracks froze at whatever release they had while
the new data went into a GenArk contrib collection that is not installed. Users are
still on bosTau9. The same had happened for marmoset, zebrafish, gorilla, cat,
macaque, chicken, rat, horse, sheep, chimp, bonobo, orangutan, zebra finch and two
more, sixteen taxa in all.

Take the first of each kind instead, one GenArk and one classic, so both keep
getting the current release. The plan goes from 119 to 135 assemblies; the taxa
count is unchanged at 109, and no assembly appears twice, so the assertion at the
end of the function still holds. Human, mouse, fly, worm and yeast are unaffected.

refs #38300

diff --git src/hg/utils/otto/uniprot/doUniprot src/hg/utils/otto/uniprot/doUniprot
index 7391929e714..a25f96f1dea 100755
--- src/hg/utils/otto/uniprot/doUniprot
+++ src/hg/utils/otto/uniprot/doUniprot
@@ -106,45 +106,53 @@
 NCBIDIR = "ncbi"
 
 # global variable needed for atexit callback function
 flagFname = None
 
 def errAbort(msg):
     " stop "
     logging.error(msg)
     assert(False) # generate stacktrace
 
 def getTaxIdDbs(onlyDbs):
     """ return a dict with taxonId -> list of most recent dbs (e.g. for human, it's hg19 and hg38) 
     if onlyDbs is a set, keep only these dbs.
     If onlyDbs is None, remove all nonAutoDbs.
     """
-    query = "select taxId, name from dbDb where active=1 order by orderKey;"
+    query = "select taxId, name, nibPath from dbDb where active=1 order by orderKey;"
     rows = runQuery("hgcentral", query, usePublic=True)
     taxIdToDbs = defaultdict(list)
-    # take only the first database for every taxonId
-    for taxId, dbCode in rows:
+    # Take the first assembly of each kind for every taxon: the first GenArk one and the
+    # first classic one. Taking only the very first, as this did, stopped updating the
+    # classic assembly the moment a GenArk assembly for the same organism appeared and
+    # sorted ahead of it. Cow is the example: ARS_UCD2.0 arrived, so bosTau9 silently
+    # stayed on the UniProt release it had, while the new data went into a GenArk contrib
+    # collection. Users are still on bosTau9. refs #38300
+    seen = defaultdict(set)
+    for taxId, dbCode, nibPath in rows:
 
         if onlyDbs:
             if dbCode not in onlyDbs:
                 continue
         else:
             if dbCode in notAutoDbs:
                 continue
 
         taxId = int(taxId)
-        if taxId not in taxIdToDbs:
+        kind = "genark" if (nibPath or "").startswith("hub:") else "classic"
+        if kind not in seen[taxId]:
+            seen[taxId].add(kind)
             taxIdToDbs[taxId].append(dbCode)
 
     for taxId, manNames in manualTaxIdDbs.items():
         if manNames is None:
             del taxIdToDbs[taxId]
         else:
             for dbCode in manNames:
                 if onlyDbs:
                     if dbCode not in onlyDbs:
                         continue
                 else:
                     if dbCode in notAutoDbs:
                         continue
 
                 if dbCode not in taxIdToDbs[taxId]: