GuidesExporter des données

Exporter des données : le format .h5dcnvs

Lorsque vous exportez depuis DataCNVS un jeu de données, appelé observation, vous obtenez un fichier que vous pouvez réellement ouvrir n’importe où, et non un bloc propriétaire qui n’a de sens que dans notre application. Cette page présente le contenu du fichier, explique comment l’ouvrir et propose des exemples pratiques en Python et MATLAB.

Sur cette page

Ce que vous obtenez #

L’export produit un fichier unique portant l’extension .h5dcnvs. Il s’agit en réalité d’un fichier HDF5 parfaitement standard ; tout outil compatible avec HDF5 peut l’ouvrir, même sans rien connaître de DataCNVS. Ce qui en fait un fichier .h5dcnvs, c’est une arborescence interne spécifique et auto-descriptive : chaque valeur est accompagnée de son rôle, de ses unités physiques ainsi que de la variable et du type de grandeur qu’elle représente. Le fichier se décrit ainsi de lui-même, que vous l’ouvriez dans un navigateur HDF5 générique ou en écrivant cinq lignes de Python.

Un export contient une observation, avec :

  • ses champs scalaires (à valeur unique), par exemple la consigne d’un four ou l’identifiant d’un échantillon,
  • ses champs de séries (à valeurs multiples), par exemple une série de températures ou de mesures de contrainte,
  • l’échantillon auquel elle appartient, le cas échéant,
  • et un catalogue des variables et des types de grandeur auxquels ces champs font référence.

Seules les données canoniques DataCNVS sont exportées : les mêmes valeurs traitées et assorties d’unités que celles affichées dans les canevas de l’application. Les données brutes telles qu’elles ont été téléversées ne sont jamais incluses.

Exporter depuis l’application #

Ouvrez la page d’une observation et utilisez le bouton Télécharger situé dans l’angle supérieur droit. L’export s’exécute en tâche de fond ; la page affiche donc sa progression pendant la création du fichier. Une fois l’opération terminée, le téléchargement démarre automatiquement. HDF5 est actuellement le seul format d’export proposé, et l’export s’effectue observation par observation : chaque export produit un fichier pour l’observation consultée.

Ouvrir le fichier #

Comme .h5dcnvs est un fichier HDF5 standard, vous disposez d’un large choix d’outils :

OutilIdéal pourRemarques
HDFViewParcourir l’arborescence, les attributs et les valeurs sans écrire la moindre ligne de codeInterface graphique gratuite de The HDF Group ; affiche chaque attribut et chaque jeu de données exactement comme décrit ci-dessous
h5dump / h5lsEffectuer une inspection rapide en ligne de commandeFournis avec les outils en ligne de commande HDF5 standard ; h5dump -A file.h5dcnvs affiche chaque attribut de l’arborescence
Python (h5py, xarray, pandas)Analyse par scripts, notebooksVoir ci-dessous
MATLAB (fonctions intégrées h5info/h5read/h5readatt)Analyse par scripts, création de graphiquesAucune boîte à outils requise ; voir ci-dessous
R (rhdf5)Analyse par scriptsPackage Bioconductor ; le même modèle d’attributs et de jeux de données s’applique

Si l’outil que vous utilisez propose une option générique « ouvrir un fichier HDF5/NetCDF » et permet de parcourir les groupes et les attributs, il fonctionnera ; DataCNVS ne nécessite aucun plugin spécifique. Accédez à n’importe quel jeu de données values/value et lisez en parallèle les attributs units/long_name.

Structure du fichier #

La règle fondamentale #

Les attributs contiennent tous les éléments descriptifs ; les jeux de données contiennent uniquement les valeurs réelles.

Toute métadonnée relative à une mesure, notamment ses unités, son libellé, la variable concernée et l’observation à laquelle elle appartient, est un attribut HDF5. Les deux seuls types de jeux de données HDF5 présents dans l’ensemble du fichier sont le tableau values d’une série et la valeur unique value d’un scalaire. Une fois ce principe compris, l’arborescence devient prévisible : les attributs indiquent ce qu’est un élément, tandis que les jeux de données fournissent les nombres.

Vue d’ensemble de la structure #

/                                        (groupe racine, attributs au niveau du fichier, voir ci-dessous)
├─ observations_summary                  (miroir JSON de toute l’arborescence, pour plus de commodité)
├─ catalog/
│   ├─ quantity_kinds/
│   │   └─ temperature/                  (un groupe par type de grandeur, nommé d’après sa clé)
│   └─ variables/
│       └─ temperature/                  (un groupe par variable, nommé d’après sa clé)
└─ observations/
    └─ obs_000001/
        ├─ sample/                       (présent uniquement si l’observation comporte un échantillon)
        ├─ scalars/
        │   └─ contextual_furnace_setpoint/
        │       └─ value                 (Jeu de données)
        ├─ series/
        │   ├─ index_time/
        │   │   └─ values                (Jeu de données)
        │   └─ dependent_temperature/
        │       └─ values                (Jeu de données)
        └─ series_groups/                (présent uniquement lorsque des séries partagent un index commun)
            └─ group_000001/

Les noms des groupes et des champs sont stables, déterministes et lisibles. Une même observation exportée deux fois produit la même arborescence, et le chemin HDF5 d’un champ (par exemple observations/obs_000001/series/dependent_temperature) constitue également son emplacement en langage clair.

Attributs racine #

Quelques attributs du groupe racine du fichier décrivent l’export dans son ensemble :

AttributSignification
formatToujours "datacnvs.interchange.hdf5", ce qui identifie le fichier comme un export DataCNVS et non comme un simple fichier HDF5
format_versionVersion du format du conteneur (entier)
generated_atDate et heure de génération de l’export, au format ISO-8601 UTC
source_tenant_slugEspace de travail depuis lequel les données ont été exportées
title, readmeUn titre lisible et un court paragraphe expliquant l’arborescence ; commencez par le lire si vous explorez un fichier pour la première fois

Catalogue : variables et types de grandeur #

catalog/quantity_kinds/<key>/ et catalog/variables/<key>/ contiennent les métadonnées partagées auxquelles les champs scalaires et de séries font référence. Elles ne sont ainsi écrites qu’une seule fois, même si plusieurs champs utilisent la même variable. Un groupe de types de grandeur se présente comme suit :

catalog/quantity_kinds/temperature/
├─ @key             = "temperature"
├─ @label           = "Temperature"
├─ @canonical_units = "K"
├─ @units           = "K"          (doublon, au format CF, voir ci-dessous)
├─ @symbol          = "T"
└─ @common_units    = ["degC", "degF", "K"]

Un groupe de variables est similaire et comporte en plus @quantity_kind_key, la chaîne à rechercher dans catalog/quantity_kinds/ pour déterminer ses unités et sa définition.

L’observation #

Le groupe observations/obs_000001/ correspond à l’observation exportée. Il comporte obs_type, title, technique, notes, ingestion_status et created_at comme attributs, ainsi qu’un sous-groupe sample/ si un échantillon y est associé.

À l’intérieur, chaque champ scalaire ou de série possède son propre groupe sous scalars/ ou series/, nommé à l’aide d’un slug lisible (par exemple contextual_furnace_setpoint, dependent_temperature, index_time). Tous les groupes de champs utilisent le même vocabulaire d’attributs, selon deux styles qui se recoupent et sont présentés côte à côte :

AttributStyleSignification
unitsConvention CFUnités physiques déterminées à partir du type de grandeur (ou de units_override si le champ les remplace)
long_nameConvention CFLibellé lisible : l’alias du champ s’il en possède un, sinon le nom de la variable
standard_nameEmplacement réservé par la convention CFRéaffecté à la clé du type de grandeur DataCNVS ; il n’est pas validé par rapport au véritable vocabulaire CF
roleDataCNVSRaison de la présence de ce champ dans l’observation, par exemple dependent, contextual, index
dtypeDataCNVSType de données DataCNVS de la valeur ; voir la référence des types ci-dessous
variable_key, quantity_kind_keyDataCNVSClés de recherche dans catalog/variables/ et catalog/quantity_kinds/
alias, units_overrideDataCNVSPrésents uniquement lorsque le champ remplace le libellé ou les unités par défaut de la variable

Les noms au format CF (units, long_name, standard_name) existent parce qu’ils sont largement reconnus par les outils scientifiques HDF5/NetCDF génériques. Vous obtenez ainsi des unités et des libellés lisibles sans plugin propre à DataCNVS. Les noms au format DataCNVS permettent quant à eux des recherches non ambiguës et adaptées au code. Les deux styles décrivent le même champ ; utilisez celui qui convient à votre outil.

Les champs de séries comportent également series_kind ("series" ou "index"), length et, si la série partage un index commun avec d’autres (par exemple un axe temporel commun à plusieurs courbes dépendantes), series_group_ref, qui pointe vers une entrée de series_groups/ (voir la section suivante).

Groupes de séries #

Lorsque deux séries ou plus d’une observation partagent un index commun (le plus souvent, un axe temporel ou de position avec plusieurs mesures dépendantes correspondantes), elles sont reliées au moyen de observations/obs_000001/series_groups/group_NNNNNN/. Ce groupe ne duplique aucune donnée ; il répertorie simplement les chemins des membres et, uniquement pour faciliter la navigation, fournit des liens symboliques HDF5 vers les véritables jeux de données values, afin qu’un navigateur d’arborescence affiche visuellement la relation. Le code doit toujours déterminer la relation à partir de l’attribut series_group_ref, et non en parcourant les liens.

Une série dépourvue d’attribut series_group_ref n’a tout simplement pas d’index partagé ; considérez donc que ses valeurs sont ordonnées selon la position des lignes (point 0, point 1, point 2, …).

observations_summary #

Le jeu de données racine observations_summary contient les mêmes informations que l’ensemble de l’arborescence, reformulées sous la forme d’un document JSON unique réunissant l’observation, ses champs et les entrées du catalogue avec leurs chemins HDF5. Il facilite les scripts qui préfèrent analyser un seul bloc JSON plutôt que parcourir l’arborescence des groupes, et constitue nécessairement un miroir strict de ce qu’indiquent déjà les attributs (jamais une source d’informations supplémentaires).

Référence des types de données #

L’attribut dtype de chaque champ indique le mode de stockage physique de son jeu de données value/values :

dtype DataCNVSStocké sous forme deRemarques
stringTexte UTF-8
booleanbooléen
integerentier 64 bits
number / numeric(p,s)nombre à virgule flottante 64 bits
dateTexte de date ISO-8601, par exemple "2026-06-01"
datetime / timestampentier 64 bits représentant les millisecondes écoulées depuis l’époque Unix (UTC)Comporte également un attribut time_units = "epoch_ms_utc" à titre de rappel
json, list, struct, map, dictionaryTexte UTF-8 contenant la valeur encodée en JSONComporte également encoding = "json" ; analysez la chaîne comme du JSON pour récupérer la valeur structurée

Les grandes séries numériques sont compressées avec gzip et segmentées ; les petites valeurs et le texte sont stockés tels quels. Cette opération est transparente pour tous les lecteurs ci-dessous : h5py, xarray et MATLAB décompressent automatiquement les données.

Utiliser les exports dans Python #

La méthode la plus directe consiste à utiliser h5py ; aucun code spécifique à DataCNVS n’est nécessaire, seulement les noms d’attributs documentés ci-dessus.

python
import datetime as dt
import json

import h5py

with h5py.File("furnace_run_14.h5dcnvs", "r") as f:
    print(f.attrs["title"])
    print(f.attrs["readme"])

    obs = f["observations/obs_000001"]
    print(obs.attrs["title"], "-", obs.attrs["technique"])

    # Une valeur scalaire, avec ses unités.
    setpoint = obs["scalars/contextual_furnace_setpoint"]
    print(setpoint["value"][()], setpoint.attrs["units"])

    # Une série et ses unités/son libellé.
    temperature = obs["series/dependent_temperature"]
    values = temperature["values"][:]
    print(f"{len(values)} points, units={temperature.attrs['units']}")

    # Une série d’index de date et heure est décodée à partir de millisecondes depuis l’époque Unix.
    index_time = obs["series/index_time"]
    epoch_ms = index_time["values"][:]
    timestamps = [
        dt.datetime(1970, 1, 1, tzinfo=dt.timezone.utc) + dt.timedelta(milliseconds=int(t))
        for t in epoch_ms
    ]

    # Recherchez le type de grandeur d’un champ dans le catalogue partagé.
    qk_key = temperature.attrs["quantity_kind_key"]
    qk = f[f"catalog/quantity_kinds/{qk_key}"]
    print(qk.attrs["label"], qk.attrs["canonical_units"])

    # Un champ json/list/struct/map est décodé avec json.loads.
    # struct_field = obs["scalars/contextual_some_json_field"]
    # value = json.loads(struct_field["value"][()])

    # L’arborescence complète, reformulée en JSON, si ce format est plus simple à exploiter.
    summary = json.loads(f["observations_summary"][()])

Si vous préférez travailler avec des tableaux étiquetés plutôt qu’avec des chemins HDF5 bruts, créez un xarray.Dataset à partir des éléments ci-dessus (le fichier n’associe pas lui-même d’échelles de dimensions ; vous devez donc assembler les libellés une fois, lors de la lecture) :

python
import h5py
import xarray as xr

with h5py.File("furnace_run_14.h5dcnvs", "r") as f:
    obs = f["observations/obs_000001"]
    time = obs["series/index_time/values"][:]
    temp_grp = obs["series/dependent_temperature"]
    temp = temp_grp["values"][:]
    units = temp_grp.attrs["units"]

ds = xr.Dataset(
    {"temperature": ("time", temp, {"units": units})},
    coords={"time": ("time", time, {"units": "epoch_ms_utc"})},
)
ds.temperature.plot()

Pour les traitements tabulaires, le tableau values d’une série se convertit directement en pandas.Series ou en colonne de DataFrame : pandas.Series(temperature["values"][:]).

Utiliser les exports dans MATLAB #

Les fonctions HDF5 intégrées de MATLAB (h5info, h5disp, h5read, h5readatt) ne nécessitent aucune boîte à outils et fonctionnent directement avec les fichiers .h5dcnvs.

matlab
file = "furnace_run_14.h5dcnvs";

% Parcourez toute l’arborescence, y compris chaque attribut.
h5disp(file);

% Lisez le titre de l’observation.
obsTitle = h5readatt(file, "/observations/obs_000001", "title");

% Lisez une série et ses unités.
temperature = h5read(file, "/observations/obs_000001/series/dependent_temperature/values");
units = h5readatt(file, "/observations/obs_000001/series/dependent_temperature", "units");

% L’index temporel associé est décodé à partir de millisecondes depuis l’époque Unix (UTC).
epochMs = h5read(file, "/observations/obs_000001/series/index_time/values");
t = datetime(epochMs, "ConvertFrom", "epochtime", ...
    "TicksPerSecond", 1000, "Epoch", "1970-01-01", "TimeZone", "UTC");

% Une valeur scalaire, avec ses unités.
setpoint = h5read(file, "/observations/obs_000001/scalars/contextual_furnace_setpoint/value");
setpointUnits = h5readatt(file, "/observations/obs_000001/scalars/contextual_furnace_setpoint", "units");

plot(t, temperature);
xlabel("Time");
ylabel(sprintf("Temperature (%s)", units));
title(sprintf("%s — setpoint %.1f %s", obsTitle, setpoint, setpointUnits));

Remarques à l’intention des utilisateurs de MATLAB :

  • Les champs de texte de longueur variable (libellés, valeurs encodées en JSON, chaînes de date ISO) sont renvoyés par h5read/h5readatt sous forme de chaîne MATLAB ou de tableau de cellules de vecteurs de caractères, selon que le jeu de données ou l’attribut sous-jacent est scalaire ou comporte plusieurs valeurs ; enveloppez les valeurs uniques dans string(...) si vous avez besoin d’un typage cohérent entre les champs.
  • Une valeur json/list/struct/map/dictionary est relue sous forme de texte JSON ; décodez-la avec jsondecode(...).
  • h5info(file, "/observations/obs_000001") fournit la même liste d’attributs et de jeux de données que celle affichée par h5disp, mais sous forme de struct que vous pouvez parcourir par programmation au lieu de la lire dans la console.

Limites et conservation #

  • L’export s’effectue par observation : un fichier, une observation.
  • Seules les données canoniques (traitées) sont exportées, jamais les données brutes telles qu’elles ont été téléversées.
  • Les liens de téléchargement expirent 7 jours après la fin de l’export ; les données de l’observation sous-jacente restent intactes, vous pouvez donc simplement effectuer un nouvel export.

Besoin d’un autre format ? #

HDF5 est aujourd’hui le seul format d’export disponible. Si votre flux de travail nécessite autre chose, comme un fichier CSV plat, un autre format d’échange ou le format natif d’un outil particulier, faites-le-nous savoir.

Contacter l’équipe DataCNVS