initial upload
This commit is contained in:
parent
e1b16f2e3f
commit
df80d03bd7
10
CMakeLists.txt
Normal file
10
CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
cmake_minimum_required(VERSION 3.15.2)
|
||||
|
||||
# 设置工程名称和语言
|
||||
project(NETCDF_CXX)
|
||||
|
||||
message(STATUS "Platform: " ${CMAKE_HOST_SYSTEM_NAME})
|
||||
set(CMAKE_INSTALL_PREFIX "D:/Library")
|
||||
|
||||
# 添加源文件地址
|
||||
add_subdirectory(src/)
|
1
src/.gitignore
vendored
Normal file
1
src/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
build/
|
61
src/CMakeLists.txt
Normal file
61
src/CMakeLists.txt
Normal file
@ -0,0 +1,61 @@
|
||||
# 设定源文件文件夹
|
||||
aux_source_directory(lib/ NETCDF_SRC)
|
||||
# 设置netcdf c接口的库文件地址
|
||||
set(LIB_NETCDF_INC C:/Program\ Files/netCDF\ 4.8.0/include)
|
||||
set(LIB_NETCDF_LIB C:/Program\ Files/netCDF\ 4.8.0/lib)
|
||||
# netcdf安装后的动态库与静态库的地址不一样 需要手动在cmake生成的VS工程内添加下面的库地址
|
||||
# 方法如下:gctl->属性->链接器->附件库目录(选择编辑,并选择netcdf的可执行文件地址)
|
||||
#set(LIB_NETCDF_BIN C:/Program\ Files/netCDF\ 4.8.0/bin)
|
||||
include_directories(${LIB_NETCDF_INC})
|
||||
|
||||
# 设置编译选项
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")
|
||||
# 设置库文件的输出地址
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
|
||||
|
||||
# 以下部分为库的编译
|
||||
# 注意目标名必须唯一 所以不能直接生成相同名称的动态库与静态库
|
||||
# 注意此处不必为目标名称添加lib前缀和相应后缀,cmake会自行添加
|
||||
add_library(netcdf_c++ SHARED ${NETCDF_SRC})
|
||||
# 首先添加静态库的生成命令
|
||||
add_library(netcdf_c++_static STATIC ${NETCDF_SRC})
|
||||
# 设置静态库的输出名称从而获得与动态库名称相同的静态库
|
||||
set_target_properties(netcdf_c++_static PROPERTIES OUTPUT_NAME "netcdf_c++")
|
||||
# 设置输出目标属性以同时输出动态库与静态库
|
||||
set_target_properties(netcdf_c++ PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
||||
set_target_properties(netcdf_c++_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
||||
# 设置动态库的版本号
|
||||
set_target_properties(netcdf_c++ PROPERTIES VERSION 1.0 SOVERSION 1.0)
|
||||
|
||||
find_library(NETCDF_LIBRARY netcdf ${LIB_NETCDF_LIB})
|
||||
target_link_libraries(netcdf_c++ PUBLIC ${NETCDF_LIBRARY})
|
||||
target_link_libraries(netcdf_c++_static ${NETCDF_LIBRARY})
|
||||
|
||||
# 库的安装命令
|
||||
install(TARGETS netcdf_c++ DESTINATION lib)
|
||||
install(TARGETS netcdf_c++_static DESTINATION lib)
|
||||
# 头文件安装命令
|
||||
install(FILES lib/netcdfcpp.h DESTINATION include)
|
||||
install(FILES lib/ncvalues.h DESTINATION include)
|
||||
|
||||
# 以下部分为例子程序的编译
|
||||
# 设置可执行文件的输出地址
|
||||
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||
|
||||
# 例子的编译方法
|
||||
macro(add_sample name)
|
||||
# 添加可执行文件 命令行
|
||||
add_executable(${name} example/${name}.cpp)
|
||||
# 为安装文件添加动态库的搜索地址 在Windows下并没有什么用 直接忽略
|
||||
set_target_properties(${name} PROPERTIES INSTALL_RPATH D:/Library/lib)
|
||||
# 链接动态库
|
||||
target_link_libraries(${name} PUBLIC netcdf_c++)
|
||||
endmacro()
|
||||
|
||||
add_sample(pres_temp_4D_rd)
|
||||
add_sample(pres_temp_4D_wr)
|
||||
add_sample(sfc_pres_temp_rd)
|
||||
add_sample(sfc_pres_temp_wr)
|
||||
add_sample(simple_xy_rd)
|
||||
add_sample(simple_xy_wr)
|
126
src/example/pres_temp_4D_rd.cpp
Normal file
126
src/example/pres_temp_4D_rd.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
/* This is part of the netCDF package.
|
||||
Copyright 2006 University Corporation for Atmospheric Research/Unidata.
|
||||
See COPYRIGHT file for conditions of use.
|
||||
|
||||
This is an example which reads some 4D pressure and temperature
|
||||
values. The data file read by this program is produced by the
|
||||
companion program pres_temp_4D_wr.cpp. It is intended to illustrate
|
||||
the use of the netCDF C++ API.
|
||||
|
||||
This program is part of the netCDF tutorial:
|
||||
http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-tutorial
|
||||
|
||||
Full documentation of the netCDF C++ API can be found at:
|
||||
http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-cxx
|
||||
|
||||
$Id: pres_temp_4D_rd.cpp,v 1.13 2007/02/14 20:59:21 ed Exp $
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <netcdfcpp.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// We are writing 4D data, a 2 x 6 x 12 lvl-lat-lon grid, with 2
|
||||
// timesteps of data.
|
||||
static const int NLVL = 2;
|
||||
static const int NLAT = 6;
|
||||
static const int NLON = 12;
|
||||
static const int NREC = 2;
|
||||
|
||||
// These are used to construct some example data.
|
||||
static const float SAMPLE_PRESSURE = 900.0;
|
||||
static const float SAMPLE_TEMP = 9.0;
|
||||
static const float START_LAT = 25.0;
|
||||
static const float START_LON = -125.0;
|
||||
|
||||
// Return this code to the OS in case of failure.
|
||||
static const int NC_ERR = 2;
|
||||
|
||||
int main()
|
||||
{
|
||||
// These arrays will store the latitude and longitude values.
|
||||
float lats[NLAT], lons[NLON];
|
||||
|
||||
// These arrays will hold the data we will read in. We will only
|
||||
// need enough space to hold one timestep of data; one record.
|
||||
float pres_in[NLVL][NLAT][NLON];
|
||||
float temp_in[NLVL][NLAT][NLON];
|
||||
|
||||
// Change the error behavior of the netCDF C++ API by creating an
|
||||
// NcError object. Until it is destroyed, this NcError object will
|
||||
// ensure that the netCDF C++ API returns error codes on any
|
||||
// failure, prints an error message, and leaves any other error
|
||||
// handling to the calling program. In the case of this example, we
|
||||
// just exit with an NC_ERR error code.
|
||||
NcError err(NcError::verbose_nonfatal);
|
||||
|
||||
// Open the file.
|
||||
NcFile dataFile("pres_temp_4D.nc", NcFile::ReadOnly);
|
||||
|
||||
// Check to see if the file was opened.
|
||||
if(!dataFile.is_valid())
|
||||
return NC_ERR;
|
||||
|
||||
// Get pointers to the latitude and longitude variables.
|
||||
NcVar *latVar, *lonVar;
|
||||
if (!(latVar = dataFile.get_var("latitude")))
|
||||
return NC_ERR;
|
||||
if (!(lonVar = dataFile.get_var("longitude")))
|
||||
return NC_ERR;
|
||||
|
||||
// Get the lat/lon data from the file.
|
||||
if (!latVar->get(lats, NLAT))
|
||||
return NC_ERR;
|
||||
if (!lonVar->get(lons, NLON))
|
||||
return NC_ERR;
|
||||
|
||||
// Check the coordinate variable data.
|
||||
for (int lat = 0; lat < NLAT; lat++)
|
||||
if (lats[lat] != START_LAT + 5. * lat)
|
||||
return NC_ERR;
|
||||
for (int lon = 0; lon < NLON; lon++)
|
||||
if (lons[lon] != START_LON + 5. * lon)
|
||||
return NC_ERR;
|
||||
|
||||
// Get pointers to the pressure and temperature variables.
|
||||
NcVar *presVar, *tempVar;
|
||||
if (!(presVar = dataFile.get_var("pressure")))
|
||||
return NC_ERR;
|
||||
if (!(tempVar = dataFile.get_var("temperature")))
|
||||
return NC_ERR;
|
||||
|
||||
// Read the data. Since we know the contents of the file we know
|
||||
// that the data arrays in this program are the correct size to
|
||||
// hold one timestep.
|
||||
for (int rec = 0; rec < NREC; rec++)
|
||||
{
|
||||
// Read the data one record at a time.
|
||||
if (!presVar->set_cur(rec, 0, 0, 0))
|
||||
return NC_ERR;
|
||||
if (!tempVar->set_cur(rec, 0, 0, 0))
|
||||
return NC_ERR;
|
||||
|
||||
// Get 1 record of NLVL by NLAT by NLON values for each variable.
|
||||
if (!presVar->get(&pres_in[0][0][0], 1, NLVL, NLAT, NLON))
|
||||
return NC_ERR;
|
||||
if (!tempVar->get(&temp_in[0][0][0], 1, NLVL, NLAT, NLON))
|
||||
return NC_ERR;
|
||||
|
||||
// Check the data.
|
||||
int i = 0;
|
||||
for (int lvl = 0; lvl < NLVL; lvl++)
|
||||
for (int lat = 0; lat < NLAT; lat++)
|
||||
for (int lon = 0; lon < NLON; lon++)
|
||||
if (pres_in[lvl][lat][lon] != SAMPLE_PRESSURE + i ||
|
||||
temp_in[lvl][lat][lon] != SAMPLE_TEMP + i++)
|
||||
return NC_ERR;
|
||||
} // next record
|
||||
|
||||
// The file is automatically closed by the destructor. This frees
|
||||
// up any internal netCDF resources associated with the file, and
|
||||
// flushes any buffers.
|
||||
|
||||
cout << "*** SUCCESS reading example file pres_temp_4D.nc!" << endl;
|
||||
return 0;
|
||||
}
|
149
src/example/pres_temp_4D_wr.cpp
Normal file
149
src/example/pres_temp_4D_wr.cpp
Normal file
@ -0,0 +1,149 @@
|
||||
/* This is part of the netCDF package.
|
||||
Copyright 2006 University Corporation for Atmospheric Research/Unidata.
|
||||
See COPYRIGHT file for conditions of use.
|
||||
|
||||
This is an example program which writes some 4D pressure and
|
||||
temperatures. This example demonstrates the netCDF C++ API.
|
||||
|
||||
This is part of the netCDF tutorial:
|
||||
http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-tutorial
|
||||
|
||||
Full documentation of the netCDF C++ API can be found at:
|
||||
http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-cxx
|
||||
|
||||
$Id: pres_temp_4D_wr.cpp,v 1.11 2007/01/19 12:52:13 ed Exp $
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <netcdfcpp.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// We are writing 4D data, a 2 x 6 x 12 lvl-lat-lon grid, with 2
|
||||
// timesteps of data.
|
||||
static const int NLVL = 2;
|
||||
static const int NLAT = 6;
|
||||
static const int NLON = 12;
|
||||
static const int NREC = 2;
|
||||
|
||||
// These are used to construct some example data.
|
||||
static const float SAMPLE_PRESSURE = 900.0;
|
||||
static const float SAMPLE_TEMP = 9.0;
|
||||
static const float START_LAT = 25.0;
|
||||
static const float START_LON = -125.0;
|
||||
|
||||
// Return this code to the OS in case of failure.
|
||||
static const int NC_ERR = 2;
|
||||
|
||||
int main()
|
||||
{
|
||||
// These arrays will store the latitude and longitude values.
|
||||
float lats[NLAT],lons[NLON];
|
||||
|
||||
// These arrays will hold the data we will write out. We will
|
||||
// only need enough space to hold one timestep of data; one record.
|
||||
float pres_out[NLVL][NLAT][NLON];
|
||||
float temp_out[NLVL][NLAT][NLON];
|
||||
|
||||
int i = 0;
|
||||
|
||||
// Create some pretend data. If this wasn't an example program, we
|
||||
// would have some real data to write for example, model output.
|
||||
for (int lat = 0; lat < NLAT; lat++)
|
||||
lats[lat] = START_LAT + 5. * lat;
|
||||
for (int lon = 0; lon < NLON; lon++)
|
||||
lons[lon] = START_LON + 5. * lon;
|
||||
|
||||
for (int lvl = 0; lvl < NLVL; lvl++)
|
||||
for (int lat = 0; lat < NLAT; lat++)
|
||||
for (int lon = 0; lon < NLON; lon++)
|
||||
{
|
||||
pres_out[lvl][lat][lon] = SAMPLE_PRESSURE + i;
|
||||
temp_out[lvl][lat][lon] = SAMPLE_TEMP + i++;
|
||||
}
|
||||
|
||||
// Change the error behavior of the netCDF C++ API by creating an
|
||||
// NcError object. Until it is destroyed, this NcError object will
|
||||
// ensure that the netCDF C++ API returns error codes on any
|
||||
// failure, prints an error message, and leaves any other error
|
||||
// handling to the calling program. In the case of this example, we
|
||||
// just exit with an NC_ERR error code.
|
||||
NcError err(NcError::verbose_nonfatal);
|
||||
|
||||
// Create the file.
|
||||
NcFile dataFile("pres_temp_4D.nc", NcFile::Replace);
|
||||
|
||||
// Check to see if the file was created.
|
||||
if(!dataFile.is_valid())
|
||||
return NC_ERR;
|
||||
|
||||
// Define the dimensions. NetCDF will hand back an ncDim object for
|
||||
// each.
|
||||
NcDim *lvlDim, *latDim, *lonDim, *recDim;
|
||||
if (!(lvlDim = dataFile.add_dim("level", NLVL)))
|
||||
return NC_ERR;
|
||||
if (!(latDim = dataFile.add_dim("latitude", NLAT)))
|
||||
return NC_ERR;
|
||||
if (!(lonDim = dataFile.add_dim("longitude", NLON)))
|
||||
return NC_ERR;
|
||||
// Add an unlimited dimension...
|
||||
if (!(recDim = dataFile.add_dim("time")))
|
||||
return NC_ERR;
|
||||
|
||||
// Define the coordinate variables.
|
||||
NcVar *latVar, *lonVar;
|
||||
if (!(latVar = dataFile.add_var("latitude", ncFloat, latDim)))
|
||||
return NC_ERR;
|
||||
if (!(lonVar = dataFile.add_var("longitude", ncFloat, lonDim)))
|
||||
return NC_ERR;
|
||||
|
||||
// Define units attributes for coordinate vars. This attaches a
|
||||
// text attribute to each of the coordinate variables, containing
|
||||
// the units.
|
||||
if (!latVar->add_att("units", "degrees_north"))
|
||||
return NC_ERR;
|
||||
if (!lonVar->add_att("units", "degrees_east"))
|
||||
return NC_ERR;
|
||||
|
||||
// Define the netCDF variables for the pressure and temperature
|
||||
// data.
|
||||
NcVar *presVar, *tempVar;
|
||||
if (!(presVar = dataFile.add_var("pressure", ncFloat, recDim,
|
||||
lvlDim, latDim, lonDim)))
|
||||
return NC_ERR;
|
||||
if (!(tempVar = dataFile.add_var("temperature", ncFloat, recDim,
|
||||
lvlDim, latDim, lonDim)))
|
||||
return NC_ERR;
|
||||
|
||||
// Define units attributes for data variables.
|
||||
if (!presVar->add_att("units", "hPa"))
|
||||
return NC_ERR;
|
||||
if (!tempVar->add_att("units", "celsius"))
|
||||
return NC_ERR;
|
||||
|
||||
// Write the coordinate variable data to the file.
|
||||
if (!latVar->put(lats, NLAT))
|
||||
return NC_ERR;
|
||||
if (!lonVar->put(lons, NLON))
|
||||
return NC_ERR;
|
||||
|
||||
// Write the pretend data. This will write our surface pressure and
|
||||
// surface temperature data. The arrays only hold one timestep
|
||||
// worth of data. We will just rewrite the same data for each
|
||||
// timestep. In a real application, the data would change between
|
||||
// timesteps.
|
||||
for (int rec = 0; rec < NREC; rec++)
|
||||
{
|
||||
if (!presVar->put_rec(&pres_out[0][0][0], rec))
|
||||
return NC_ERR;
|
||||
if (!tempVar->put_rec(&temp_out[0][0][0], rec))
|
||||
return NC_ERR;
|
||||
}
|
||||
|
||||
// The file is automatically closed by the destructor. This frees
|
||||
// up any internal netCDF resources associated with the file, and
|
||||
// flushes any buffers.
|
||||
|
||||
cout << "*** SUCCESS writing example file pres_temp_4D.nc!" << endl;
|
||||
return 0;
|
||||
}
|
161
src/example/sfc_pres_temp_rd.cpp
Normal file
161
src/example/sfc_pres_temp_rd.cpp
Normal file
@ -0,0 +1,161 @@
|
||||
/* This is part of the netCDF package.
|
||||
Copyright 2006 University Corporation for Atmospheric Research/Unidata.
|
||||
See COPYRIGHT file for conditions of use.
|
||||
|
||||
This is an example which reads some surface pressure and
|
||||
temperatures. The data file read by this program is produced
|
||||
companion program sfc_pres_temp_wr.cxx. It is intended to
|
||||
illustrate the use of the netCDF C++ API.
|
||||
|
||||
This program is part of the netCDF tutorial:
|
||||
http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-tutorial
|
||||
|
||||
Full documentation of the netCDF C++ API can be found at:
|
||||
http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-cxx
|
||||
|
||||
$Id: sfc_pres_temp_rd.cpp,v 1.17 2008/05/16 13:42:28 ed Exp $
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <netcdfcpp.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// We are reading 2D data, a 6 x 12 lat-lon grid.
|
||||
static const int NLAT = 6;
|
||||
static const int NLON = 12;
|
||||
|
||||
// These are used to calculate the values we expect to find.
|
||||
static const float SAMPLE_PRESSURE = 900;
|
||||
static const float SAMPLE_TEMP = 9.0;
|
||||
static const float START_LAT = 25.0;
|
||||
static const float START_LON = -125.0;
|
||||
|
||||
// Return this code to the OS in case of failure.
|
||||
static const int NC_ERR = 2;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// These will hold our pressure and temperature data.
|
||||
float presIn[NLAT][NLON];
|
||||
float tempIn[NLAT][NLON];
|
||||
|
||||
// These will hold our latitudes and longitudes.
|
||||
float latsIn[NLAT];
|
||||
float lonsIn[NLON];
|
||||
|
||||
// Change the error behavior of the netCDF C++ API by creating an
|
||||
// NcError object. Until it is destroyed, this NcError object will
|
||||
// ensure that the netCDF C++ API silently returns error codes on
|
||||
// any failure, and leaves any other error handling to the calling
|
||||
// program. In the case of this example, we just exit with an
|
||||
// NC_ERR error code.
|
||||
NcError err(NcError::silent_nonfatal);
|
||||
|
||||
// Open the file and check to make sure it's valid.
|
||||
NcFile dataFile("sfc_pres_temp.nc", NcFile::ReadOnly);
|
||||
if(!dataFile.is_valid())
|
||||
return NC_ERR;
|
||||
|
||||
// There are a number of inquiry functions in netCDF which can be
|
||||
// used to learn about an unknown netCDF file. In this case we know
|
||||
// that there are 2 netCDF dimensions, 4 netCDF variables, no
|
||||
// global attributes, and no unlimited dimension.
|
||||
if (dataFile.num_dims() != 2 || dataFile.num_vars() != 4 ||
|
||||
dataFile.num_atts() != 0 || dataFile.rec_dim() != 0)
|
||||
return NC_ERR;
|
||||
|
||||
// We get back a pointer to each NcVar we request. Get the
|
||||
// latitude and longitude coordinate variables.
|
||||
NcVar *latVar, *lonVar;
|
||||
if (!(latVar = dataFile.get_var("latitude")))
|
||||
return NC_ERR;
|
||||
if (!(lonVar = dataFile.get_var("longitude")))
|
||||
return NC_ERR;
|
||||
|
||||
// Read the latitude and longitude coordinate variables into arrays
|
||||
// latsIn and lonsIn.
|
||||
if (!latVar->get(latsIn, NLAT))
|
||||
return NC_ERR;
|
||||
if (!lonVar->get(lonsIn, NLON))
|
||||
return NC_ERR;
|
||||
|
||||
// Check the coordinate variable data.
|
||||
for(int lat = 0; lat < NLAT; lat++)
|
||||
if (latsIn[lat] != START_LAT + 5. * lat)
|
||||
return NC_ERR;
|
||||
|
||||
// Check longitude values.
|
||||
for (int lon = 0; lon < NLON; lon++)
|
||||
if (lonsIn[lon] != START_LON + 5. * lon)
|
||||
return NC_ERR;
|
||||
|
||||
// We get back a pointer to each NcVar we request.
|
||||
NcVar *presVar, *tempVar;
|
||||
if (!(presVar = dataFile.get_var("pressure")))
|
||||
return NC_ERR;
|
||||
if (!(tempVar = dataFile.get_var("temperature")))
|
||||
return NC_ERR;
|
||||
|
||||
// Read the data. Since we know the contents of the file we know
|
||||
// that the data arrays in this program are the correct size to
|
||||
// hold all the data.
|
||||
if (!presVar->get(&presIn[0][0], NLAT, NLON))
|
||||
return NC_ERR;
|
||||
if (!tempVar->get(&tempIn[0][0], NLAT, NLON))
|
||||
return NC_ERR;
|
||||
|
||||
// Check the data.
|
||||
for (int lat = 0; lat < NLAT; lat++)
|
||||
for (int lon = 0; lon < NLON; lon++)
|
||||
if (presIn[lat][lon] != SAMPLE_PRESSURE + (lon * NLAT + lat)
|
||||
|| tempIn[lat][lon] != SAMPLE_TEMP + .25 * (lon * NLAT + lat))
|
||||
return NC_ERR;
|
||||
|
||||
// Each of the netCDF variables has a "units" attribute. Let's read
|
||||
// them and check them.
|
||||
NcAtt *att;
|
||||
char *units;
|
||||
|
||||
if (!(att = latVar->get_att("units")))
|
||||
return NC_ERR;
|
||||
units = att->as_string(0);
|
||||
if (strncmp(units, "degrees_north", strlen("degrees_north")))
|
||||
return NC_ERR;
|
||||
// Attributes and attribute values should be deleted by the caller
|
||||
// when no longer needed, to prevent memory leaks.
|
||||
delete units;
|
||||
delete att;
|
||||
|
||||
if (!(att = lonVar->get_att("units")))
|
||||
return NC_ERR;
|
||||
units = att->as_string(0);
|
||||
if (strncmp(units, "degrees_east", strlen("degrees_east")))
|
||||
return NC_ERR;
|
||||
delete units;
|
||||
delete att;
|
||||
|
||||
if (!(att = presVar->get_att("units")))
|
||||
return NC_ERR;
|
||||
units = att->as_string(0);
|
||||
if (strncmp(units, "hPa", strlen("hPa")))
|
||||
return NC_ERR;
|
||||
delete units;
|
||||
delete att;
|
||||
|
||||
if (!(att = tempVar->get_att("units")))
|
||||
return NC_ERR;
|
||||
units = att->as_string(0);
|
||||
if (strncmp(units, "celsius", strlen("celsius")))
|
||||
return NC_ERR;
|
||||
delete units;
|
||||
delete att;
|
||||
|
||||
// The file will be automatically closed by the destructor. This
|
||||
// frees up any internal netCDF resources associated with the file,
|
||||
// and flushes any buffers.
|
||||
cout << "*** SUCCESS reading example file sfc_pres_temp.nc!" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
142
src/example/sfc_pres_temp_wr.cpp
Normal file
142
src/example/sfc_pres_temp_wr.cpp
Normal file
@ -0,0 +1,142 @@
|
||||
/* This is part of the netCDF package.
|
||||
Copyright 2006 University Corporation for Atmospheric Research/Unidata.
|
||||
See COPYRIGHT file for conditions of use.
|
||||
|
||||
This example writes some surface pressure and temperatures. It is
|
||||
intended to illustrate the use of the netCDF C++ API. The companion
|
||||
program sfc_pres_temp_rd.cpp shows how to read the netCDF data file
|
||||
created by this program.
|
||||
|
||||
This program is part of the netCDF tutorial:
|
||||
http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-tutorial
|
||||
|
||||
Full documentation of the netCDF C++ API can be found at:
|
||||
http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-cxx
|
||||
|
||||
$Id: sfc_pres_temp_wr.cpp,v 1.12 2007/01/19 12:52:13 ed Exp $
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <netcdfcpp.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// We are writing 2D data, a 6 x 12 lat-lon grid. We will need two
|
||||
// netCDF dimensions.
|
||||
static const int NLAT = 6;
|
||||
static const int NLON = 12;
|
||||
|
||||
// These are used to construct some example data.
|
||||
static const float SAMPLE_PRESSURE = 900;
|
||||
static const float SAMPLE_TEMP = 9.0;
|
||||
static const float START_LAT = 25.0;
|
||||
static const float START_LON = -125.0;
|
||||
|
||||
// Return this to OS if there is a failure.
|
||||
static const int NC_ERR = 2;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// These will hold our pressure and temperature data.
|
||||
float presOut[NLAT][NLON];
|
||||
float tempOut[NLAT][NLON];
|
||||
|
||||
// These will hold our latitudes and longitudes.
|
||||
float lats[NLAT];
|
||||
float lons[NLON];
|
||||
|
||||
// Create some pretend data. If this wasn't an example program, we
|
||||
// would have some real data to write, for example, model
|
||||
// output.
|
||||
for(int lat = 0; lat < NLAT; lat++)
|
||||
lats[lat] = START_LAT + 5. * lat;
|
||||
|
||||
for(int lon = 0; lon < NLON; lon++)
|
||||
lons[lon] = START_LON + 5. * lon;
|
||||
|
||||
for (int lat = 0; lat < NLAT; lat++)
|
||||
for(int lon = 0; lon < NLON; lon++)
|
||||
{
|
||||
presOut[lat][lon] = SAMPLE_PRESSURE + (lon * NLAT + lat);
|
||||
tempOut[lat][lon] = SAMPLE_TEMP + .25 * (lon * NLAT + lat);
|
||||
}
|
||||
|
||||
// Change the error behavior of the netCDF C++ API by creating an
|
||||
// NcError object. Until it is destroyed, this NcError object will
|
||||
// ensure that the netCDF C++ API silently returns error codes
|
||||
// on any failure, and leaves any other error handling to the
|
||||
// calling program. In the case of this example, we just exit with
|
||||
// an NC_ERR error code.
|
||||
NcError err(NcError::silent_nonfatal);
|
||||
|
||||
// Create the file. The Replace parameter tells netCDF to overwrite
|
||||
// this file, if it already exists.
|
||||
NcFile dataFile("sfc_pres_temp.nc", NcFile::Replace);
|
||||
|
||||
// Check to see if the file was created.
|
||||
if(!dataFile.is_valid())
|
||||
return NC_ERR;
|
||||
|
||||
// Define the dimensions. NetCDF will hand back an ncDim object for
|
||||
// each.
|
||||
NcDim *latDim, *lonDim;
|
||||
if (!(latDim = dataFile.add_dim("latitude", NLAT)))
|
||||
return NC_ERR;
|
||||
if (!(lonDim = dataFile.add_dim("longitude", NLON)))
|
||||
return NC_ERR;
|
||||
|
||||
// In addition to the latitude and longitude dimensions, we will
|
||||
// also create latitude and longitude netCDF variables which will
|
||||
// hold the actual latitudes and longitudes. Since they hold data
|
||||
// about the coordinate system, the netCDF term for these is:
|
||||
// "coordinate variables."
|
||||
NcVar *latVar, *lonVar;
|
||||
if (!(latVar = dataFile.add_var("latitude", ncFloat, latDim)))
|
||||
return NC_ERR;
|
||||
if (!(lonVar = dataFile.add_var("longitude", ncFloat, lonDim)))
|
||||
return NC_ERR;
|
||||
|
||||
// Define units attributes for coordinate vars. This attaches a
|
||||
// text attribute to each of the coordinate variables, containing
|
||||
// the units.
|
||||
if (!lonVar->add_att("units", "degrees_east"))
|
||||
return NC_ERR;
|
||||
if (!latVar->add_att("units", "degrees_north"))
|
||||
return NC_ERR;
|
||||
|
||||
// Define the netCDF data variables.
|
||||
NcVar *presVar, *tempVar;
|
||||
if (!(presVar = dataFile.add_var("pressure", ncFloat, latDim, lonDim)))
|
||||
return NC_ERR;
|
||||
if (!(tempVar = dataFile.add_var("temperature", ncFloat, latDim, lonDim)))
|
||||
return NC_ERR;
|
||||
|
||||
// Define units attributes for variables.
|
||||
if (!presVar->add_att("units", "hPa"))
|
||||
return NC_ERR;
|
||||
if (!tempVar->add_att("units", "celsius"))
|
||||
return NC_ERR;
|
||||
|
||||
// Write the coordinate variable data. This will put the latitudes
|
||||
// and longitudes of our data grid into the netCDF file.
|
||||
if (!latVar->put(lats, NLAT))
|
||||
return NC_ERR;
|
||||
if (!lonVar->put(lons, NLON))
|
||||
return NC_ERR;
|
||||
|
||||
// Write the pretend data. This will write our surface pressure and
|
||||
// surface temperature data. The arrays of data are the same size
|
||||
// as the netCDF variables we have defined, and below we write them
|
||||
// each in one step.
|
||||
if (!presVar->put(&presOut[0][0], NLAT, NLON))
|
||||
return NC_ERR;
|
||||
if (!tempVar->put(&tempOut[0][0], NLAT, NLON))
|
||||
return NC_ERR;
|
||||
|
||||
// The file is automatically closed by the destructor. This frees
|
||||
// up any internal netCDF resources associated with the file, and
|
||||
// flushes any buffers.
|
||||
cout << "*** SUCCESS writing example file sfc_pres_temp.nc!" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
67
src/example/simple_xy_rd.cpp
Normal file
67
src/example/simple_xy_rd.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
/* This is part of the netCDF package.
|
||||
Copyright 2006 University Corporation for Atmospheric Research/Unidata.
|
||||
See COPYRIGHT file for conditions of use.
|
||||
|
||||
This is a very simple example which reads a 2D array of
|
||||
sample data produced by simple_xy_wr.cpp.
|
||||
|
||||
This example is part of the netCDF tutorial:
|
||||
http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-tutorial
|
||||
|
||||
Full documentation of the netCDF C++ API can be found at:
|
||||
http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-cxx
|
||||
|
||||
$Id: simple_xy_rd.cpp,v 1.13 2007/01/19 12:52:13 ed Exp $
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <netcdfcpp.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// We are reading 2D data, a 6 x 12 grid.
|
||||
static const int NX = 6;
|
||||
static const int NY = 12;
|
||||
|
||||
// Return this in event of a problem.
|
||||
static const int NC_ERR = 2;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// This is the array we will read.
|
||||
int dataIn[NX][NY];
|
||||
|
||||
// Open the file. The ReadOnly parameter tells netCDF we want
|
||||
// read-only access to the file.
|
||||
NcFile dataFile("simple_xy.nc", NcFile::ReadOnly);
|
||||
|
||||
// You should always check whether a netCDF file open or creation
|
||||
// constructor succeeded.
|
||||
if (!dataFile.is_valid())
|
||||
{
|
||||
cout << "Couldn't open file!\n";
|
||||
return NC_ERR;
|
||||
}
|
||||
|
||||
// For other method calls, the default behavior of the C++ API is
|
||||
// to exit with a message if there is an error. If that behavior
|
||||
// is OK, there is no need to check return values in simple cases
|
||||
// like the following.
|
||||
|
||||
// Retrieve the variable named "data"
|
||||
NcVar *data = dataFile.get_var("data");
|
||||
|
||||
// Read all the values from the "data" variable into memory.
|
||||
data->get(&dataIn[0][0], NX, NY);
|
||||
|
||||
// Check the values.
|
||||
for (int i = 0; i < NX; i++)
|
||||
for (int j = 0; j < NY; j++)
|
||||
if (dataIn[i][j] != i * NY + j)
|
||||
return NC_ERR;
|
||||
|
||||
// The netCDF file is automatically closed by the NcFile destructor
|
||||
cout << "*** SUCCESS reading example file simple_xy.nc!" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
80
src/example/simple_xy_wr.cpp
Normal file
80
src/example/simple_xy_wr.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
/* This is part of the netCDF package.
|
||||
Copyright 2006 University Corporation for Atmospheric Research/Unidata.
|
||||
See COPYRIGHT file for conditions of use.
|
||||
|
||||
This is a very simple example which writes a 2D array of
|
||||
sample data. To handle this in netCDF we create two shared
|
||||
dimensions, "x" and "y", and a netCDF variable, called "data".
|
||||
|
||||
This example is part of the netCDF tutorial:
|
||||
http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-tutorial
|
||||
|
||||
Full documentation of the netCDF C++ API can be found at:
|
||||
http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-cxx
|
||||
|
||||
$Id: simple_xy_wr.cpp,v 1.15 2007/01/19 12:52:13 ed Exp $
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <netcdfcpp.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// We are writing 2D data, a 6 x 12 grid.
|
||||
static const int NX = 6;
|
||||
static const int NY = 12;
|
||||
|
||||
// Return this in event of a problem.
|
||||
static const int NC_ERR = 2;
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
// This is the data array we will write. It will just be filled
|
||||
// with a progression of numbers for this example.
|
||||
int dataOut[NX][NY];
|
||||
|
||||
// Create some pretend data. If this wasn't an example program, we
|
||||
// would have some real data to write, for example, model output.
|
||||
for(int i = 0; i < NX; i++)
|
||||
for(int j = 0; j < NY; j++)
|
||||
dataOut[i][j] = i * NY + j;
|
||||
|
||||
// Create the file. The Replace parameter tells netCDF to overwrite
|
||||
// this file, if it already exists.
|
||||
NcFile dataFile("simple_xy.nc", NcFile::Replace);
|
||||
|
||||
// You should always check whether a netCDF file creation or open
|
||||
// constructor succeeded.
|
||||
if (!dataFile.is_valid())
|
||||
{
|
||||
cout << "Couldn't open file!\n";
|
||||
return NC_ERR;
|
||||
}
|
||||
|
||||
// For other method calls, the default behavior of the C++ API is
|
||||
// to exit with a message if there is an error. If that behavior
|
||||
// is OK, there is no need to check return values in simple cases
|
||||
// like the following.
|
||||
|
||||
// When we create netCDF dimensions, we get back a pointer to an
|
||||
// NcDim for each one.
|
||||
NcDim* xDim = dataFile.add_dim("x", NX);
|
||||
NcDim* yDim = dataFile.add_dim("y", NY);
|
||||
|
||||
// Define a netCDF variable. The type of the variable in this case
|
||||
// is ncInt (32-bit integer).
|
||||
NcVar *data = dataFile.add_var("data", ncInt, xDim, yDim);
|
||||
|
||||
// Write the pretend data to the file. Although netCDF supports
|
||||
// reading and writing subsets of data, in this case we write all
|
||||
// the data in one operation.
|
||||
data->put(&dataOut[0][0], NX, NY);
|
||||
|
||||
// The file will be automatically close when the NcFile object goes
|
||||
// out of scope. This frees up any internal netCDF resources
|
||||
// associated with the file, and flushes any buffers.
|
||||
cout << "*** SUCCESS writing example file simple_xy.nc!" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
332
src/lib/ncvalues.cpp
Normal file
332
src/lib/ncvalues.cpp
Normal file
@ -0,0 +1,332 @@
|
||||
/*********************************************************************
|
||||
* Copyright 1992, University Corporation for Atmospheric Research
|
||||
* See netcdf/README file for copying and redistribution conditions.
|
||||
*
|
||||
* Purpose: implementation of classes of typed arrays for netCDF
|
||||
*
|
||||
* $Header: /upc/share/CVS/netcdf-3/cxx/ncvalues.cpp,v 1.12 2008/03/05 16:45:32 russ Exp $
|
||||
*********************************************************************/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
#include "netcdf_config.h"
|
||||
#include "ncvalues.h"
|
||||
#pragma warning(disable : 4996)
|
||||
|
||||
NcValues::NcValues( void ) : the_type(ncNoType), the_number(0)
|
||||
{}
|
||||
|
||||
NcValues::NcValues(NcType type, long num)
|
||||
: the_type(type), the_number(num)
|
||||
{}
|
||||
|
||||
NcValues::~NcValues( void )
|
||||
{}
|
||||
|
||||
long NcValues::num( void )
|
||||
{
|
||||
return the_number;
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, const NcValues& vals)
|
||||
{
|
||||
return vals.print(os);
|
||||
}
|
||||
|
||||
implement(NcValues,ncbyte)
|
||||
implement(NcValues,char)
|
||||
implement(NcValues,short)
|
||||
implement(NcValues,int)
|
||||
implement(NcValues,nclong)
|
||||
implement(NcValues,long)
|
||||
implement(NcValues,float)
|
||||
implement(NcValues,double)
|
||||
|
||||
Ncbytes_for_one_implement(ncbyte)
|
||||
Ncbytes_for_one_implement(char)
|
||||
Ncbytes_for_one_implement(short)
|
||||
Ncbytes_for_one_implement(int)
|
||||
Ncbytes_for_one_implement(nclong)
|
||||
Ncbytes_for_one_implement(long)
|
||||
Ncbytes_for_one_implement(float)
|
||||
Ncbytes_for_one_implement(double)
|
||||
|
||||
as_ncbyte_implement(short)
|
||||
as_ncbyte_implement(int)
|
||||
as_ncbyte_implement(nclong)
|
||||
as_ncbyte_implement(long)
|
||||
as_ncbyte_implement(float)
|
||||
as_ncbyte_implement(double)
|
||||
|
||||
inline ncbyte NcValues_char::as_ncbyte( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
inline ncbyte NcValues_ncbyte::as_ncbyte( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
as_char_implement(short)
|
||||
as_char_implement(int)
|
||||
as_char_implement(nclong)
|
||||
as_char_implement(long)
|
||||
as_char_implement(float)
|
||||
as_char_implement(double)
|
||||
|
||||
inline char NcValues_ncbyte::as_char( long n ) const
|
||||
{
|
||||
return the_values[n] > CHAR_MAX ? ncBad_char : (char) the_values[n];
|
||||
}
|
||||
|
||||
inline char NcValues_char::as_char( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
as_short_implement(int)
|
||||
as_short_implement(nclong)
|
||||
as_short_implement(long)
|
||||
as_short_implement(float)
|
||||
as_short_implement(double)
|
||||
|
||||
inline short NcValues_ncbyte::as_short( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
inline short NcValues_char::as_short( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
inline short NcValues_short::as_short( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
|
||||
as_int_implement(float)
|
||||
as_int_implement(double)
|
||||
|
||||
inline int NcValues_ncbyte::as_int( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
inline int NcValues_char::as_int( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
inline int NcValues_short::as_int( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
inline int NcValues_int::as_int( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
inline int NcValues_nclong::as_int( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
inline int NcValues_long::as_int( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
as_nclong_implement(float)
|
||||
as_nclong_implement(double)
|
||||
|
||||
inline nclong NcValues_ncbyte::as_nclong( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
inline nclong NcValues_char::as_nclong( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
inline nclong NcValues_short::as_nclong( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
inline nclong NcValues_int::as_nclong( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
inline nclong NcValues_nclong::as_nclong( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
inline nclong NcValues_long::as_nclong( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
as_long_implement(float)
|
||||
as_long_implement(double)
|
||||
|
||||
inline long NcValues_ncbyte::as_long( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
inline long NcValues_char::as_long( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
inline long NcValues_short::as_long( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
inline long NcValues_int::as_long( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
inline long NcValues_nclong::as_long( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
inline long NcValues_long::as_long( long n ) const
|
||||
{
|
||||
return the_values[n];
|
||||
}
|
||||
|
||||
as_float_implement(ncbyte)
|
||||
as_float_implement(char)
|
||||
as_float_implement(short)
|
||||
as_float_implement(int)
|
||||
as_float_implement(nclong)
|
||||
as_float_implement(long)
|
||||
as_float_implement(float)
|
||||
as_float_implement(double)
|
||||
|
||||
as_double_implement(ncbyte)
|
||||
as_double_implement(char)
|
||||
as_double_implement(short)
|
||||
as_double_implement(int)
|
||||
as_double_implement(nclong)
|
||||
as_double_implement(long)
|
||||
as_double_implement(float)
|
||||
as_double_implement(double)
|
||||
|
||||
as_string_implement(short)
|
||||
as_string_implement(int)
|
||||
as_string_implement(nclong)
|
||||
as_string_implement(long)
|
||||
as_string_implement(float)
|
||||
as_string_implement(double)
|
||||
|
||||
inline char* NcValues_ncbyte::as_string( long n ) const
|
||||
{
|
||||
char* s = new char[the_number + 1];
|
||||
s[the_number] = '\0';
|
||||
strncpy(s, (const char*)the_values + n, (int)the_number);
|
||||
return s;
|
||||
}
|
||||
|
||||
inline char* NcValues_char::as_string( long n ) const
|
||||
{
|
||||
char* s = new char[the_number + 1];
|
||||
s[the_number] = '\0';
|
||||
strncpy(s, (const char*)the_values + n, (int)the_number);
|
||||
return s;
|
||||
}
|
||||
|
||||
std::ostream& NcValues_short::print(std::ostream& os) const
|
||||
{
|
||||
for(int i = 0; i < the_number - 1; i++)
|
||||
os << the_values[i] << ", ";
|
||||
if (the_number > 0)
|
||||
os << the_values[the_number-1] ;
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& NcValues_int::print(std::ostream& os) const
|
||||
{
|
||||
for(int i = 0; i < the_number - 1; i++)
|
||||
os << the_values[i] << ", ";
|
||||
if (the_number > 0)
|
||||
os << the_values[the_number-1] ;
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& NcValues_nclong::print(std::ostream& os) const
|
||||
{
|
||||
for(int i = 0; i < the_number - 1; i++)
|
||||
os << the_values[i] << ", ";
|
||||
if (the_number > 0)
|
||||
os << the_values[the_number-1] ;
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& NcValues_long::print(std::ostream& os) const
|
||||
{
|
||||
for(int i = 0; i < the_number - 1; i++)
|
||||
os << the_values[i] << ", ";
|
||||
if (the_number > 0)
|
||||
os << the_values[the_number-1] ;
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& NcValues_ncbyte::print(std::ostream& os) const
|
||||
{
|
||||
for(int i = 0; i < the_number - 1; i++)
|
||||
os << the_values[i] << ", ";
|
||||
if (the_number > 0)
|
||||
os << the_values[the_number-1] ;
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& NcValues_char::print(std::ostream& os) const
|
||||
{
|
||||
os << '"';
|
||||
long len = the_number;
|
||||
while (the_values[--len] == '\0') // don't output trailing null bytes
|
||||
;
|
||||
for(int i = 0; i <= len; i++)
|
||||
os << the_values[i] ;
|
||||
os << '"';
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& NcValues_float::print(std::ostream& os) const
|
||||
{
|
||||
std::streamsize save=os.precision();
|
||||
os.precision(7);
|
||||
for(int i = 0; i < the_number - 1; i++)
|
||||
os << the_values[i] << ", ";
|
||||
if (the_number > 0)
|
||||
os << the_values[the_number-1] ;
|
||||
os.precision(save);
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& NcValues_double::print(std::ostream& os) const
|
||||
{
|
||||
std::streamsize save=os.precision();
|
||||
os.precision(15);
|
||||
for(int i = 0; i < the_number - 1; i++)
|
||||
os << the_values[i] << ", ";
|
||||
if (the_number > 0)
|
||||
os << the_values[the_number-1];
|
||||
os.precision(save);
|
||||
return os;
|
||||
}
|
279
src/lib/ncvalues.h
Normal file
279
src/lib/ncvalues.h
Normal file
@ -0,0 +1,279 @@
|
||||
/*********************************************************************
|
||||
* Copyright 1992, University Corporation for Atmospheric Research
|
||||
* See netcdf/README file for copying and redistribution conditions.
|
||||
*
|
||||
* Purpose: interface for classes of typed arrays for netCDF
|
||||
*
|
||||
* $Header: /upc/share/CVS/netcdf-3/cxx/ncvalues.h,v 1.7 2006/07/26 21:12:06 russ Exp $
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef Ncvalues_def
|
||||
#define Ncvalues_def
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <limits.h>
|
||||
#include "netcdf.h"
|
||||
|
||||
// Documentation warned this might change and now it has, for
|
||||
// consistency with C interface
|
||||
typedef signed char ncbyte;
|
||||
|
||||
#define NC_UNSPECIFIED ((nc_type)0)
|
||||
|
||||
// C++ interface dates from before netcdf-3, still uses some netcdf-2 names
|
||||
#ifdef NO_NETCDF_2
|
||||
#define NC_LONG NC_INT
|
||||
#define FILL_LONG NC_FILL_INT
|
||||
typedef int nclong;
|
||||
#define NC_FATAL 1
|
||||
#define NC_VERBOSE 2
|
||||
#endif
|
||||
|
||||
enum NcType
|
||||
{
|
||||
ncNoType = NC_UNSPECIFIED,
|
||||
ncByte = NC_BYTE,
|
||||
ncChar = NC_CHAR,
|
||||
ncShort = NC_SHORT,
|
||||
ncInt = NC_INT,
|
||||
ncLong = NC_LONG, // deprecated, someday want to use for 64-bit ints
|
||||
ncFloat = NC_FLOAT,
|
||||
ncDouble = NC_DOUBLE
|
||||
};
|
||||
|
||||
#define ncBad_ncbyte ncBad_byte
|
||||
static const ncbyte ncBad_byte = NC_FILL_BYTE;
|
||||
static const char ncBad_char = NC_FILL_CHAR;
|
||||
static const short ncBad_short = NC_FILL_SHORT;
|
||||
static const nclong ncBad_nclong = FILL_LONG; // deprecated
|
||||
static const int ncBad_int = NC_FILL_INT;
|
||||
static const long ncBad_long = FILL_LONG; // deprecated
|
||||
static const float ncBad_float = NC_FILL_FLOAT;
|
||||
static const double ncBad_double = NC_FILL_DOUBLE;
|
||||
|
||||
// macros to glue tokens together to form new names (used to be in generic.h)
|
||||
#define name2(a,b) a ## b
|
||||
#define declare(clas,t) name2(clas,declare)(t)
|
||||
#define implement(clas,t) name2(clas,implement)(t)
|
||||
// This is the same as the name2 macro, but we need to define our own
|
||||
// version since rescanning something generated with the name2 macro
|
||||
// won't necessarily cause name2 to be expanded again.
|
||||
#define makename2(z, y) makename2_x(z, y)
|
||||
#define makename2_x(z, y) z##y
|
||||
|
||||
#define NcVal(TYPE) makename2(NcValues_,TYPE)
|
||||
|
||||
#define NcValuesdeclare(TYPE) \
|
||||
class NcVal(TYPE) : public NcValues \
|
||||
{ \
|
||||
public: \
|
||||
NcVal(TYPE)( void ); \
|
||||
NcVal(TYPE)(long num); \
|
||||
NcVal(TYPE)(long num, const TYPE* vals); \
|
||||
NcVal(TYPE)(const NcVal(TYPE)&); \
|
||||
virtual NcVal(TYPE)& operator=(const NcVal(TYPE)&); \
|
||||
virtual ~NcVal(TYPE)( void ); \
|
||||
virtual void* base( void ) const; \
|
||||
virtual int bytes_for_one( void ) const; \
|
||||
virtual ncbyte as_ncbyte( long n ) const; \
|
||||
virtual char as_char( long n ) const; \
|
||||
virtual short as_short( long n ) const; \
|
||||
virtual int as_int( long n ) const; \
|
||||
virtual int as_nclong( long n ) const; \
|
||||
virtual long as_long( long n ) const; \
|
||||
virtual float as_float( long n ) const; \
|
||||
virtual double as_double( long n ) const; \
|
||||
virtual char* as_string( long n ) const; \
|
||||
virtual int invalid( void ) const; \
|
||||
private: \
|
||||
TYPE* the_values; \
|
||||
std::ostream& print(std::ostream&) const; \
|
||||
};
|
||||
|
||||
#define NcTypeEnum(TYPE) makename2(_nc__,TYPE)
|
||||
#define _nc__ncbyte ncByte
|
||||
#define _nc__char ncChar
|
||||
#define _nc__short ncShort
|
||||
#define _nc__int ncInt
|
||||
#define _nc__nclong ncLong
|
||||
#define _nc__long ncLong
|
||||
#define _nc__float ncFloat
|
||||
#define _nc__double ncDouble
|
||||
#define NcValuesimplement(TYPE) \
|
||||
NcVal(TYPE)::NcVal(TYPE)( void ) \
|
||||
: NcValues(NcTypeEnum(TYPE), 0), the_values(0) \
|
||||
{} \
|
||||
\
|
||||
NcVal(TYPE)::NcVal(TYPE)(long num, const TYPE* vals) \
|
||||
: NcValues(NcTypeEnum(TYPE), num) \
|
||||
{ \
|
||||
the_values = new TYPE[num]; \
|
||||
for(int i = 0; i < num; i++) \
|
||||
the_values[i] = vals[i]; \
|
||||
} \
|
||||
\
|
||||
NcVal(TYPE)::NcVal(TYPE)(long num) \
|
||||
: NcValues(NcTypeEnum(TYPE), num), the_values(new TYPE[num]) \
|
||||
{} \
|
||||
\
|
||||
NcVal(TYPE)::NcVal(TYPE)(const NcVal(TYPE)& v) : \
|
||||
NcValues(v) \
|
||||
{ \
|
||||
delete[] the_values; \
|
||||
the_values = new TYPE[v.the_number]; \
|
||||
for(int i = 0; i < v.the_number; i++) \
|
||||
the_values[i] = v.the_values[i]; \
|
||||
} \
|
||||
\
|
||||
NcVal(TYPE)& NcVal(TYPE)::operator=(const NcVal(TYPE)& v) \
|
||||
{ \
|
||||
if ( &v != this) { \
|
||||
NcValues::operator=(v); \
|
||||
delete[] the_values; \
|
||||
the_values = new TYPE[v.the_number]; \
|
||||
for(int i = 0; i < v.the_number; i++) \
|
||||
the_values[i] = v.the_values[i]; \
|
||||
} \
|
||||
return *this; \
|
||||
} \
|
||||
\
|
||||
void* NcVal(TYPE)::base( void ) const \
|
||||
{ \
|
||||
return the_values; \
|
||||
} \
|
||||
\
|
||||
NcVal(TYPE)::~NcVal(TYPE)( void ) \
|
||||
{ \
|
||||
delete[] the_values; \
|
||||
} \
|
||||
\
|
||||
int NcVal(TYPE)::invalid( void ) const \
|
||||
{ \
|
||||
for(int i=0;i<the_number;i++) \
|
||||
if (the_values[i] == makename2(ncBad_,TYPE)) return 1; \
|
||||
return 0; \
|
||||
} \
|
||||
|
||||
|
||||
#define Ncbytes_for_one_implement(TYPE) \
|
||||
int NcVal(TYPE)::bytes_for_one( void ) const \
|
||||
{ \
|
||||
return sizeof(TYPE); \
|
||||
}
|
||||
|
||||
#define as_ncbyte_implement(TYPE) \
|
||||
ncbyte NcVal(TYPE)::as_ncbyte( long n ) const \
|
||||
{ \
|
||||
if (the_values[n] < 0 || the_values[n] > UCHAR_MAX) \
|
||||
return ncBad_byte; \
|
||||
return (ncbyte) the_values[n]; \
|
||||
}
|
||||
|
||||
#define as_char_implement(TYPE) \
|
||||
char NcVal(TYPE)::as_char( long n ) const \
|
||||
{ \
|
||||
if (the_values[n] < CHAR_MIN || the_values[n] > CHAR_MAX) \
|
||||
return ncBad_char; \
|
||||
return (char) the_values[n]; \
|
||||
}
|
||||
|
||||
#define as_short_implement(TYPE) \
|
||||
short NcVal(TYPE)::as_short( long n ) const \
|
||||
{ \
|
||||
if (the_values[n] < SHRT_MIN || the_values[n] > SHRT_MAX) \
|
||||
return ncBad_short; \
|
||||
return (short) the_values[n]; \
|
||||
}
|
||||
|
||||
#define NCINT_MIN INT_MIN
|
||||
#define NCINT_MAX INT_MAX
|
||||
#define as_int_implement(TYPE) \
|
||||
int NcVal(TYPE)::as_int( long n ) const \
|
||||
{ \
|
||||
if (the_values[n] < NCINT_MIN || the_values[n] > NCINT_MAX) \
|
||||
return ncBad_int; \
|
||||
return (int) the_values[n]; \
|
||||
}
|
||||
|
||||
#define NCLONG_MIN INT_MIN
|
||||
#define NCLONG_MAX INT_MAX
|
||||
#define as_nclong_implement(TYPE) \
|
||||
nclong NcVal(TYPE)::as_nclong( long n ) const \
|
||||
{ \
|
||||
if (the_values[n] < NCLONG_MIN || the_values[n] > NCLONG_MAX) \
|
||||
return ncBad_nclong; \
|
||||
return (nclong) the_values[n]; \
|
||||
}
|
||||
|
||||
#define as_long_implement(TYPE) \
|
||||
long NcVal(TYPE)::as_long( long n ) const \
|
||||
{ \
|
||||
if (the_values[n] < LONG_MIN || the_values[n] > LONG_MAX) \
|
||||
return ncBad_long; \
|
||||
return (long) the_values[n]; \
|
||||
}
|
||||
|
||||
#define as_float_implement(TYPE) \
|
||||
inline float NcVal(TYPE)::as_float( long n ) const \
|
||||
{ \
|
||||
return (float) the_values[n]; \
|
||||
}
|
||||
|
||||
#define as_double_implement(TYPE) \
|
||||
inline double NcVal(TYPE)::as_double( long n ) const \
|
||||
{ \
|
||||
return (double) the_values[n]; \
|
||||
}
|
||||
|
||||
#define as_string_implement(TYPE) \
|
||||
char* NcVal(TYPE)::as_string( long n ) const \
|
||||
{ \
|
||||
char* s = new char[32]; \
|
||||
std::ostringstream ostr; \
|
||||
ostr << the_values[n]; \
|
||||
ostr.str().copy(s, std::string::npos); \
|
||||
s[ostr.str().length()] = 0; \
|
||||
return s; \
|
||||
}
|
||||
|
||||
class NcValues // ABC for value blocks
|
||||
{
|
||||
public:
|
||||
NcValues( void );
|
||||
NcValues(NcType, long);
|
||||
virtual ~NcValues( void );
|
||||
virtual long num( void );
|
||||
virtual std::ostream& print(std::ostream&) const = 0;
|
||||
virtual void* base( void ) const = 0;
|
||||
virtual int bytes_for_one( void ) const = 0;
|
||||
|
||||
// The following member functions provide conversions from the value
|
||||
// type to a desired basic type. If the value is out of range, the
|
||||
// default "fill-value" for the appropriate type is returned.
|
||||
virtual ncbyte as_ncbyte( long n ) const = 0; // nth value as a byte
|
||||
virtual char as_char( long n ) const = 0; // nth value as char
|
||||
virtual short as_short( long n ) const = 0; // nth value as short
|
||||
virtual int as_int( long n ) const = 0; // nth value as int
|
||||
virtual int as_nclong( long n ) const = 0; // nth value as nclong
|
||||
virtual long as_long( long n ) const = 0; // nth value as long
|
||||
virtual float as_float( long n ) const = 0; // nth value as floating-point
|
||||
virtual double as_double( long n ) const = 0; // nth value as double
|
||||
virtual char* as_string( long n ) const = 0; // value as string
|
||||
|
||||
protected:
|
||||
NcType the_type;
|
||||
long the_number;
|
||||
friend std::ostream& operator<< (std::ostream&, const NcValues&);
|
||||
};
|
||||
|
||||
declare(NcValues,ncbyte)
|
||||
declare(NcValues,char)
|
||||
declare(NcValues,short)
|
||||
declare(NcValues,int)
|
||||
declare(NcValues,nclong)
|
||||
declare(NcValues,long)
|
||||
declare(NcValues,float)
|
||||
declare(NcValues,double)
|
||||
|
||||
#endif
|
1660
src/lib/netcdf.cpp
Normal file
1660
src/lib/netcdf.cpp
Normal file
File diff suppressed because it is too large
Load Diff
92
src/lib/netcdf_config.h
Normal file
92
src/lib/netcdf_config.h
Normal file
@ -0,0 +1,92 @@
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* if true, run extra tests which may not work yet */
|
||||
#undef EXTRA_TESTS
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `nccreate' function. */
|
||||
#undef HAVE_NCCREATE
|
||||
|
||||
/* Define to 1 if you have the `nc_def_opaque' function. */
|
||||
#undef HAVE_NC_DEF_OPAQUE
|
||||
|
||||
/* Define to 1 if you have the `nc_set_log_level' function. */
|
||||
#undef HAVE_NC_SET_LOG_LEVEL
|
||||
|
||||
/* Define to 1 if you have the `nc_use_parallel_enabled' function. */
|
||||
#undef HAVE_NC_USE_PARALLEL_ENABLED
|
||||
|
||||
/* Define to 1 if you have the <netcdf.h> header file. */
|
||||
#undef HAVE_NETCDF_H
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* do large file tests */
|
||||
#undef LARGE_FILE_TESTS
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#undef LT_OBJDIR
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Place to put very large netCDF test files. */
|
||||
#undef TEMP_LARGE
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#undef _FILE_OFFSET_BITS
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
#undef _LARGE_FILES
|
469
src/lib/netcdfcpp.h
Normal file
469
src/lib/netcdfcpp.h
Normal file
@ -0,0 +1,469 @@
|
||||
/*********************************************************************
|
||||
* Copyright 1992, University Corporation for Atmospheric Research
|
||||
* See netcdf/README file for copying and redistribution conditions.
|
||||
*
|
||||
* Purpose: C++ class interface for netCDF
|
||||
*
|
||||
* $Header: /upc/share/CVS/netcdf-3/cxx/netcdfcpp.h,v 1.15 2009/03/10 15:20:54 russ Exp $
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef NETCDF_HH
|
||||
#define NETCDF_HH
|
||||
|
||||
#include "ncvalues.h" // arrays that know their element type
|
||||
|
||||
typedef const char* NcToken; // names for netCDF objects
|
||||
typedef unsigned int NcBool; // many members return 0 on failure
|
||||
|
||||
class NcDim; // dimensions
|
||||
class NcVar; // variables
|
||||
class NcAtt; // attributes
|
||||
|
||||
/*
|
||||
* ***********************************************************************
|
||||
* A netCDF file.
|
||||
* ***********************************************************************
|
||||
*/
|
||||
class NcFile
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~NcFile( void );
|
||||
|
||||
enum FileMode {
|
||||
ReadOnly, // file exists, open read-only
|
||||
Write, // file exists, open for writing
|
||||
Replace, // create new file, even if already exists
|
||||
New // create new file, fail if already exists
|
||||
};
|
||||
|
||||
enum FileFormat {
|
||||
Classic, // netCDF classic format (i.e. version 1 format)
|
||||
Offset64Bits, // netCDF 64-bit offset format
|
||||
Netcdf4, // netCDF-4 using HDF5 format
|
||||
Netcdf4Classic, // netCDF-4 using HDF5 format using only netCDF-3 calls
|
||||
BadFormat
|
||||
};
|
||||
|
||||
NcFile( const char * path, FileMode = ReadOnly ,
|
||||
size_t *bufrsizeptr = NULL, // optional tuning parameters
|
||||
size_t initialsize = 0,
|
||||
FileFormat = Classic );
|
||||
|
||||
NcBool is_valid( void ) const; // opened OK in ctr, still valid
|
||||
|
||||
int num_dims( void ) const; // number of dimensions
|
||||
int num_vars( void ) const; // number of variables
|
||||
int num_atts( void ) const; // number of (global) attributes
|
||||
|
||||
NcDim* get_dim( NcToken ) const; // dimension by name
|
||||
NcVar* get_var( NcToken ) const; // variable by name
|
||||
NcAtt* get_att( NcToken ) const; // global attribute by name
|
||||
|
||||
NcDim* get_dim( int ) const; // n-th dimension
|
||||
NcVar* get_var( int ) const; // n-th variable
|
||||
NcAtt* get_att( int ) const; // n-th global attribute
|
||||
NcDim* rec_dim( void ) const; // unlimited dimension, if any
|
||||
|
||||
// Add new dimensions, variables, global attributes.
|
||||
// These put the file in "define" mode, so could be expensive.
|
||||
virtual NcDim* add_dim( NcToken dimname, long dimsize );
|
||||
virtual NcDim* add_dim( NcToken dimname ); // unlimited
|
||||
|
||||
virtual NcVar* add_var( NcToken varname, NcType type, // scalar
|
||||
const NcDim* dim0=0, // 1-dim
|
||||
const NcDim* dim1=0, // 2-dim
|
||||
const NcDim* dim2=0, // 3-dim
|
||||
const NcDim* dim3=0, // 4-dim
|
||||
const NcDim* dim4=0 ); // 5-dim
|
||||
virtual NcVar* add_var( NcToken varname, NcType type, // n-dim
|
||||
int ndims, const NcDim** dims );
|
||||
|
||||
NcBool add_att( NcToken attname, char ); // scalar attributes
|
||||
NcBool add_att( NcToken attname, ncbyte );
|
||||
NcBool add_att( NcToken attname, short );
|
||||
NcBool add_att( NcToken attname, long );
|
||||
NcBool add_att( NcToken attname, int );
|
||||
NcBool add_att( NcToken attname, float );
|
||||
NcBool add_att( NcToken attname, double );
|
||||
NcBool add_att( NcToken attname, const char*); // string attribute
|
||||
NcBool add_att( NcToken attname, int, const char* ); // vector attributes
|
||||
NcBool add_att( NcToken attname, int, const ncbyte* );
|
||||
NcBool add_att( NcToken attname, int, const short* );
|
||||
NcBool add_att( NcToken attname, int, const long* );
|
||||
NcBool add_att( NcToken attname, int, const int* );
|
||||
NcBool add_att( NcToken attname, int, const float* );
|
||||
NcBool add_att( NcToken attname, int, const double* );
|
||||
|
||||
enum FillMode {
|
||||
Fill = NC_FILL, // prefill (default)
|
||||
NoFill = NC_NOFILL, // don't prefill
|
||||
Bad
|
||||
};
|
||||
|
||||
NcBool set_fill( FillMode = Fill ); // set fill-mode
|
||||
FillMode get_fill( void ) const; // get fill-mode
|
||||
FileFormat get_format( void ) const; // get format version
|
||||
|
||||
NcBool sync( void ); // synchronize to disk
|
||||
NcBool close( void ); // to close earlier than dtr
|
||||
NcBool abort( void ); // back out of bad defines
|
||||
|
||||
// Needed by other Nc classes, but users will not need them
|
||||
NcBool define_mode( void ); // leaves in define mode, if possible
|
||||
NcBool data_mode( void ); // leaves in data mode, if possible
|
||||
int id( void ) const; // id used by C interface
|
||||
|
||||
protected:
|
||||
int the_id;
|
||||
int in_define_mode;
|
||||
FillMode the_fill_mode;
|
||||
NcDim** dimensions;
|
||||
NcVar** variables;
|
||||
NcVar* globalv; // "variable" for global attributes
|
||||
};
|
||||
|
||||
/*
|
||||
* For backward compatibility. We used to derive NcOldFile and NcNewFile
|
||||
* from NcFile, but that was over-zealous inheritance.
|
||||
*/
|
||||
#define NcOldFile NcFile
|
||||
#define NcNewFile NcFile
|
||||
#define Clobber Replace
|
||||
#define NoClobber New
|
||||
|
||||
/*
|
||||
* **********************************************************************
|
||||
* A netCDF dimension, with a name and a size. These are only created
|
||||
* by NcFile member functions, because they cannot exist independently
|
||||
* of an open netCDF file.
|
||||
* **********************************************************************
|
||||
*/
|
||||
class NcDim
|
||||
{
|
||||
public:
|
||||
NcToken name( void ) const;
|
||||
long size( void ) const;
|
||||
NcBool is_valid( void ) const;
|
||||
NcBool is_unlimited( void ) const;
|
||||
NcBool rename( NcToken newname );
|
||||
int id( void ) const;
|
||||
NcBool sync( void );
|
||||
|
||||
private:
|
||||
NcFile *the_file; // not const because of rename
|
||||
int the_id;
|
||||
char *the_name;
|
||||
|
||||
NcDim(NcFile*, int num); // existing dimension
|
||||
NcDim(NcFile*, NcToken name, long sz); // defines a new dim
|
||||
virtual ~NcDim( void );
|
||||
|
||||
// to construct dimensions, since constructor is private
|
||||
friend class NcFile;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* **********************************************************************
|
||||
* Abstract base class for a netCDF variable or attribute, both of which
|
||||
* have a name, a type, and associated values. These only exist as
|
||||
* components of an open netCDF file.
|
||||
* **********************************************************************
|
||||
*/
|
||||
class NcTypedComponent
|
||||
{
|
||||
public:
|
||||
virtual ~NcTypedComponent( void ) {}
|
||||
virtual NcToken name( void ) const = 0;
|
||||
virtual NcType type( void ) const = 0;
|
||||
virtual NcBool is_valid( void ) const = 0;
|
||||
virtual long num_vals( void ) const = 0;
|
||||
virtual NcBool rename( NcToken newname ) = 0;
|
||||
virtual NcValues* values( void ) const = 0; // block of all values
|
||||
|
||||
// The following member functions provide conversions from the value
|
||||
// type to a desired basic type. If the value is out of range,
|
||||
// the default "fill-value" for the appropriate type is returned.
|
||||
|
||||
virtual ncbyte as_ncbyte( long n ) const; // nth value as an unsgnd char
|
||||
virtual char as_char( long n ) const; // nth value as char
|
||||
virtual short as_short( long n ) const; // nth value as short
|
||||
virtual int as_int( long n ) const; // nth value as int
|
||||
virtual int as_nclong( long n ) const; // nth value as nclong (deprecated)
|
||||
virtual long as_long( long n ) const; // nth value as long
|
||||
virtual float as_float( long n ) const; // nth value as floating-point
|
||||
virtual double as_double( long n ) const; // nth value as double
|
||||
virtual char* as_string( long n ) const; // nth value as string
|
||||
|
||||
protected:
|
||||
NcFile *the_file;
|
||||
NcTypedComponent( NcFile* );
|
||||
virtual NcValues* get_space( long numVals = 0 ) const; // to hold values
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* **********************************************************************
|
||||
* netCDF variables. In addition to a name and a type, these also have
|
||||
* a shape, given by a list of dimensions
|
||||
* **********************************************************************
|
||||
*/
|
||||
class NcVar : public NcTypedComponent
|
||||
{
|
||||
public:
|
||||
virtual ~NcVar( void );
|
||||
NcToken name( void ) const;
|
||||
NcType type( void ) const;
|
||||
NcBool is_valid( void ) const;
|
||||
int num_dims( void ) const; // dimensionality of variable
|
||||
NcDim* get_dim( int ) const; // n-th dimension
|
||||
long* edges( void ) const; // dimension sizes
|
||||
int num_atts( void ) const; // number of attributes
|
||||
NcAtt* get_att( NcToken ) const; // attribute by name
|
||||
NcAtt* get_att( int ) const; // n-th attribute
|
||||
long num_vals( void ) const; // product of dimension sizes
|
||||
NcValues* values( void ) const; // all values
|
||||
|
||||
// Put scalar or 1, ..., 5 dimensional arrays by providing enough
|
||||
// arguments. Arguments are edge lengths, and their number must not
|
||||
// exceed variable's dimensionality. Start corner is [0,0,..., 0] by
|
||||
// default, but may be reset using the set_cur() member. FALSE is
|
||||
// returned if type of values does not match type for variable.
|
||||
NcBool put( const ncbyte* vals,
|
||||
long c0=0, long c1=0, long c2=0, long c3=0, long c4=0 );
|
||||
NcBool put( const char* vals,
|
||||
long c0=0, long c1=0, long c2=0, long c3=0, long c4=0 );
|
||||
NcBool put( const short* vals,
|
||||
long c0=0, long c1=0, long c2=0, long c3=0, long c4=0 );
|
||||
NcBool put( const int* vals,
|
||||
long c0=0, long c1=0, long c2=0, long c3=0, long c4=0 );
|
||||
NcBool put( const long* vals,
|
||||
long c0=0, long c1=0, long c2=0, long c3=0, long c4=0 );
|
||||
NcBool put( const float* vals,
|
||||
long c0=0, long c1=0, long c2=0, long c3=0, long c4=0 );
|
||||
NcBool put( const double* vals,
|
||||
long c0=0, long c1=0, long c2=0, long c3=0, long c4=0 );
|
||||
|
||||
// Put n-dimensional arrays, starting at [0, 0, ..., 0] by default,
|
||||
// may be reset with set_cur().
|
||||
NcBool put( const ncbyte* vals, const long* counts );
|
||||
NcBool put( const char* vals, const long* counts );
|
||||
NcBool put( const short* vals, const long* counts );
|
||||
NcBool put( const int* vals, const long* counts );
|
||||
NcBool put( const long* vals, const long* counts );
|
||||
NcBool put( const float* vals, const long* counts );
|
||||
NcBool put( const double* vals, const long* counts );
|
||||
|
||||
// Get scalar or 1, ..., 5 dimensional arrays by providing enough
|
||||
// arguments. Arguments are edge lengths, and their number must not
|
||||
// exceed variable's dimensionality. Start corner is [0,0,..., 0] by
|
||||
// default, but may be reset using the set_cur() member.
|
||||
NcBool get( ncbyte* vals, long c0=0, long c1=0,
|
||||
long c2=0, long c3=0, long c4=0 ) const;
|
||||
NcBool get( char* vals, long c0=0, long c1=0,
|
||||
long c2=0, long c3=0, long c4=0 ) const;
|
||||
NcBool get( short* vals, long c0=0, long c1=0,
|
||||
long c2=0, long c3=0, long c4=0 ) const;
|
||||
NcBool get( int* vals, long c0=0, long c1=0,
|
||||
long c2=0, long c3=0, long c4=0 ) const;
|
||||
NcBool get( long* vals, long c0=0, long c1=0,
|
||||
long c2=0, long c3=0, long c4=0 ) const;
|
||||
NcBool get( float* vals, long c0=0, long c1=0,
|
||||
long c2=0, long c3=0, long c4=0 ) const;
|
||||
NcBool get( double* vals, long c0=0, long c1=0,
|
||||
long c2=0, long c3=0, long c4=0 ) const;
|
||||
|
||||
// Get n-dimensional arrays, starting at [0, 0, ..., 0] by default,
|
||||
// may be reset with set_cur().
|
||||
NcBool get( ncbyte* vals, const long* counts ) const;
|
||||
NcBool get( char* vals, const long* counts ) const;
|
||||
NcBool get( short* vals, const long* counts ) const;
|
||||
NcBool get( int* vals, const long* counts ) const;
|
||||
NcBool get( long* vals, const long* counts ) const;
|
||||
NcBool get( float* vals, const long* counts ) const;
|
||||
NcBool get( double* vals, const long* counts ) const;
|
||||
|
||||
NcBool set_cur(long c0=-1, long c1=-1, long c2=-1,
|
||||
long c3=-1, long c4=-1);
|
||||
NcBool set_cur(long* cur);
|
||||
|
||||
// these put file in define mode, so could be expensive
|
||||
NcBool add_att( NcToken, char ); // add scalar attributes
|
||||
NcBool add_att( NcToken, ncbyte );
|
||||
NcBool add_att( NcToken, short );
|
||||
NcBool add_att( NcToken, int );
|
||||
NcBool add_att( NcToken, long );
|
||||
NcBool add_att( NcToken, float );
|
||||
NcBool add_att( NcToken, double );
|
||||
NcBool add_att( NcToken, const char* ); // string attribute
|
||||
NcBool add_att( NcToken, int, const char* ); // vector attributes
|
||||
NcBool add_att( NcToken, int, const ncbyte* );
|
||||
NcBool add_att( NcToken, int, const short* );
|
||||
NcBool add_att( NcToken, int, const int* );
|
||||
NcBool add_att( NcToken, int, const long* );
|
||||
NcBool add_att( NcToken, int, const float* );
|
||||
NcBool add_att( NcToken, int, const double* );
|
||||
|
||||
NcBool rename( NcToken newname );
|
||||
|
||||
long rec_size ( void ); // number of values per record
|
||||
long rec_size ( NcDim* ); // number of values per dimension slice
|
||||
|
||||
// Though following are intended for record variables, they also work
|
||||
// for other variables, using first dimension as record dimension.
|
||||
|
||||
// Get a record's worth of data
|
||||
NcValues *get_rec(void); // get current record
|
||||
NcValues *get_rec(long rec); // get specified record
|
||||
NcValues *get_rec(NcDim* d); // get current dimension slice
|
||||
NcValues *get_rec(NcDim* d, long slice); // get specified dimension slice
|
||||
|
||||
// Put a record's worth of data in current record
|
||||
NcBool put_rec( const ncbyte* vals );
|
||||
NcBool put_rec( const char* vals );
|
||||
NcBool put_rec( const short* vals );
|
||||
NcBool put_rec( const int* vals );
|
||||
NcBool put_rec( const long* vals );
|
||||
NcBool put_rec( const float* vals );
|
||||
NcBool put_rec( const double* vals );
|
||||
|
||||
// Put a dimension slice worth of data in current dimension slice
|
||||
NcBool put_rec( NcDim* d, const ncbyte* vals );
|
||||
NcBool put_rec( NcDim* d, const char* vals );
|
||||
NcBool put_rec( NcDim* d, const short* vals );
|
||||
NcBool put_rec( NcDim* d, const int* vals );
|
||||
NcBool put_rec( NcDim* d, const long* vals );
|
||||
NcBool put_rec( NcDim* d, const float* vals );
|
||||
NcBool put_rec( NcDim* d, const double* vals );
|
||||
|
||||
// Put a record's worth of data in specified record
|
||||
NcBool put_rec( const ncbyte* vals, long rec );
|
||||
NcBool put_rec( const char* vals, long rec );
|
||||
NcBool put_rec( const short* vals, long rec );
|
||||
NcBool put_rec( const int* vals, long rec );
|
||||
NcBool put_rec( const long* vals, long rec );
|
||||
NcBool put_rec( const float* vals, long rec );
|
||||
NcBool put_rec( const double* vals, long rec );
|
||||
|
||||
// Put a dimension slice worth of data in specified dimension slice
|
||||
NcBool put_rec( NcDim* d, const ncbyte* vals, long slice );
|
||||
NcBool put_rec( NcDim* d, const char* vals, long slice );
|
||||
NcBool put_rec( NcDim* d, const short* vals, long slice );
|
||||
NcBool put_rec( NcDim* d, const int* vals, long slice );
|
||||
NcBool put_rec( NcDim* d, const long* vals, long slice );
|
||||
NcBool put_rec( NcDim* d, const float* vals, long slice );
|
||||
NcBool put_rec( NcDim* d, const double* vals, long slice );
|
||||
|
||||
// Get first record index corresponding to specified key value(s)
|
||||
long get_index( const ncbyte* vals );
|
||||
long get_index( const char* vals );
|
||||
long get_index( const short* vals );
|
||||
long get_index( const int* vals );
|
||||
long get_index( const long* vals );
|
||||
long get_index( const float* vals );
|
||||
long get_index( const double* vals );
|
||||
|
||||
// Get first index of specified dimension corresponding to key values
|
||||
long get_index( NcDim* d, const ncbyte* vals );
|
||||
long get_index( NcDim* d, const char* vals );
|
||||
long get_index( NcDim* d, const short* vals );
|
||||
long get_index( NcDim* d, const int* vals );
|
||||
long get_index( NcDim* d, const long* vals );
|
||||
long get_index( NcDim* d, const float* vals );
|
||||
long get_index( NcDim* d, const double* vals );
|
||||
|
||||
// Set current record
|
||||
void set_rec ( long rec );
|
||||
// Set current dimension slice
|
||||
void set_rec ( NcDim* d, long slice );
|
||||
|
||||
int id( void ) const; // rarely needed, C interface id
|
||||
NcBool sync( void );
|
||||
|
||||
private:
|
||||
int dim_to_index(NcDim* rdim);
|
||||
int the_id;
|
||||
long* the_cur;
|
||||
char* the_name;
|
||||
long* cur_rec;
|
||||
|
||||
// private constructors because only an NcFile creates these
|
||||
NcVar( void );
|
||||
NcVar(NcFile*, int);
|
||||
|
||||
int attnum( NcToken attname ) const;
|
||||
NcToken attname( int attnum ) const;
|
||||
void init_cur( void );
|
||||
|
||||
// to make variables, since constructor is private
|
||||
friend class NcFile;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* **********************************************************************
|
||||
* netCDF attributes. In addition to a name and a type, these are each
|
||||
* associated with a specific variable, or are global to the file.
|
||||
* **********************************************************************
|
||||
*/
|
||||
class NcAtt : public NcTypedComponent
|
||||
{
|
||||
public:
|
||||
virtual ~NcAtt( void );
|
||||
NcToken name( void ) const;
|
||||
NcType type( void ) const;
|
||||
NcBool is_valid( void ) const;
|
||||
long num_vals( void ) const;
|
||||
NcValues* values( void ) const;
|
||||
NcBool rename( NcToken newname );
|
||||
NcBool remove( void );
|
||||
|
||||
private:
|
||||
const NcVar* the_variable;
|
||||
char* the_name;
|
||||
// protected constructors because only NcVars and NcFiles create
|
||||
// attributes
|
||||
NcAtt( NcFile*, const NcVar*, NcToken);
|
||||
NcAtt( NcFile*, NcToken); // global attribute
|
||||
|
||||
// To make attributes, since constructor is private
|
||||
friend class NcFile;
|
||||
friend NcAtt* NcVar::get_att( NcToken ) const;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* **********************************************************************
|
||||
* To control error handling. Declaring an NcError object temporarily
|
||||
* changes the error-handling behavior until the object is destroyed, at
|
||||
* which time the previous error-handling behavior is restored.
|
||||
* **********************************************************************
|
||||
*/
|
||||
class NcError {
|
||||
public:
|
||||
enum Behavior {
|
||||
silent_nonfatal = 0,
|
||||
silent_fatal = 1,
|
||||
verbose_nonfatal = 2,
|
||||
verbose_fatal = 3
|
||||
};
|
||||
|
||||
// constructor saves previous error state, sets new state
|
||||
NcError( Behavior b = verbose_fatal );
|
||||
|
||||
// destructor restores previous error state
|
||||
virtual ~NcError( void );
|
||||
|
||||
int get_err( void ); // returns most recent error number
|
||||
const char* get_errmsg( void ) {return nc_strerror(get_err());}
|
||||
static int set_err( int err );
|
||||
|
||||
private:
|
||||
int the_old_state;
|
||||
int the_old_err;
|
||||
static int ncopts;
|
||||
static int ncerr;
|
||||
};
|
||||
|
||||
#endif /* NETCDF_HH */
|
Loading…
Reference in New Issue
Block a user