read_nc_grps
def read_nc_grps(
fname, # Path to netcdf file
):Read a MARIS NetCDF file and return {group: DataFrame} dict
Each step is a single-responsibility function that transforms a dict of DataFrames keyed by sample group. They are composed in to_csv() below.
Open a standardised MARIS NetCDF file, extract each group’s variable arrays, and return them as {group_name: DataFrame}.
Read a MARIS NetCDF file and return {group: DataFrame} dict
| 0 | |
|---|---|
| SMP_ID_PROVIDER | BBFFG1999001 |
| LON | 13.72 |
| LAT | 54.220001 |
| SMP_DEPTH | 0.0 |
| TIME | 929404800 |
| STATION | BGBODD |
| NUCLIDE | 4 |
| VALUE | 841.0 |
| UNIT | 4 |
| UNC | 58.869999 |
| DL | 1 |
| BIO_GROUP | 11 |
| SPECIES | 96 |
| BODY_PART | 54 |
| DRYWT | NaN |
| WETWT | NaN |
| PERCENTWT | 0.1692 |
Keep only columns in the CSV schema. The NetCDF has internal columns (like SMP_ID) not part of the CSV output.
def keep_csv_cols(
dfs:dict, # dict of DataFrames keyed by sample group
cols:list={'AREA': 'area', 'BODY_PART': 'bodypar_id', 'BOTTOM': 'slicedown', 'COUNT_MET': 'counmet_id', 'DL': 'detection', 'DLV': 'detection_lim', 'DRYWT': 'drywt', 'FILT': 'filtered', 'LAB': 'lab_id', 'LAT': 'latitude', 'LON': 'longitude', 'NUCLIDE': 'nuclide_id', 'PERCENTWT': 'percentwt', 'PREP_MET': 'prepmet_id', 'PROFILE_ID': 'profile_id', 'REF_ID': 'ref_id', 'SAL': 'salinity', 'SAMP_MET': 'sampmet_id', 'SAMPLE_TYPE': 'samptype_id', 'SED_TYPE': 'sedtype_id', 'SMP_DEPTH': 'sampdepth', 'SMP_ID_PROVIDER': 'samplabcode', 'SPECIES': 'species_id', 'STATION': 'station', 'TAXONDB': 'taxondb', 'TAXONDBID': 'taxondb_id', 'TAXONDBURL': 'taxondb_url', 'TAXONNAME': 'taxonname', 'TAXONRANK': 'taxonrank', 'TAXONREPNAME': 'taxonrepname', 'TEMP': 'temperatur', 'TIME': 'begperiod', 'TOP': 'sliceup', 'TOT_DEPTH': 'totdepth', 'UNC': 'uncertaint', 'UNIT': 'unit_id', 'VALUE': 'activity', 'VOL': 'volume', 'WETWT': 'wetwt'}, # columns to keep (defaults to CSV_VARS)
):Keep only columns listed in cols
NetCDF stores time as seconds since epoch. Convert to datetime.
Decode TIME from epoch seconds to datetime
SQL import expects a sample type column. Each group has a fixed identifier.
Add SAMPLE_TYPE column using group ID mapping
Each group gets its MARIS sample type ID from SMP_TYPE_LUT:
Optional column from Zotero / INIS archive location. Omitted if not provided.
Add REF_ID column if ref_id is provided
Map BIOTA species IDs to scientific names and database references via the MARIS species lookup table.
Read species lookup table, return {col_name: {species_id: value}} dict
Add taxon columns to BIOTA from species lookup
add_taxon_info adds the taxon columns to BIOTA, looked up by species ID. An ID missing from the species table gets 'Unknown':
Convert integer enum IDs to display names. DL and FILT use the Excel name column rather than the sanitised version.
Map columns using get_lut
A group without the column is left unchanged:
CSV_DTYPES marks decoded vs encoded columns. DL and FILT are excluded since they use a different LUT column.
Decode enumerated columns marked as state='decoded' in CSV_DTYPES
It would be cleaner/more consistent to expect all MARIS LUT values in their encoded (integer) form during SQL import, rather than receiving a mix of decoded display names and encoded IDs.
Rename columns via CSV_VARS, then write one file per group.
Rename columns and write one CSV per group
to_csv_files renames the columns to their CSV names and writes one file for each group:
to_csv composes the helpers in order.
Convert MARIS standard NetCDF file to import-ready CSV files
to_csv converts a MARIS standard NetCDF file to import-ready CSV files, one for each sample type group. This example writes them to a temporary directory:
The output CSV includes 23 columns: sample metadata, activity, detection limit info, taxon details for biota, and reference ID. Below the first row:
| 0 | |
|---|---|
| bodypar_id | 54 |
| detection | = |
| drywt | NaN |
| latitude | 54.22 |
| longitude | 13.72 |
| nuclide_id | 4 |
| percentwt | 0.1692 |
| sampdepth | 0.0 |
| samplabcode | BBFFG1999001 |
| species_id | 96 |
| station | BGBODD |
| begperiod | 1999-06-15 |
| uncertaint | 58.87 |
| unit_id | 4 |
| activity | 841.0 |
| wetwt | NaN |
| samptype_id | 2 |
| ref_id | 100 |
| taxonname | Fucus vesiculosus |
| taxonrank | species |
| taxondb | Wikidata |
| taxondb_id | Q754755 |
| taxondb_url | https://www.wikidata.org/wiki/Q754755 |