NetCDF
Nesta seção:
Descrição
De acordo com a página do NetCDF, NetCDF (Network Common Data Form) é um conjunto de bibliotecas e formatos de dados independentes de máquina que suportam a criação, acesso e compartilhamento de dados científicos orientados a arrays. É também um padrão comunitário para compartilhamento de dados científicos.
Versões Disponíveis
netcdf/c/4.6.3 (default)
netcdf/fortran/4.4.5 (default)
Carregando Módulos
# Para C
module load netcdf/c/4.6.3
# Para Fortran
module load netcdf/fortran/4.4.5
# Para ambos
module load netcdf/c/4.6.3
module load netcdf/fortran/4.4.5
Compilação com NetCDF
C
#!/bin/bash
#SBATCH -J compile_netcdf_c
#SBATCH -N 1
#SBATCH -n 1
#SBATCH -t 00:10:00
#SBATCH --mem=2G
export INPUT="read_write.c"
export OUTPUT="read_write"
module load netcdf/c/4.6.3
job-nanny gcc -o read_write read_write.c -lnetcdf
Fortran
#!/bin/bash
#SBATCH -J compile_netcdf_fortran
#SBATCH -N 1
#SBATCH -n 1
#SBATCH -t 00:10:00
#SBATCH --mem=2G
export INPUT="read_write.f90"
export OUTPUT="read_write"
module load netcdf/fortran/4.4.5
job-nanny gfortran -o read_write read_write.f90 -lnetcdff
Exemplo de Código C
#include <netcdf.h>
#include <stdio.h>
#include <stdlib.h>
#define NDIMS 2
#define NX 6
#define NY 12
int main() {
int ncid, x_dimid, y_dimid, varid;
int dimids[NDIMS];
int data[NX][NY];
int retval;
// Criar dados
for (int i = 0; i < NX; i++)
for (int j = 0; j < NY; j++)
data[i][j] = i * NY + j;
// Criar arquivo
if ((retval = nc_create("simple.nc", NC_CLOBBER, &ncid)))
return retval;
// Definir dimensões
if ((retval = nc_def_dim(ncid, "x", NX, &x_dimid)))
return retval;
if ((retval = nc_def_dim(ncid, "y", NY, &y_dimid)))
return retval;
// Definir variável
dimids[0] = x_dimid;
dimids[1] = y_dimid;
if ((retval = nc_def_var(ncid, "data", NC_INT, NDIMS,
dimids, &varid)))
return retval;
// Sair do modo de definição
if ((retval = nc_enddef(ncid)))
return retval;
// Escrever dados
if ((retval = nc_put_var_int(ncid, varid, &data[0][0])))
return retval;
// Fechar arquivo
if ((retval = nc_close(ncid)))
return retval;
printf("Arquivo simple.nc criado com sucesso!\n");
return 0;
}
Exemplo de Código Fortran
program write_netcdf
use netcdf
implicit none
integer :: ncid, x_dimid, y_dimid, varid
integer, parameter :: NX = 6, NY = 12
integer :: data(NX, NY)
integer :: i, j
! Criar dados
do i = 1, NX
do j = 1, NY
data(i,j) = (i-1)*NY + (j-1)
end do
end do
! Criar arquivo
call check( nf90_create("simple_f.nc", NF90_CLOBBER, ncid) )
! Definir dimensões
call check( nf90_def_dim(ncid, "x", NX, x_dimid) )
call check( nf90_def_dim(ncid, "y", NY, y_dimid) )
! Definir variável
call check( nf90_def_var(ncid, "data", NF90_INT, &
(/ x_dimid, y_dimid /), varid) )
! Sair do modo de definição
call check( nf90_enddef(ncid) )
! Escrever dados
call check( nf90_put_var(ncid, varid, data) )
! Fechar arquivo
call check( nf90_close(ncid) )
print *, "Arquivo simple_f.nc criado com sucesso!"
contains
subroutine check(status)
integer, intent(in) :: status
if (status /= nf90_noerr) then
print *, trim(nf90_strerror(status))
stop
end if
end subroutine check
end program write_netcdf
Script para Processamento em Lote
#!/bin/bash
#SBATCH -J netcdf_process
#SBATCH -N 1
#SBATCH -n 1
#SBATCH -t 04:00:00
#SBATCH --mem=8G
export INPUT="dados/*.nc"
export OUTPUT="processados/"
module load netcdf/c/4.6.3
module load netcdf4-python
mkdir -p processados
cat > process_netcdf.py << 'EOF'
import netCDF4 as nc
import numpy as np
import glob
import os
# Processar todos os arquivos .nc
for arquivo in glob.glob('dados/*.nc'):
print(f"Processando {arquivo}...")
# Abrir arquivo
ds = nc.Dataset(arquivo, 'r')
# Ler variáveis
for var_name in ds.variables:
var = ds.variables[var_name]
# Calcular estatísticas
data = var[:]
if data.size > 0:
media = np.mean(data)
desvio = np.std(data)
minimo = np.min(data)
maximo = np.max(data)
print(f" {var_name}: média={media:.3f}, "
f"desvio={desvio:.3f}, min={minimo:.3f}, max={maximo:.3f}")
# Salvar resultados
nome_base = os.path.basename(arquivo)
with open(f"processados/{nome_base}.txt", 'w') as f:
f.write(f"Análise de {arquivo}\n")
for var_name in ds.variables:
var = ds.variables[var_name]
data = var[:]
if data.size > 0:
f.write(f"{var_name}: {np.mean(data):.6f} "
f"{np.std(data):.6f}\n")
ds.close()
EOF
python3 process_netcdf.py
Ferramentas de Linha de Comando
O NetCDF inclui utilitários de linha de comando úteis:
# Informações sobre o arquivo
ncdump -h arquivo.nc
# Extrair dados em formato texto
ncdump arquivo.nc > arquivo.cdl
# Comparar arquivos
ncdiff -v var arquivo1.nc arquivo2.nc diff.nc
# Juntar arquivos no tempo
ncrcat arquivo1.nc arquivo2.nc arquivo3.nc saida.nc
Job Array para Processamento Paralelo
#!/bin/bash
#SBATCH -J netcdf_array
#SBATCH --array=1-20
#SBATCH -N 1
#SBATCH -n 1
#SBATCH -t 02:00:00
#SBATCH --mem=4G
ARQUIVOS=($(ls dados/*.nc))
ARQUIVO=${ARQUIVOS[$SLURM_ARRAY_TASK_ID-1]}
export INPUT="$ARQUIVO"
export OUTPUT="saida_${SLURM_ARRAY_TASK_ID}/"
module load netcdf/c/4.6.3
mkdir -p saida_${SLURM_ARRAY_TASK_ID}
cd saida_${SLURM_ARRAY_TASK_ID}
# Extrair metadados
ncdump -h ../$ARQUIVO > metadados.txt
# Extrair variáveis específicas
ncdump -v temperatura ../$ARQUIVO > temperatura.txt
Referências
Documentação: https://www.unidata.ucar.edu/software/netcdf/documentation/
Guia do Usuário: https://www.unidata.ucar.edu/software/netcdf/docs/
NetCDF4 Python: https://unidata.github.io/netcdf4-python/
Ver também
HDF5 - Formato similar para dados hierárquicos
Python Runtime Services - Processamento com Python
Processando Simulações - Como submeter jobs