long* NcVar::edges( void ) const // edge lengths (dimension sizes) { long* evec = new long[num_dims()]; for(int i=0; i < num_dims(); i++) evec[i] = get_dim(i)->size(); return evec; }
// If no args, set cursor to all zeros. Else set initial elements of cursor // to args provided, rest to zeros. NcBool NcVar::set_cur(long c0, long c1, long c2, long c3, long c4) { long t[6]; t[0] = c0; t[1] = c1; t[2] = c2; t[3] = c3; t[4] = c4; t[5] = -1; for(int j = 0; j < 6; j++) { // find how many parameters were used int i; if (t[j] == -1) { if (num_dims() < j) return FALSE; // too many for variable's dimensionality for (i = 0; i < j; i++) { if (t[i] >= get_dim(i)->size() && ! get_dim(i)->is_unlimited()) return FALSE; // too big for dimension the_cur[i] = t[i]; } for(i = j; i < num_dims(); i++) the_cur[i] = 0; return TRUE; } } return TRUE; }
long NcVar::num_vals( void ) const { long prod = 1; for (int d = 0; d < num_dims(); d++) prod *= get_dim(d)->size(); return prod; }
NcBool NcVar::put( const char* vals, long edge0, long edge1, long edge2, long edge3, long edge4) { /* no need to check type() vs. TYPE, invoked C function will do that */ if (! the_file->data_mode()) return FALSE; size_t count[5]; count[0] = edge0; count[1] = edge1; count[2] = edge2; count[3] = edge3; count[4] = edge4; for (int i = 0; i < 5; i++) { if (count[i]) { if (num_dims() < i) return FALSE; } else break; } size_t start[5]; for (int j = 0; j < 5; j++) { start[j] = the_cur[j]; } return NcError::set_err( nc_put_vara_text (the_file->id(), the_id, start, count, vals) ) == NC_NOERR; }
NcBool NcFile::sync( void ) { if (!data_mode()) return 0; if (NcError::set_err( nc_sync(the_id) ) != NC_NOERR) return 0; int i; for (i = 0; i < num_dims(); i++) { if (dimensions[i]->is_valid()) { dimensions[i]->sync(); } else { // someone else added a new dimension dimensions[i] = new NcDim(this,i); } } for (i = 0; i < num_vars(); i++) { if (variables[i]->is_valid()) { variables[i]->sync(); } else { // someone else added a new variable variables[i] = new NcVar(this,i); } } return 1; }
NcBool NcVar::get( char* vals, long edge0, long edge1, long edge2, long edge3, long edge4) const { if (! the_file->data_mode()) return FALSE; size_t count[5]; count[0] = edge0; count[1] = edge1; count[2] = edge2; count[3] = edge3; count[4] = edge4; for (int i = 0; i < 5; i++) { if (count[i]) { if (num_dims() < i) return FALSE; } else break; } size_t start[5]; for (int j = 0; j < 5; j++) { start[j] = the_cur[j]; } return NcError::set_err( nc_get_vara_text (the_file->id(), the_id, start, count, vals) ) == NC_NOERR; }
NcBool NcVar::set_cur(long* cur) { for(int i = 0; i < num_dims(); i++) { if (cur[i] >= get_dim(i)->size() && ! get_dim(i)->is_unlimited()) return FALSE; the_cur[i] = cur[i]; } return TRUE; }
NcBool NcVar::get( char* vals, const long* count ) const { if (! the_file->data_mode()) return FALSE; size_t start[NC_MAX_DIMS]; for (int i = 0; i < num_dims(); i++) start[i] = the_cur[i]; return nc_get_vara_text (the_file->id(), the_id, start, (const size_t*) count, vals) == NC_NOERR; }
NcDim* NcFile::add_dim(NcToken name, long size) { if (!is_valid() || !define_mode()) return 0; int n = num_dims(); NcDim* dimp = new NcDim(this, name, size); dimensions[n] = dimp; // for garbage collection on close() return dimp; }
NcValues* NcVar::values( void ) const { int ndims = num_dims(); size_t crnr[NC_MAX_DIMS]; size_t edgs[NC_MAX_DIMS]; for (int i = 0; i < ndims; i++) { crnr[i] = 0; edgs[i] = get_dim(i)->size(); } NcValues* valp = get_space(); int status; switch (type()) { case ncFloat: status = NcError::set_err( nc_get_vara_float(the_file->id(), the_id, crnr, edgs, (float *)valp->base()) ); break; case ncDouble: status = NcError::set_err( nc_get_vara_double(the_file->id(), the_id, crnr, edgs, (double *)valp->base()) ); break; case ncInt: status = NcError::set_err( nc_get_vara_int(the_file->id(), the_id, crnr, edgs, (int *)valp->base()) ); break; case ncShort: status = NcError::set_err( nc_get_vara_short(the_file->id(), the_id, crnr, edgs, (short *)valp->base()) ); break; case ncByte: status = NcError::set_err( nc_get_vara_schar(the_file->id(), the_id, crnr, edgs, (signed char *)valp->base()) ); break; case ncChar: status = NcError::set_err( nc_get_vara_text(the_file->id(), the_id, crnr, edgs, (char *)valp->base()) ); break; case ncNoType: default: return 0; } if (status != NC_NOERR) return 0; return valp; }
int NcVar::dim_to_index(NcDim *rdim) { for (int i=0; i < num_dims() ; i++) { if (strcmp(get_dim(i)->name(),rdim->name()) == 0) { return i; } } // we should fail and gripe about it here.... return -1; }
NcBool NcVar::put( const char* vals, const long* count ) { /* no need to check type() vs. TYPE, invoked C function will do that */ if (! the_file->data_mode()) return FALSE; size_t start[NC_MAX_DIMS]; for (int i = 0; i < num_dims(); i++) start[i] = the_cur[i]; return NcError::set_err( nc_put_vara_text (the_file->id(), the_id, start, (const size_t *)count, vals) ) == NC_NOERR; }
long NcVar::rec_size(NcDim *rdim) { int idx = dim_to_index(rdim); long size = 1; long* edge = edges(); for( int i = 0 ; i<num_dims() ; i++) { if (i != idx) { size *= edge[i]; } } delete [] edge; return size; }
NcBool NcFile::close( void ) { int i; if (the_id == ncBad) return 0; for (i = 0; i < num_dims(); i++) delete dimensions[i]; for (i = 0; i < num_vars(); i++) delete variables[i]; delete [] dimensions; delete [] variables; delete globalv; int old_id = the_id; the_id = ncBad; return NcError::set_err( nc_close(old_id) ) == NC_NOERR; }
static bool verify_sizes(const Mda& m, const int dims[6], const QString& message) { bool result = true; int totalSize = 1; for (int k = 0; k < 6; ++k) { totalSize *= dims[k]; if (m.size(k) != dims[k]) result = false; } result = result && (m.N1() == dims[0]); result = result && (m.N2() == dims[1]); result = result && (m.N3() == dims[2]); result = result && (m.N4() == dims[3]); result = result && (m.N5() == dims[4]); result = result && (m.N6() == dims[5]); result = result && (m.ndims() == num_dims(dims)); result = result && (m.totalSize() == totalSize); if (!result) { qDebug().noquote() << message << ", verify_sizes() failed for dimensions "; for (int k = 0; k < 6; ++k) qDebug().noquote() << dims[k]; } return result; }
NcValues* NcVar::get_rec(NcDim* rdim, long slice) { int idx = dim_to_index(rdim); long size = num_dims(); size_t* start = new size_t[size]; long* startl = new long[size]; for (int i=1; i < size ; i++) { start[i] = 0; startl[i] = 0; } start[idx] = slice; startl[idx] = slice; NcBool result = set_cur(startl); if (! result ) { delete [] start; delete [] startl; return 0; } long* edgel = edges(); size_t* edge = new size_t[size]; for (int i=1; i < size ; i++) { edge[i] = edgel[i]; } edge[idx] = 1; edgel[idx] = 1; NcValues* valp = get_space(rec_size(rdim)); int status; switch (type()) { case ncFloat: status = NcError::set_err( nc_get_vara_float(the_file->id(), the_id, start, edge, (float *)valp->base()) ); break; case ncDouble: status = NcError::set_err( nc_get_vara_double(the_file->id(), the_id, start, edge, (double *)valp->base()) ); break; case ncInt: status = NcError::set_err( nc_get_vara_int(the_file->id(), the_id, start, edge, (int *)valp->base()) ); break; case ncShort: status = NcError::set_err( nc_get_vara_short(the_file->id(), the_id, start, edge, (short *)valp->base()) ); break; case ncByte: status = NcError::set_err( nc_get_vara_schar(the_file->id(), the_id, start, edge, (signed char *)valp->base()) ); break; case ncChar: status = NcError::set_err( nc_get_vara_text(the_file->id(), the_id, start, edge, (char *)valp->base()) ); break; case ncNoType: default: return 0; } delete [] start; delete [] startl; delete [] edge; delete [] edgel; if (status != NC_NOERR) { delete valp; return 0; } return valp; }
NcDim* NcFile::get_dim( int i ) const { if (! is_valid() || i < 0 || i >= num_dims()) return 0; return dimensions[i]; }
NcFile::NcFile( const char* path, FileMode fmode, size_t* chunksizeptr, size_t initialsize, FileFormat fformat ) { NcError err(NcError::silent_nonfatal); // constructor must not fail int mode = NC_NOWRITE; the_fill_mode = Fill; int status; // If the user wants a 64-bit offset format, set that flag. if (fformat == Offset64Bits) mode |= NC_64BIT_OFFSET; #ifdef USE_NETCDF4 else if (fformat == Netcdf4) mode |= NC_NETCDF4; else if (fformat == Netcdf4Classic) mode |= NC_NETCDF4|NC_CLASSIC_MODEL; #endif switch (fmode) { case Write: mode |= NC_WRITE; /*FALLTHRU*/ case ReadOnly: // use netcdf-3 interface to permit specifying tuning parameter status = NcError::set_err( nc__open(path, mode, chunksizeptr, &the_id) ); if(status != NC_NOERR) { NcError::set_err(status); the_id = -1; } in_define_mode = 0; break; case New: mode |= NC_NOCLOBBER; /*FALLTHRU*/ case Replace: // use netcdf-3 interface to permit specifying tuning parameters status = NcError::set_err( nc__create(path, mode, initialsize, chunksizeptr, &the_id) ); if(status != NC_NOERR) { NcError::set_err(status); the_id = -1; } in_define_mode = 1; break; default: the_id = ncBad; in_define_mode = 0; break; } if (is_valid()) { dimensions = new NcDim*[NC_MAX_DIMS]; variables = new NcVar*[NC_MAX_VARS]; int i; for (i = 0; i < num_dims(); i++) dimensions[i] = new NcDim(this, i); for (i = 0; i < num_vars(); i++) variables[i] = new NcVar(this, i); globalv = new NcVar(this, ncGlobal); } else { dimensions = 0; variables = 0; globalv = 0; } }