Skip to content

GEO series to BioProject, via the SOFT family file

Route id: gse->bioproject:soft_family Provider: GEO FTP Direction: GSE → PRJNA

The hinge of the whole GEO side. ENA's filereport answers a GSE with a 400 — GEO accessions are not INSDC accessions — so every route from a GEO series into ENA goes through the BioProject the series names, and this is where that name comes from.

The request

curl -s 'https://ftp.ncbi.nlm.nih.gov/geo/series/GSE236nnn/GSE236084/soft/GSE236084_family.soft.gz' \
  | gzip -dc | grep '^!Series_relation'
!Series_relation = BioProject: https://www.ncbi.nlm.nih.gov/bioproject/PRJNA988806
!Series_relation = SRA: https://www.ncbi.nlm.nih.gov/sra?term=SRP446371

GEO buckets its FTP tree by masking the last three digits of the accession, so GSE236084 lives under GSE236nnn. Series with three digits or fewer sit in GSEnnn.

Measured

Corpus: reprocessed-gse — all 13,045 GEO series the reprocessing pipeline has had to resolve. Surveyed: 2026-09-15.

Resolved 12,572
Named no BioProject 473
Failed 7

Exactly one BioProject per series, every time. Not one of the 12,572 named two. That is worth stating because the opposite direction is emphatically not one-to-one: a single BioProject can hold several GEO series — PRJNA1169288 holds three — so the graph is a many-to-one, and code that assumes symmetry is wrong in one direction only.

The 473 that name none are the population behind series under a shared umbrella BioProject: 3.6% of the corpus, for which the BioProject route cannot be the entry into ENA and the experiment-level route has to be.

The 7 failures are series whose SOFT family file could not be fetched at all; GSE207991 is among them and is private on GEO, which is the correct answer rather than a transport problem.

Compared with esummary db=gds

Now censused: gds_summary resolves 13,038 of the same 13,045 series, never fails, and finds a BioProject for 466 of the 473 this route leaves empty. Where both answer they never disagree.

It should still not be ranked first. 190 of those 466 resolve to a species- or consortium-level umbrella project holding thousands of unrelated runs — PRJNA30709 alone accounts for 138 of them and holds 7,591 runs. The extra coverage is real and about 41% of it is unusable without a size check. The comparison is written up on the gds_summary page.