void DumpableNcFile::dumpvars( void ) { int n; static const char* types[] = {"","byte","char","short","long","float","double"}; NcVar* vp; for(n = 0; vp = get_var(n); n++) { cout << "\t" << types[vp->type()] << " " << vp->name() ; if (vp->num_dims() > 0) { cout << "("; for (int d = 0; d < vp->num_dims(); d++) { NcDim* dim = vp->get_dim(d); cout << dim->name(); if (d < vp->num_dims()-1) cout << ", "; } cout << ")"; } cout << " ;\n"; // now dump each of this variable's attributes dumpatts(*vp); } }
void DumpableNcFile::dumpdims( void ) { for (int n=0; n < num_dims(); n++) { NcDim* dim = get_dim(n); cout << "\t" << dim->name() << " = " ; if (dim->is_unlimited()) cout << "UNLIMITED" << " ;\t " << "// " << dim->size() << " currently\n"; else cout << dim->size() << " ;\n"; } }
void CopyNcVar( NcFile & ncIn, NcFile & ncOut, const std::string & strVarName, bool fCopyAttributes, bool fCopyData ) { if (!ncIn.is_valid()) { _EXCEPTIONT("Invalid input file specified"); } if (!ncOut.is_valid()) { _EXCEPTIONT("Invalid output file specified"); } NcVar * var = ncIn.get_var(strVarName.c_str()); if (var == NULL) { _EXCEPTION1("NetCDF file does not contain variable \"%s\"", strVarName.c_str()); } NcVar * varOut; std::vector<NcDim *> dimOut; dimOut.resize(var->num_dims()); std::vector<long> counts; counts.resize(var->num_dims()); long nDataSize = 1; for (int d = 0; d < var->num_dims(); d++) { NcDim * dimA = var->get_dim(d); dimOut[d] = ncOut.get_dim(dimA->name()); if (dimOut[d] == NULL) { if (dimA->is_unlimited()) { dimOut[d] = ncOut.add_dim(dimA->name()); } else { dimOut[d] = ncOut.add_dim(dimA->name(), dimA->size()); } if (dimOut[d] == NULL) { _EXCEPTION2("Failed to add dimension \"%s\" (%i) to file", dimA->name(), dimA->size()); } } if (dimOut[d]->size() != dimA->size()) { if (dimA->is_unlimited() && !dimOut[d]->is_unlimited()) { _EXCEPTION2("Mismatch between input file dimension \"%s\" and " "output file dimension (UNLIMITED / %i)", dimA->name(), dimOut[d]->size()); } else if (!dimA->is_unlimited() && dimOut[d]->is_unlimited()) { _EXCEPTION2("Mismatch between input file dimension \"%s\" and " "output file dimension (%i / UNLIMITED)", dimA->name(), dimA->size()); } else if (!dimA->is_unlimited() && !dimOut[d]->is_unlimited()) { _EXCEPTION3("Mismatch between input file dimension \"%s\" and " "output file dimension (%i / %i)", dimA->name(), dimA->size(), dimOut[d]->size()); } } counts[d] = dimA->size(); nDataSize *= counts[d]; } // ncByte / ncChar type if ((var->type() == ncByte) || (var->type() == ncChar)) { DataVector<char> data; data.Initialize(nDataSize); varOut = ncOut.add_var( var->name(), var->type(), dimOut.size(), (const NcDim**)&(dimOut[0])); if (varOut == NULL) { _EXCEPTION1("Cannot create variable \"%s\"", var->name()); } var->get(&(data[0]), &(counts[0])); varOut->put(&(data[0]), &(counts[0])); } // ncShort type if (var->type() == ncShort) { DataVector<short> data; data.Initialize(nDataSize); varOut = ncOut.add_var( var->name(), var->type(), dimOut.size(), (const NcDim**)&(dimOut[0])); if (varOut == NULL) { _EXCEPTION1("Cannot create variable \"%s\"", var->name()); } if (fCopyData) { var->get(&(data[0]), &(counts[0])); varOut->put(&(data[0]), &(counts[0])); } } // ncInt type if (var->type() == ncInt) { DataVector<int> data; data.Initialize(nDataSize); varOut = ncOut.add_var( var->name(), var->type(), dimOut.size(), (const NcDim**)&(dimOut[0])); if (varOut == NULL) { _EXCEPTION1("Cannot create variable \"%s\"", var->name()); } if (fCopyData) { var->get(&(data[0]), &(counts[0])); varOut->put(&(data[0]), &(counts[0])); } } // ncFloat type if (var->type() == ncFloat) { DataVector<float> data; data.Initialize(nDataSize); varOut = ncOut.add_var( var->name(), var->type(), dimOut.size(), (const NcDim**)&(dimOut[0])); if (varOut == NULL) { _EXCEPTION1("Cannot create variable \"%s\"", var->name()); } if (fCopyData) { var->get(&(data[0]), &(counts[0])); varOut->put(&(data[0]), &(counts[0])); } } // ncDouble type if (var->type() == ncDouble) { DataVector<double> data; data.Initialize(nDataSize); varOut = ncOut.add_var( var->name(), var->type(), dimOut.size(), (const NcDim**)&(dimOut[0])); if (varOut == NULL) { _EXCEPTION1("Cannot create variable \"%s\"", var->name()); } if (fCopyData) { var->get(&(data[0]), &(counts[0])); varOut->put(&(data[0]), &(counts[0])); } } // ncInt64 type if (var->type() == ncInt64) { DataVector<ncint64> data; data.Initialize(nDataSize); varOut = ncOut.add_var( var->name(), var->type(), dimOut.size(), (const NcDim**)&(dimOut[0])); if (varOut == NULL) { _EXCEPTION1("Cannot create variable \"%s\"", var->name()); } if (fCopyData) { var->get(&(data[0]), &(counts[0])); varOut->put(&(data[0]), &(counts[0])); } } // Check output variable exists if (varOut == NULL) { _EXCEPTION1("Unable to create output variable \"%s\"", var->name()); } // Copy attributes if (fCopyAttributes) { CopyNcVarAttributes(var, varOut); } }
int main(int argc, char** argv) { if (!cmdline(argc, argv)) { printhelp(); return EXIT_FAILURE; } NcFile infile(infilename.c_str(), NcFile::ReadOnly); if (!infile.is_valid()) { std::cerr << "Error: invalid input file -- '" << infilename << "'" << std::endl; infile.close(); return EXIT_FAILURE; } NcFile outfile(outfilename.c_str(), NcFile::Replace); if (!outfile.is_valid()) { std::cerr << "Error: cannot open output file -- '" << outfilename << "'" << std::endl; outfile.close(); return EXIT_FAILURE; } if (varstrings.size() == 0) { std::cerr << "Warning: no variables specified" << std::endl; } std::vector<NcVar*> invars; for (std::vector<std::string>::const_iterator it = varstrings.begin(); it != varstrings.end(); ++it) { NcVar* var = infile.get_var((*it).c_str()); if (var == NULL) { std::cerr << "Error: " << *it << ": no such variable" << std::endl; infile.close(); outfile.close(); return EXIT_FAILURE; } invars.push_back(var); } // extract the distinct set of dims std::map<std::string, NcDim*> indims; for (std::vector<NcVar*>::const_iterator it = invars.begin(); it != invars.end(); ++it) { NcVar* var = *it; for (int i = 0; i < var->num_dims(); ++i) { NcDim* dim = var->get_dim(i); indims[dim->name()] = dim; } } // add dims to outfile std::map<std::string, NcDim*> outdims; for (std::map<std::string, NcDim*>::const_iterator it = indims.begin(); it != indims.end(); ++it) { NcDim* dim = (*it).second; NcDim* outdim = NULL; if (dim->is_unlimited()) { outdim = outfile.add_dim(dim->name()); } else { outdim = outfile.add_dim(dim->name(), dim->size()); } if (outdim != NULL) { outdims[outdim->name()] = outdim; } } // create variables for (std::vector<NcVar*>::const_iterator it = invars.begin(); it != invars.end(); ++it) { NcVar* var = *it; std::vector<const NcDim*> dims(var->num_dims()); for (int i = 0; i < var->num_dims(); ++i) { dims[i] = outdims[var->get_dim(i)->name()]; } NcVar* outvar = outfile.add_var(var->name(), var->type(), var->num_dims(), &dims[0]); // identify largest dim, if dim (nearly) exceeds main memory, split along that dim int maxdim = -1; long maxdimsize = 0; long totallen = 1; for (int i = 0; i < var->num_dims(); ++i) { NcDim* dim = var->get_dim(i); if (dim->size() > maxdimsize) { maxdim = i; maxdimsize = dim->size(); } totallen *= dim->size(); } // TODO: support other data types totallen *= sizeof(float); // TODO: configurable page size const unsigned long pagesize = 1000000000; #ifdef __linux__ struct sysinfo info; sysinfo(&info); if (pagesize >= info.freeram) { std::cerr << "Warning: page size exceeds free memory" << std::endl; } #endif int numpages = 1; long pagesizedim = var->get_dim(maxdim)->size(); if (totallen < pagesize) { } else { long mul = 1; for (int i = 0; i < var->num_dims(); ++i) { if (i != maxdim) { NcDim* dim = var->get_dim(i); mul *= dim->size(); } } // TODO: support other data types mul *= sizeof(float); pagesizedim = pagesize / mul; numpages = var->get_dim(maxdim)->size() / pagesizedim; if (var->get_dim(maxdim)->size() % pagesizedim > 0) { ++numpages; } } std::vector< std::vector<long> > curvec; std::vector< std::vector<long> > countsvec; std::vector<long> lengths; int pages = numpages > 0 ? numpages : 1; for (int p = 0; p < pages; ++p) { long len = 1; std::vector<long> cur; std::vector<long> counts; for (int i = 0; i < var->num_dims(); ++i) { NcDim* dim = var->get_dim(i); long current = 0; long count = dim->size(); if (i == maxdim) { current = pagesizedim * p; count = pagesizedim; if (p == pages -1) { if (dim->size() % pagesizedim != 0) { count = dim->size() % pagesizedim; } } } cur.push_back(current); counts.push_back(count); len *= count; } curvec.push_back(cur); countsvec.push_back(counts); lengths.push_back(len); } std::vector< std::vector<long> >::const_iterator it1; std::vector< std::vector<long> >::const_iterator it2; std::vector<long>::const_iterator it3; for (it1 = curvec.begin(), it2 = countsvec.begin(), it3 = lengths.begin(); it1 != curvec.end() && it2 != countsvec.end() && it3 != lengths.end(); ++it1, ++it2, ++it3) { std::vector<long> cur = *it1; std::vector<long> counts = *it2; long len = *it3; var->set_cur(&cur[0]); outvar->set_cur(&cur[0]); switch (outvar->type()) { case ncByte: { ncbyte* barr = new ncbyte[len]; var->get(barr, &counts[0]); outvar->put(barr, &counts[0]); delete[] barr; break; } case ncChar: { char* carr = new char[len]; var->get(carr, &counts[0]); outvar->put(carr, &counts[0]); delete[] carr; break; } case ncShort: { short* sarr = new short[len]; var->get(sarr, &counts[0]); outvar->put(sarr, &counts[0]); delete[] sarr; break; } case ncInt: { long* larr = new long[len]; var->get(larr, &counts[0]); outvar->put(larr, &counts[0]); delete[] larr; break; } case ncFloat: { float* farr = new float[len]; var->get(farr, &counts[0]); outvar->put(farr, &counts[0]); delete[] farr; break; } case ncDouble: { double* darr = new double[len]; var->get(darr, &counts[0]); outvar->put(darr, &counts[0]); delete[] darr; break; } default: break; } } } infile.close(); outfile.close(); return 0; }
const std::string name( void ) const { return( m_dim->name() ); }
eavlNetCDFImporter::eavlNetCDFImporter(const string &filename) { file = new NcFile(filename.c_str(), NcFile::ReadOnly); if (!file->is_valid()) { THROW(eavlException,"Couldn't open file!\n"); } if (debugoutput) cerr << "num_dims="<<file->num_dims()<<endl; if (debugoutput) cerr << "num_vars="<<file->num_vars()<<endl; if (debugoutput) cerr << "num_atts="<<file->num_atts()<<endl; for (int i=0; i<file->num_dims(); i++) { NcDim *d = file->get_dim(i); if (debugoutput) cerr << " dim["<<i<<"]: name="<<d->name()<<" size="<<d->size()<<endl; } for (int i=0; i<file->num_atts(); i++) { NcAtt *a = file->get_att(i); if (debugoutput) cerr << " att["<<i<<"]: name="<<a->name()<<" numvals="<<a->num_vals()<<endl; } bool found_grid = false; for (int i=0; i<file->num_vars(); i++) { NcVar *v = file->get_var(i); if (debugoutput) { cerr << " var["<<i<<"]: name="<<v->name(); cerr << " ndims="<<v->num_dims(); cerr << " dims = "; for (int j=0; j<v->num_dims(); j++) { cerr << v->get_dim(j)->name(); if (j<v->num_dims()-1) cerr << "*"; } cerr << endl; } // Here's the condition for what we're going to use; // we only support one mesh for the moment, so we're picking one. // Also, the netcdf files we have have the time dim size as "1" if (v->num_dims() == 4 && string(v->get_dim(0)->name())=="time") { if (!found_grid) { dims.push_back(v->get_dim(1)); dims.push_back(v->get_dim(2)); dims.push_back(v->get_dim(3)); found_grid = true; vars.push_back(v); if (debugoutput) cerr << " * using as first real var\n"; } else { if (string(v->get_dim(1)->name()) == dims[0]->name() && string(v->get_dim(2)->name()) == dims[1]->name() && string(v->get_dim(3)->name()) == dims[2]->name()) { vars.push_back(v); if (debugoutput) cerr << " * using as another var; matches the first real one's dims\n"; } } } } }