Exportação de dados: o formato .h5dcnvs
Quando você exporta um conjunto de dados, chamado de observação, do DataCNVS, recebe um arquivo que pode realmente ser aberto em qualquer lugar, e não um bloco proprietário que só faz sentido dentro do nosso aplicativo. Esta página explica o que há no arquivo, como abri-lo e apresenta exemplos práticos em Python e MATLAB.
Nesta página
O que você recebe #
A exportação gera um único arquivo com a extensão .h5dcnvs. Por baixo, ele é um arquivo HDF5 totalmente padrão; qualquer ferramenta compatível com HDF5 pode abri-lo, mesmo sem saber nada sobre o DataCNVS. O que o torna um arquivo .h5dcnvs é uma estrutura de árvore específica e autodescritiva em seu interior: cada valor é rotulado com sua função, suas unidades físicas e a variável e o tipo de grandeza que representa. Assim, o próprio arquivo se explica, seja quando aberto em um navegador HDF5 genérico, seja ao escrever cinco linhas de Python.
Uma exportação contém uma observação, com:
- seus campos escalares (de valor único), por exemplo, o ponto de ajuste de um forno ou o ID de uma amostra,
- seus campos de série (com valores em matriz), por exemplo, uma série de temperaturas ou medições de tensão,
- a amostra à qual ela pertence, se houver,
- e um catálogo das variáveis e dos tipos de grandeza referenciados por esses campos.
Somente dados canônicos do DataCNVS são exportados: os mesmos valores processados e com unidades resolvidas que você vê nas telas do aplicativo. Os dados brutos, tais como foram enviados, nunca são incluídos.
Exportação pelo aplicativo #
Abra a página de uma observação e use o botão Baixar no canto superior direito. A exportação é executada como uma tarefa em segundo plano, portanto, a página exibe o progresso enquanto o arquivo é criado; quando terminar, o download começará automaticamente. No momento, HDF5 é o único formato de exportação disponível, e cada exportação corresponde a uma observação: há um arquivo por exportação, referente à observação que você está visualizando.
Como abrir o arquivo #
Como .h5dcnvs é HDF5 puro, você tem uma grande variedade de ferramentas à disposição:
| Ferramenta | Ideal para | Observações |
|---|---|---|
| HDFView | Navegar pela árvore, pelos atributos e pelos valores sem escrever código | Interface gráfica gratuita do The HDF Group; exibe cada atributo e conjunto de dados exatamente como descrito abaixo |
h5dump / h5ls | Inspeção rápida pela linha de comando | Incluídos nas ferramentas de linha de comando padrão do HDF5; h5dump -A file.h5dcnvs exibe todos os atributos da árvore |
| Python (h5py, xarray, pandas) | Análises com scripts e notebooks | Veja abaixo |
| MATLAB (h5info/h5read/h5readatt integrados) | Análises com scripts e geração de gráficos | Não requer toolbox; veja abaixo |
| R (rhdf5) | Análises com scripts | Pacote do Bioconductor; aplica-se o mesmo modelo de atributos/conjuntos de dados |
Se qualquer outra ferramenta que você usa tiver uma opção genérica de "abrir arquivo HDF5/NetCDF" e permitir navegar por grupos e atributos, ela funcionará; o DataCNVS não exige um plugin específico do DataCNVS em nenhuma situação. Aponte-a para qualquer conjunto de dados values/value e leia os atributos units/long_name junto com ele.
Estrutura do arquivo #
A regra principal #
Os atributos contêm todas as informações descritivas; os conjuntos de dados contêm somente os valores propriamente ditos.
Tudo o que for metadado sobre uma medição, incluindo suas unidades, seu rótulo, a variável à qual corresponde e a observação à qual pertence, é um atributo HDF5. Os únicos dois tipos de conjunto de dados HDF5 em todo o arquivo são a matriz values de uma série e o único value de um escalar. Depois que você entende isso, navegar pela árvore se torna previsível: os atributos informam o que algo é, e os conjuntos de dados fornecem os números.
Visão geral da estrutura #
/ (grupo raiz, atributos no nível do arquivo; veja abaixo)
├─ observations_summary (um espelho em JSON de toda a árvore, por conveniência)
├─ catalog/
│ ├─ quantity_kinds/
│ │ └─ temperature/ (um grupo por tipo de grandeza, nomeado por sua chave)
│ └─ variables/
│ └─ temperature/ (um grupo por variável, nomeado por sua chave)
└─ observations/
└─ obs_000001/
├─ sample/ (presente somente se a observação tiver uma amostra)
├─ scalars/
│ └─ contextual_furnace_setpoint/
│ └─ value (Conjunto de dados)
├─ series/
│ ├─ index_time/
│ │ └─ values (Conjunto de dados)
│ └─ dependent_temperature/
│ └─ values (Conjunto de dados)
└─ series_groups/ (presente somente quando as séries compartilham um índice comum)
└─ group_000001/Os nomes de grupos e campos são estáveis, determinísticos e legíveis por pessoas. A mesma observação exportada duas vezes produz a mesma árvore, e o caminho HDF5 de um campo (por exemplo, observations/obs_000001/series/dependent_temperature) também serve como sua localização em linguagem simples.
Atributos da raiz #
Alguns atributos no grupo raiz do arquivo descrevem a exportação como um todo:
| Atributo | Significado |
|---|---|
format | Sempre "datacnvs.interchange.hdf5", o que identifica este arquivo como uma exportação do DataCNVS, e não apenas como qualquer arquivo HDF5 |
format_version | Versão do formato do contêiner (número inteiro) |
generated_at | Momento em que a exportação foi gerada, no formato ISO-8601 UTC |
source_tenant_slug | O espaço de trabalho do qual os dados foram exportados |
title, readme | Um título legível e um breve parágrafo explicando a árvore; leia isso primeiro se estiver explorando um arquivo pela primeira vez |
Catálogo: variáveis e tipos de grandeza #
catalog/quantity_kinds/<key>/ e catalog/variables/<key>/ contêm os metadados compartilhados aos quais os campos escalares e de série fazem referência. Assim, eles são gravados apenas uma vez, mesmo que vários campos usem a mesma variável. Um grupo de tipo de grandeza tem esta aparência:
catalog/quantity_kinds/temperature/
├─ @key = "temperature"
├─ @label = "Temperature"
├─ @canonical_units = "K"
├─ @units = "K" (duplicado, no estilo CF; veja abaixo)
├─ @symbol = "T"
└─ @common_units = ["degC", "degF", "K"]Um grupo de variáveis é semelhante e também contém @quantity_kind_key, que é a string a ser consultada em catalog/quantity_kinds/ para resolver suas unidades e sua definição.
A observação #
O grupo observations/obs_000001/ é a observação que você exportou, com obs_type, title, technique, notes, ingestion_status e created_at como atributos, além de um subgrupo sample/ caso haja uma amostra associada.
Em seu interior, cada campo escalar e de série recebe seu próprio grupo em scalars/ ou series/, nomeado com um slug legível (por exemplo, contextual_furnace_setpoint, dependent_temperature, index_time). Cada grupo de campos contém o mesmo vocabulário de atributos, apresentado lado a lado em dois estilos sobrepostos:
| Atributo | Estilo | Significado |
|---|---|---|
units | Convenção CF | Unidades físicas, resolvidas a partir do tipo de grandeza (ou de units_override, se o campo as substituir) |
long_name | Convenção CF | Rótulo legível: o alias do campo, se houver, ou o nome da variável |
standard_name | Campo da convenção CF | Reutilizado para armazenar a chave de tipo de grandeza do DataCNVS; ele não é validado em relação ao vocabulário CF real |
role | DataCNVS | Por que esse campo existe na observação, por exemplo, dependent, contextual, index |
dtype | DataCNVS | O tipo de dados do valor no DataCNVS; veja a referência de tipos abaixo |
variable_key, quantity_kind_key | DataCNVS | Chaves de consulta em catalog/variables/ e catalog/quantity_kinds/ |
alias, units_override | DataCNVS | Presentes somente quando o campo substitui o rótulo/as unidades padrão da variável |
Os nomes no estilo CF (units, long_name, standard_name) existem porque são amplamente reconhecidos por ferramentas científicas genéricas para HDF5/NetCDF. Assim, você obtém unidades e rótulos legíveis sem nenhum plugin específico do DataCNVS. Os nomes no estilo DataCNVS existem para permitir consultas inequívocas e fáceis de usar em código. Ambos descrevem o mesmo campo; use o que melhor se adaptar à sua ferramenta.
Os campos de série também contêm series_kind ("series" ou "index"), length e, se a série compartilhar um índice comum com outras (por exemplo, um eixo de tempo compartilhado por várias curvas dependentes), series_group_ref, que aponta para uma entrada em series_groups/ (veja a próxima seção).
Grupos de séries #
Quando duas ou mais séries na observação compartilham um índice comum (na maioria das vezes, um eixo de tempo ou posição com várias medições dependentes relacionadas a ele), elas são vinculadas por meio de observations/obs_000001/series_groups/group_NNNNNN/. Esse grupo não duplica nenhum dado; ele apenas lista os caminhos dos membros e, somente para facilitar a navegação, fornece links simbólicos HDF5 para os conjuntos de dados values reais, de modo que um navegador de árvore mostre visualmente a relação. O código deve sempre resolver essa relação a partir do atributo series_group_ref, e não percorrendo os links.
Uma série sem o atributo series_group_ref simplesmente não tem um índice compartilhado; portanto, trate seus valores como ordenados pela posição da linha (ponto 0, ponto 1, ponto 2, …).
observations_summary #
O conjunto de dados observations_summary no nível da raiz contém as mesmas informações que a árvore inteira, reapresentadas como um único documento JSON com a observação, seus campos e as entradas do catálogo com seus caminhos HDF5. É uma conveniência para scripts que prefiram analisar um único bloco JSON em vez de percorrer a árvore de grupos, e há a garantia de que ele seja um espelho fiel do que os atributos já informam (nunca uma fonte de informações adicionais).
Referência de tipos de dados #
O atributo dtype de cada campo informa como seu conjunto de dados value/values é armazenado fisicamente:
| dtype do DataCNVS | Armazenado como | Observações |
|---|---|---|
string | Texto UTF-8 | |
boolean | boolean | |
integer | Número inteiro de 64 bits | |
number / numeric(p,s) | Número de ponto flutuante de 64 bits | |
date | Texto de data ISO-8601, por exemplo, "2026-06-01" | |
datetime / timestamp | Número inteiro de 64 bits em milissegundos desde a época Unix (UTC) | Também contém um atributo time_units = "epoch_ms_utc" como lembrete |
json, list, struct, map, dictionary | Texto UTF-8 contendo o valor codificado em JSON | Também contém encoding = "json"; analise a string como JSON para recuperar o valor estruturado |
Séries numéricas grandes são compactadas com gzip e divididas em blocos; valores pequenos e textos são armazenados sem compactação. Isso é transparente para todos os leitores abaixo: h5py, xarray e MATLAB fazem a descompactação automaticamente.
Como trabalhar com exportações em Python #
O caminho mais direto é usar h5py; ele não exige nenhum código específico do DataCNVS, apenas os nomes de atributos documentados acima.
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"])
# Um valor escalar, com suas unidades.
setpoint = obs["scalars/contextual_furnace_setpoint"]
print(setpoint["value"][()], setpoint.attrs["units"])
# Uma série e suas unidades/seu rótulo.
temperature = obs["series/dependent_temperature"]
values = temperature["values"][:]
print(f"{len(values)} points, units={temperature.attrs['units']}")
# Uma série de índice de data e hora é decodificada a partir de milissegundos desde a época.
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
]
# Consulte o tipo de grandeza de um campo por meio do catálogo compartilhado.
qk_key = temperature.attrs["quantity_kind_key"]
qk = f[f"catalog/quantity_kinds/{qk_key}"]
print(qk.attrs["label"], qk.attrs["canonical_units"])
# Um campo json/list/struct/map é decodificado com json.loads.
# struct_field = obs["scalars/contextual_some_json_field"]
# value = json.loads(struct_field["value"][()])
# A árvore inteira, reapresentada como JSON, caso seja mais fácil trabalhar assim.
summary = json.loads(f["observations_summary"][()])Se você preferir trabalhar com matrizes rotuladas em vez de caminhos HDF5 brutos, crie um xarray.Dataset a partir das partes acima (o arquivo não associa escalas de dimensão por conta própria; portanto, você monta os rótulos uma vez durante a leitura):
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()Para trabalhos tabulares, a matriz values de uma série é convertida diretamente em uma pandas.Series ou em uma coluna de DataFrame: pandas.Series(temperature["values"][:]).
Como trabalhar com exportações no MATLAB #
As funções HDF5 integradas do MATLAB (h5info, h5disp, h5read, h5readatt) não exigem toolbox e funcionam diretamente com arquivos .h5dcnvs.
file = "furnace_run_14.h5dcnvs";
% Navegue por toda a árvore, incluindo todos os atributos.
h5disp(file);
% Leia o título da observação.
obsTitle = h5readatt(file, "/observations/obs_000001", "title");
% Leia uma série e suas unidades.
temperature = h5read(file, "/observations/obs_000001/series/dependent_temperature/values");
units = h5readatt(file, "/observations/obs_000001/series/dependent_temperature", "units");
% O índice de tempo correspondente é decodificado a partir de milissegundos desde a época (UTC).
epochMs = h5read(file, "/observations/obs_000001/series/index_time/values");
t = datetime(epochMs, "ConvertFrom", "epochtime", ...
"TicksPerSecond", 1000, "Epoch", "1970-01-01", "TimeZone", "UTC");
% Um valor escalar, com suas unidades.
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));Observações para usuários do MATLAB:
- Campos de texto de tamanho variável (rótulos, valores codificados em JSON, strings de data ISO) são retornados por
h5read/h5readattcomo uma string do MATLAB ou uma matriz de células de vetores de caracteres, dependendo de o conjunto de dados/atributo subjacente ser escalar ou ter valores em matriz; envolva valores únicos emstring(...)se precisar de tipagem consistente entre os campos. - Um valor
json/list/struct/map/dictionaryé lido como texto JSON; decodifique-o comjsondecode(...). h5info(file, "/observations/obs_000001")fornece a mesma lista de atributos/conjuntos de dados exibida porh5disp, mas como uma struct que você pode percorrer programaticamente em vez de lê-la no console.
Limites e retenção #
- A exportação é feita por observação: um arquivo, uma observação.
- Somente dados canônicos (processados) são exportados; os dados brutos, tais como foram enviados, nunca são incluídos.
- Os links para download expiram sete dias após a conclusão da exportação; os dados da observação subjacente não são alterados, portanto, basta exportar novamente.
Quer outro formato? #
Atualmente, HDF5 é o único formato de exportação. Se o seu fluxo de trabalho precisar de outra opção, como um CSV simples, outro formato de intercâmbio ou o formato nativo de uma ferramenta específica, fale conosco.
Fale com a equipe do DataCNVS