Hi,
On 30.07.2012, at 20:53, Dave Allured wrote:
> Define each "object" independently, except all objects have one
> dimension in common. There will be no formal "array of objects", but
> you can access them automatically in a program, via an array of
> variable names.
>
> This is a simplistic view of what I think you requested. Will this work?
>
> dimensions:
> d = 30 ;
> nx = 5 ;
> ny = 7 ;
> nz = 11 ;
> variables:
> float x(nx,d) ;
> float y(ny,d) ;
> float z(nz,d) ;
I was trying to avoid the creation of one dimension per variable. Apart from
that, I've done it just so, one variable per object, last dimension d is
constant, N varies.
Here is the code I used. It runs through without any exceptions but the error
checking is also non-existent (yet). However, it does not create any variables.
I'm going to add error-code checks today, but perhaps someone could tell me at
first glance what went wrong:
using std::stringstream;
// use mix of C++ and C - API, because the C++ API has no
// support for variable length arrays :(
NcFile *file = new NcFile( path.c_str(), NcFile::Replace );
if ( ! file->is_valid() )
{
std::cerr << "Error opening output file at " << path << std::endl;
exit(-1);
}
// Create dimensions
NcDim *dim = file->add_dim("dim", (int)
featureSpace->coordinate_system->size() );
NcDim *N = file->add_dim( "N", clusters.size() );
// Create attributes
file->add_att( "num_clusters", (int) clusters.size() );
file->add_att( "source", featureSpace->filename().c_str() );
file->add_att( "parameters", parameters.c_str() );
file->close();
// Open the file with the C API as well
int retval, ncid;
if ( ! nc_open( path.c_str(), NC_WRITE, &ncid ) )
{
cerr << "Error opening file " << path << "for writing" << endl;
exit( -1 );
}
// Add cluster variables
for ( size_t ci = 0; ci < clusters.size(); ci++ )
{
stringstream ss(stringstream::in | stringstream::out);
// Create variable
ss << "cluster_" << ci;
// Declare a variable length array type
nc_type type_id, base_type;
size_t type_size;
char type_name[255];
nc_def_vlen( ncid, "cluster_type", NC_DOUBLE, &type_id );
nc_inq_vlen( ncid, type_id, &type_name[0], &type_size, &base_type );
// Create a variable with the new VLEN type
int var_id, dim_id;
nc_inq_dimid( ncid, "dim", &dim_id );
int dims[1] = {dim_id};
nc_def_var( ncid, ss.str().c_str(), type_id, 1, dims, &var_id );
// write attributes mode, size, id
vector<T> mode = clusters[ci].mode;
ss.clear();
// mode
for (size_t i = 0; i < mode.size(); i++ )
{
ss << mode[i] << " ";
};
const char *mode_values[1] = {ss.str().c_str()};
nc_put_att( ncid, var_id, "mode", NC_STRING, 1, mode_values );
// size
int size_values[1] = {(int) clusters[ci].points.size()};
nc_put_att_int( ncid, var_id, "size", NC_INT, 1, size_values );
// id
const char *id_values[1] = {clusters[ci].id.c_str()};
nc_put_att( ncid, var_id, "id", NC_STRING, 1, id_values );
// allocate memory and write the cluster away
double
data[clusters[ci].points.size()][featureSpace->coordinate_system->size()];
for ( size_t pi = 0; pi < clusters[ci].points.size(); pi++ )
{
Point<T> *p = clusters[ci].points[pi];
for ( size_t di = 0; di <
featureSpace->coordinate_system->size(); di++ )
{
data[pi][di] = p->coordinate[di];
}
}
size_t start=0, len=clusters[ci].points.size();
nc_put_vara_double( ncid, var_id, &start, &len, &data[0][0] );
// var->put( &data[0][0] );
}
nc_close( ncid );
Thanks in advance!
J.