{"schema_version":"1.0","audience":"automated agents and LLMs accessing this Zarr store","domain":"ecosystem","access":{"open":"xarray.open_zarr(store, group='_combined/fluxnet_dd', consolidated=True)","combined_view":"_combined/fluxnet_dd","available_views":["_combined/fluxnet_dd"],"layout":"station × time panel — dims (station, time); latitude/longitude are 1-D coords on station","station_dim":"station","time_coord":"time","lat_coord":"latitude","lon_coord":"longitude","bbox_filter":"select station whose latitude/longitude fall in range, then slice time","entity_groups":"top-level groups not starting with '_' are individual stations/sites/cruises; '_combined' holds cross-entity views","list_entities":"listing groups is a ZARR call, not an xarray one: zarr.open_group(store, mode='r').group_keys() returns the top-level group names. An xarray Dataset has no .group_keys() and no .groups — reaching for either raises AttributeError. List first, then read one with xarray.open_zarr(store, group=<id>).","entity_ids":"FLUXNET site code — e.g. SE-Htm, DE-Hai, BE-Bra. Same string as the 'station' coord in the combined views and as the ICOS ecosystem station URI suffix after 'ES_'","entity_views":["<SITE>/fluxnet_dd","<SITE>/fluxnet_ww","<SITE>/fluxnet_mm","<SITE>/fluxnet_yy"],"open_entity":"xarray.open_zarr(store, group='SE-Htm/fluxnet_mm', consolidated=True)","list_entities_example":"import zarr; keys = list(zarr.open_group(store, mode='r').group_keys()); sites = [g for g in keys if not g.startswith('_')]   # site codes; '_combined' holds the cross-site views. list() binds group_keys(): it is a generator","aggregation_rule":"a monthly question opens fluxnet_mm, a yearly one fluxnet_yy — never open a finer group and resample, the aggregated groups carry the QC fractions and are far smaller","entity_vs_combined":"for a single named entity open its own group; use the combined view only for cross-entity work. Do NOT locate a named entity by bounding box — match it by id","citation_location":"license, collection_doi and time_coverage_* live ONLY on the STORE ROOT: xarray.open_zarr(store, consolidated=True).attrs. A per-site group carries citation and source_doi (and its own license) but a _combined/* group carries neither — there the citation is a per-station COORDINATE, ds['citation'].values.","carbon_flux":"reference-slice fluxes exposed flat in the combined views: NEE_VUT_REF, GPP_NT_VUT_REF, GPP_DT_VUT_REF, RECO_NT_VUT_REF, RECO_DT_VUT_REF; in the per-site groups NEE and NEE_QC are BOTH cubes with dims (time, ustar_threshold, nee_variant) — slice the flag with the same .sel() as the flux."},"conventions":{"metadata":"CF-1.12, ACDD-1.3 with a canonical cross-store attribute vocabulary","identity_attrs":"obspack and socat: latitude, longitude, elevation, station_id, station_name, network, country, source_doi, citation, collection_doi, license, license_url. fluxnet per-site groups use a DIFFERENT set: citation, source_doi, country, station_id, station_name, station_elevation, geospatial_lat, geospatial_lon, icos_labeling_date, icos_landing_page — the cross-store vocabulary is not yet applied here.","quality_control":"two different things share the _QC suffix, by group. In a per-site RAW group <var>_QC is an INTEGER gap-fill flag: 0 = measured, 1 = good_quality_fill, 2 = medium_quality_fill, 3 = poor_quality_fill, 255 = missing. xarray decodes it to float because fill_value 255 is masked to NaN — that float is NOT a fraction, and a '> 0.3' test there silently discards flag 0, the measured data; keep <= 1 if you must filter, and prefer to report the fill quality. In the AGGREGATED groups (per-site fluxnet_dd/ww/mm/yy and every _combined/*) <var>_QC IS a float fraction in [0,1] — the share of the interval backed by good measurements — and there the keep rule is > 0.3.","reading_string_arrays":"take .values before iterating: for a coord like 'cruise' or a byte-flag array, iterating the DataArray yields 0-d DataArrays, so .startswith()/.decode() fail and a boolean mask can come out silently all-False. Use arr.values (or arr[:].values) first.","carbon_flux":"reference-slice fluxes exposed flat in the combined views: NEE_VUT_REF, GPP_NT_VUT_REF, GPP_DT_VUT_REF, RECO_NT_VUT_REF, RECO_DT_VUT_REF; the full ustar_threshold × nee_variant cube remains in the per-site groups"},"discovery":{"variable_catalog":"variable_catalog.json (sibling of the store directory)","api":"ICOS zarr proxy — GET /variables, /variables/{id}, /query?id=..&station=..&cruise=..&lat_min=..&lat_max=..&lon_min=..&lon_max=..&start=..&end=..&apply_qc=true ; station/cruise ids are CASE-SENSITIVE, end is EXCLUSIVE, apply_qc DROPS rows the store flags bad; for WOCE stores it keeps flag 2 AND the -1 'no source flag' rows, whose values may be NaN — filter *_QC == 2 yourself (unknown/unusable filters answer 400 naming the problem); machine-readable contract at /openapi.json","croissant":"icos-fluxnet.croissant.jsonld (sibling of the store directory)","croissant_url":"ICOS zarr proxy: GET /icos-fluxnet.zarr/croissant — same Croissant, also linked (with @id) from the proxy-root schema.org DataCatalog when fetched with Accept: application/ld+json","collection_doi":"https://doi.org/10.18160/S6TB-567H"},"docs":["CONVENTIONS.md","CONSUMER_MIGRATION.md"]}