netcdf-c/nc_test4/tst_varms.c
2024-03-12 16:13:40 +00:00

266 lines
8.8 KiB
C

/* This is part of the netCDF package. Copyright 2018 University
Corporation for Atmospheric Research/Unidata. See COPYRIGHT file
for conditions of use.
Test netcdf-4 mapped var operations.
Remember, in C, last dimension of an array varies fastest in memory.
int data[2][3] is order in memory (0,0), (0,1), (0,2), (1,0), (1,1), (1,2).
applying map of (1,2) will reorder them in the following way:
(0,0), (1,0), (0,1), (1,1), (0,2), (1,2)
I wrote this in Jenny Lake Campground near Jackson, WY. This is a
bit of a change from my usual workplace. Given total mobility the
ability to work anywhere, I usually choose to work at home. Not
sure what this says about me or the modern world, but camping makes
a nice change of pace! Ed 8/19/5
$Id: tst_varms.c,v 1.9 2010/05/25 13:53:04 ed Exp $
*/
#include <nc_tests.h>
#include "err_macros.h"
#define FILE_NAME "tst_varms.nc"
#define DIM1_NAME "i"
#define DIM1_LEN 2
#define DIM2_NAME "j"
#define DIM2_LEN 3
#define VAR_NAME "Little_Jenny_Campground"
int
main(int argc, char **argv)
{
int ncid, varid, dimids[2];
int data[DIM1_LEN][DIM2_LEN], data_in[DIM1_LEN][DIM2_LEN];
int ndims_in, dimids_in[10], natts_in;
size_t start[2], count[2];
ptrdiff_t stride[2], map[2];
char name_in[NC_MAX_NAME+1];
nc_type xtype_in;
int nvars, natts, ndims, unlimdimid;
int i, j, k = 0;
printf("\n*** Testing netcdf-4 mapped variable functions.\n");
{
int data_2d[2][2], data_2d_in[2][2];
printf("*** testing mapping with 2x2 variable...");
/* Create phoney data. */
for (i = 0; i < 2; i++)
for (j = 0; j < 2; j++)
data_2d[i][j] = k++;
/* Create a file with one 2D variable of type int and write our
* data. */
if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
if (nc_def_dim(ncid, "i", 2, &dimids[0])) ERR;
if (nc_def_dim(ncid, "j", 2, &dimids[1])) ERR;
if (nc_def_var(ncid, VAR_NAME, NC_INT, 2, dimids, &varid)) ERR;
if (nc_enddef(ncid)) ERR;
if (nc_put_var_int(ncid, varid, (int *)data_2d)) ERR;
if (nc_close(ncid)) ERR;
/* Open the file and check. */
if (nc_open(FILE_NAME, 0, &ncid)) ERR;
if (nc_get_var_int(ncid, varid, (int *)data_2d_in)) ERR;
for (i = 0; i < 2; i++)
for (j = 0; j < 2; j++)
if (data_2d_in[i][j] != data_2d[i][j]) ERR;
/* Get a transpose of the array. I have no idea how to figure
* out the map array, but my first guess worked. */
start[0] = start[1] = 0;
count[0] = count[1] = 2;
stride[0] = stride[1] = 1;
map[0] = 1;
map[1] = 2;
if (nc_get_varm_int(ncid, varid, start, count, stride, map,
(int *)data_2d_in)) ERR;
for (i = 0; i < 2; i++)
for (j = 0; j < 2; j++)
if (data_2d_in[j][i] != data_2d[i][j]) ERR;
/* Now read the untransposed array. I still haven't much idea
* what these numbers mean. */
map[0] = 2;
map[1] = 1;
if (nc_get_varm_int(ncid, varid, start, count, stride, map,
(int *)data_2d_in)) ERR;
for (i = 0; i < 2; i++)
for (j = 0; j < 2; j++)
if (data_2d_in[i][j] != data_2d[i][j]) ERR;
if (nc_close(ncid)) ERR;
}
SUMMARIZE_ERR;
printf("*** testing mapping with 2x3 variable...");
{
int data_in_t[DIM2_LEN][DIM1_LEN];
/* Create some phoney data. */
k = 0;
for (i = 0; i < DIM1_LEN; i++)
for (j = 0; j < DIM2_LEN; j++)
data[i][j] = k++;
/* Create a file with one variable of type int. */
if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
if (nc_def_var(ncid, VAR_NAME, NC_INT, 2, dimids, &varid)) ERR;
if (nc_enddef(ncid)) ERR;
if (nc_put_var_int(ncid, varid, (int *)data)) ERR;
if (nc_close(ncid)) ERR;
/* Open the file and check. */
if (nc_open(FILE_NAME, 0, &ncid)) ERR;
if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in,
&natts_in)) ERR;
if (strcmp(name_in, VAR_NAME) || xtype_in != NC_INT ||
ndims_in != 2 || natts_in != 0 || dimids_in[0] != dimids[0] ||
dimids_in[1] != dimids[1]) ERR;
if (nc_get_var_int(ncid, varid, (int *)data_in)) ERR;
for (i = 0; i < DIM1_LEN; i++)
for (j = 0; j < DIM2_LEN; j++)
if (data_in[i][j] != data[i][j]) ERR;
/* Get a transpose of the array. */
start[0] = start[1] = 0;
count[0] = DIM1_LEN;
count[1] = DIM2_LEN;
stride[0] = stride[1] = 1;
map[0] = 1;
map[1] = 2;
if (nc_get_varm_int(ncid, varid, start, count, stride, map,
(int *)data_in_t)) ERR;
for (i = 0; i < DIM1_LEN; i++)
for (j = 0; j < DIM2_LEN; j++)
if (data_in_t[j][i] != data[i][j]) ERR;
if (nc_close(ncid)) ERR;
}
SUMMARIZE_ERR;
printf("*** testing simple example from C Users' Guide...");
{
#define D0 4
#define D1 3
#define D2 2
/* netCDF dimension inter-element distance */
/* ---------------- ---------------------- */
/* most rapidly varying 1 */
/* intermediate 2 (=imap[2]*2) */
/* most slowly varying 6 (=imap[1]*3) */
ptrdiff_t imap[3] = {6, 2, 1}, stride[3] = {1, 1, 1};
size_t start[3] = {0, 0, 0}, count[3] = {D0, D1, D2};
int ncid, varid, dimids[3];
float data[D0][D1][D2], data_in[D0][D1][D2];
for (i = 0; i < D0; i++)
for (j = 0; j < D1; j++)
for (k = 0; k < D2; k++)
data[i][j][k] = (float)(i + j + k);
/* Create a file with one variable of type float. */
if (nc_create(FILE_NAME, NC_CLOBBER, &ncid)) ERR;
if (nc_def_dim(ncid, "D0", D0, &dimids[0])) ERR;
if (nc_def_dim(ncid, "D1", D1, &dimids[1])) ERR;
if (nc_def_dim(ncid, "D2", D2, &dimids[2])) ERR;
if (nc_def_var(ncid, "Jackson_Hole", NC_FLOAT, 3, dimids, &varid)) ERR;
if (nc_enddef(ncid)) ERR;
if (nc_put_var_float(ncid, varid, (float *)data)) ERR;
if (nc_close(ncid)) ERR;
/* Open the file and check. */
if (nc_open(FILE_NAME, 0, &ncid)) ERR;
if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
if (ndims != 3 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR;
if (nc_get_var_float(ncid, 0, (float *)data_in)) ERR;
for (i = 0; i < D0; i++)
for (j = 0; j < D1; j++)
for (k = 0; k < D2; k++)
if (data_in[i][j][k] != data[i][j][k]) ERR;
/* Using the imap above I should get identical results
* (according to the manual). */
if (nc_get_varm_float(ncid, 0, start, count, stride, imap,
(float *)data_in)) ERR;
for (i = 0; i < D0; i++)
for (j = 0; j < D1; j++)
for (k = 0; k < D2; k++)
if (data_in[i][j][k] != data[i][j][k]) ERR;
/* Now let's mess things around a bit. */
/* imap[0] = 0; */
/* imap[1] = 1; */
/* imap[2] = 2; */
/* if (nc_get_varm_float(ncid, 0, start, count, stride, imap, */
/* (float *)data_in)) ERR; */
/* for (i = 0; i < D0; i++) */
/* for (j = 0; j < D1; j++) */
/* for (k = 0; k < D2; k++) */
/* if (data_in[i][j][k] != data[i][j][k]) ERR; */
if (nc_close(ncid)) ERR;
}
SUMMARIZE_ERR;
printf("*** testing transposed rh example from C Users' Guide...");
{
/*nc_set_log_level(2);*/
ptrdiff_t imap[2] = {1, 6}, stride[2] = {1, 1};
size_t start[2] = {0, 0}, count[2] = {6, 4};
int ncid, varid, dimids[3];
float data[4][6], data_in[6][4];
int k=0;
/* Phoney data. */
for (i = 0; i < 4; i++)
for (j = 0; j < 6; j++)
{
data[i][j] = (float)k;
data_in[j][i] = (float)k;
k++;
}
/* Create a file with one variable of type float, writing a transposed array. */
if (nc_create(FILE_NAME, 0, &ncid)) ERR;
if (nc_def_dim(ncid, "lat", 6, &dimids[0])) ERR;
if (nc_def_dim(ncid, "lon", 4, &dimids[1])) ERR;
if (nc_def_var(ncid, "rh", NC_FLOAT, 2, dimids, &varid)) ERR;
dimids[0] = 1;
dimids[1] = 0;
if (nc_def_var(ncid, "rh2", NC_FLOAT, 2, dimids, &varid)) ERR;
if (nc_enddef(ncid)) ERR;
if (nc_put_varm_float(ncid, 0, start, count, stride, imap,
(float *)data)) ERR;
count[0] = 4;
count[1] = 6;
if (nc_put_vara_float(ncid, 1, start, count,
(float *)data_in)) ERR;
if (nc_close(ncid)) ERR;
/* Open the file and check. */
if (nc_open(FILE_NAME, 0, &ncid)) ERR;
if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
if (ndims != 2 || nvars != 2 || natts != 0 || unlimdimid != -1) ERR;
if (nc_get_var_float(ncid, 0, (float *)data_in)) ERR;
/* for (i = 0; i < 4; i++) */
/* for (j = 0; j < 6; j++) */
/* if (data_in[i][j] != data[j][i]) ERR; */
if (nc_close(ncid)) ERR;
}
SUMMARIZE_ERR;
FINAL_RESULTS;
}