NMD Biotic v3 is a nested hierarchy. BioticExplorerServer flattens it into a few wide,
joinable tables in DuckDB. You mostly work with three: mission, stnall, indall.
mission one cruise / survey trip
└─ fishstation one haul / station (position, time, gear, depths)
└─ catchsample one species-portion of a station's catch (commonname, weights, counts)
└─ individual one measured fish (length, weight, sex, maturity)
└─ agedetermination one age reading of that fish (age, readability)
(There are more elements — prey, tag, copepodedevstage, etc. — but the above is the
backbone for almost every query.)
| Table | Made from | One row = | Use for |
|---|---|---|---|
mission |
mission | one cruise | cruise/survey overviews |
stnall |
mission + fishstation + catchsample | one species-portion of one station | catches, maps, CPUE, distribution |
indall |
stnall + individual + preferred agedetermination | one measured fish | length, weight, sex, maturity, age, life-history |
ageall |
+ all age readings | one age reading | age-reading comparisons (if present) |
stnall and indall already contain the upstream columns (cruise, position, gear,
species…), so you rarely need manual joins.
Built by
RstoxUtils::processBioticFile()(same logic the server uses). Join keys aremissiontype, startyear, platform, missionnumber, serialnumber, catchsampleid, specimenid.
mission — missiontype, missiontypename, startyear, platform, platformname,
missionnumber, callsignal, cruise, missionstartdate, missionstopdate, purpose
stnall (mission + station + catch) — adds:
serialnumber (station id), station, stationstartdate, stationstarttime,
longitudestart, latitudestart, bottomdepthstart, fishingdepthmin, gear,
distance, commonname, catchcategory, catchpartnumber, catchweight, catchcount,
lengthsampleweight, lengthsamplecount. The DuckDB build also typically carries
geographic lookups such as icesarea — confirm with colnames(stnall).
indall (stnall + individual + age) — adds:
specimenid, sex, maturationstage, specialstage, length, individualweight,
age, readability, preferredagereading, numberofreads.
lengthis in METRES (per the XSD). A 92 cm cod haslength = 0.92. Present in cm withlength * 100. Sort "largest" bylength.individualweightis in KILOGRAMS;catchweightis in kg.commonnameis in Norwegian ("torsk","brosme","lange", …). Seespecies-and-surveys.mdandfield-glossary.md.missiontypedistinguishes survey vs. commercial data — research surveys aremissiontype %in% c(4, 5). Seespecies-and-surveys.md.- Coordinates are
longitudestart/latitudestart(decimal degrees). Filter outNAand obviously bad values (e.g.latitudestart > 0) before mapping. - Empty-catch stations can have
commonname = NA(stations retained without catch). - Codes (gear, area, maturity stage…) are foreign keys into NMDreference; the
glossary flags these. Resolve them with the in-database lookup tables (
gearindex,csindex,taxaindex; see below) — read these from the database, don't call BES functions.
Besides the core tables, the DuckDB carries small reference tables you can collect() up
front (inspect what's present with DBI::dbListTables(con)):
| Table | Maps |
|---|---|
csindex |
cruise-series code → name |
gearindex |
gear code → name / category |
taxaindex |
taxon (tsn) → name + synonyms; primary source for species names |
metadata |
latest build/update times, package version, schema version, update mode |
source_manifest |
administrative change signals used by updateDatabase(); not scientific data |
The lookup tables and metadata are written into DuckDB by BioticExplorerServer—query
them from the database; don't call BES fetch functions from BAIT. source_manifest is
created on the first incremental update.
taxaindex is present in databases compiled after the taxa table was added; if it's absent
in an older database, fall back to the species list in
species-and-surveys.md.
The full, generated field dictionary is field-glossary.md.