void NetCdfConfigureDialog::getDimEdges(int dimId, unsigned &size, double &firstValue, double &lastValue) { if ((_currentFile->get_var(_currentVar->get_dim(dimId)->name())) != NULL) { NcVar *tmpVarOfDim = _currentFile->get_var(_currentVar->get_dim(dimId)->name()); if ((tmpVarOfDim->num_dims()) == 1) { int sizeOfDim = tmpVarOfDim->get_dim(0)->size(); size = sizeOfDim; double arrayOfDimStart[1] = {0}; size_t edgeOfArray[1] = {1}; long edgeOrigin[1] = {0}; tmpVarOfDim->set_cur(edgeOrigin); tmpVarOfDim->get(arrayOfDimStart,edgeOfArray); firstValue = arrayOfDimStart[0]; double arrayOfDimEnd[1] = {0}; edgeOrigin[0] = sizeOfDim - 1; tmpVarOfDim->set_cur(edgeOrigin); tmpVarOfDim->get(arrayOfDimEnd,edgeOfArray); lastValue = arrayOfDimEnd[0]; } } else { size = 0; firstValue = 0; lastValue = 0; } }
FieldPtr FileArome::getFieldCore(std::string iVariable, int iTime) const { // Not cached, retrieve data NcVar* var = getVar(iVariable); int nLat = mNLat; int nLon = mNLon; int numDims = var->num_dims(); long* count; long totalCount = nLat*nLon; if(numDims == 4) { // Variable has a surface dimension count = new long[4]; count[0] = 1; count[1] = 1; count[2] = nLat; count[3] = nLon; var->set_cur(iTime, 0, 0, 0); } else if(numDims == 3) { count = new long[3]; count[0] = 1; count[1] = nLat; count[2] = nLon; var->set_cur(iTime, 0, 0); } else { std::stringstream ss; ss << "Cannot read variable '" << iVariable << "' from '" << getFilename() << "'"; Util::error(ss.str()); } float* values = new float[nLat*nLon]; var->get(values, count); float MV = getMissingValue(var); float offset = getOffset(var); float scale = getScale(var); int index = 0; FieldPtr field = getEmptyField(); for(int lat = 0; lat < nLat; lat++) { for(int lon = 0; lon < nLon; lon++) { float value = values[index]; assert(index < totalCount); if(value == MV) { // Field has missing value indicator and the value is missing // Save values using our own internal missing value indicator value = Util::MV; } else { value = scale*values[index] + offset; } (*field)(lat,lon,0) = value; index++; } } delete[] values; delete[] count; return field; }
template<class T> static bool load_nc_array(const NcFile& ncf, const string& name, vector<T>& dest, bool required = true, int offset = 0, int count = -1) { NcVar *v = load_nc_variable(ncf, name.c_str(), required); if (v) { vector<long> offsets = list_of(offset).repeat(v->num_dims()-1, 0); v->set_cur(&offsets.front()); vector<long> counts (v->num_dims()); long* shape = v->edges(); transform(shape, shape + v->num_dims(), offsets.begin(), counts.begin(), minus<long>()); delete shape; if (count > 0) { counts[0] = count; } dest.resize(product(counts)); bool success = v->get(&dest.front(), &counts.front()); if (!success) { dest.resize(0); check(!required, string("NetcdfDataset::load_nc_array<") + typeid(T).name() + "> " + name + '\n' + "failed with offset " + str(offsets) + ", counts " + str(counts)); } return success; } return false; }
//YUAN: recid - the order (from ZERO) in the .nc file, chtid - the cohort id int SiteinInputer::getRecID(const int &siteid){ NcError err(NcError::silent_nonfatal); NcFile siteFile(siteinfname.c_str(), NcFile::ReadOnly); NcVar* siteidV = siteFile.get_var("CHTID"); int id = -1; for (int i=0; i<(int)siteidV->num_vals(); i++){ siteidV->set_cur(i); siteidV->get(&id, 1); if(id==siteid) return i; } return -1; }
void Regioner::createCohorList4Run(){ // read in a list of cohorts to run //netcdf error NcError err(NcError::silent_nonfatal); //open file and check if valid string filename = md.runchtfile; NcFile runFile(filename.c_str(), NcFile::ReadOnly); if(!runFile.is_valid()){ string msg = filename+" is not valid"; char* msgc = const_cast< char* > ( msg.c_str()); throw Exception(msgc, I_NCFILE_NOT_EXIST); } NcDim* chtD = runFile.get_dim("CHTID"); if(!chtD->is_valid()){ string msg="CHT Dimension is not valid in createCohortList4Run"; char* msgc = const_cast<char*> (msg.c_str()); throw Exception(msgc, I_NCDIM_NOT_EXIST); } NcVar* chtV = runFile.get_var("CHTID"); if(chtV==NULL){ string msg="Cannot get CHTID in createCohortList4Run "; char* msgc = const_cast<char*> (msg.c_str()); throw Exception(msgc, I_NCVAR_NOT_EXIST); } int numcht = chtD->size(); int chtid = -1; int chtid0 = -1; int chtidx = -1; for (int i=0; i<numcht; i++){ chtV->set_cur(i); chtV->get(&chtid, 1); runchtlist.push_back(chtid); if (i==0) chtid0=chtid; if (i==numcht-1) chtidx=chtid; } cout <<md.casename << ": " <<numcht <<" cohorts to be run @" <<md.runstages<< "\n"; cout <<" from: " <<chtid0<<" to: " <<chtidx <<"\n"; };
static string get_nc_string(const NcFile& ncf, const string& name, int offset = 0, bool required = true) { static array<long, 2> offsets = {{0, 0}}; static array<long, 2> counts = {{1, 0}}; NcVar *v = load_nc_variable(ncf, name.c_str(), required); if (v) { long* shape = v->edges(); offsets.front() = offset; counts.back() = shape[1]; v->set_cur(&offsets.front()); char* temp = new char [shape[1]]; delete shape; bool success = v->get(temp, &counts.front()); if(!success) { check(!required, " index " + str(offset) + " out of bounds for " + name + " in netcdf file"); } string s(temp); delete [] temp; return s; } return ""; }
RadarData_t ReadRadarFile(const string &filename, const float latmin, const float latmax, const float lonmin, const float lonmax) { RadarData_t inputData; // Sets the internal netcdf error handling to nonfatal for this scope NcError error_handler(NcError::verbose_nonfatal); NcFile radarFile(filename.c_str()); if (!radarFile.is_valid()) { cerr << "ERROR: Could not open radar file: " << filename << " for reading.\n"; // Error is indicated by the lack of initialization of // the filename member of the struct. return(inputData); } NcVar* latVar = radarFile.get_var("lat"); if (NULL == latVar) { cerr << "ERROR: invalid data file. No variable called 'lat'!\n"; radarFile.close(); return(inputData); } long latCnt = latVar->num_vals(); double* latVals = new double[latCnt]; latVar->get(latVals, latCnt); inputData.latUnits = GrabAttribute(latVar, 0); inputData.latSpacing = strtod(GrabAttribute(latVar, 1).c_str(), NULL); const long minLatIndex = lower_bound(latVals, latmin, latCnt); const long maxLatIndex = upper_bound(latVals, latmax, latCnt); delete latVals; latCnt = (maxLatIndex - minLatIndex) + 1; latVar->set_cur(minLatIndex); inputData.latVals = new double[latCnt]; latVar->get(inputData.latVals, latCnt); NcVar* lonVar = radarFile.get_var("lon"); if (NULL == lonVar) { cerr << "ERROR: invalid data file. No variable called 'lon'!\n"; radarFile.close(); return(inputData); } long lonCnt = lonVar->num_vals(); double* lonVals = new double[lonCnt]; lonVar->get(lonVals, lonCnt); inputData.lonUnits = GrabAttribute(lonVar, 0); inputData.lonSpacing = strtod(GrabAttribute(lonVar, 1).c_str(), NULL); const long minLonIndex = lower_bound(lonVals, lonmin, lonCnt); const long maxLonIndex = upper_bound(lonVals, lonmax, lonCnt); delete lonVals; lonCnt = (maxLonIndex - minLonIndex) + 1; lonVar->set_cur(minLonIndex); inputData.lonVals = new double[lonCnt]; lonVar->get(inputData.lonVals, lonCnt); NcVar* reflectVar = NULL; reflectVar = radarFile.get_var("value"); if ( reflectVar == NULL ) { // Try this variable name reflectVar = radarFile.get_var("Reflectivity"); } if (reflectVar == NULL) { cerr << "ERROR: invalid data file. No variable called 'value'!\n"; radarFile.close(); return(inputData); } inputData.dataEdges = reflectVar->edges(); // [0] - time, [1] - lat, [2] - lon inputData.dataEdges[1] = latCnt; inputData.dataEdges[2] = lonCnt; inputData.dataVals = new double[inputData.dataEdges[0] * inputData.dataEdges[1] * inputData.dataEdges[2]]; reflectVar->set_cur(0, minLatIndex, minLonIndex); reflectVar->get(inputData.dataVals, inputData.dataEdges); inputData.var_LongName = GrabAttribute(reflectVar, 0); inputData.var_Units = "dBZ";//GrabAttribute(reflectVar, 1); NcVar* timeVar = radarFile.get_var("time"); if (NULL == timeVar) { cerr << "ERROR: invalid data file. No variable called 'time'!\n"; radarFile.close(); return(inputData); } inputData.scanTime = timeVar->as_long(0); inputData.timeUnits = GrabAttribute(timeVar, 0); NcAtt* titleAttrib = radarFile.get_att("title"); inputData.fileTitle = (NULL == titleAttrib ? "" : titleAttrib->as_string(0)); delete titleAttrib; radarFile.close(); // Success! inputData.inputFilename = filename; return(inputData); }
int main(int argc, char ** argv){ NcError error(NcError::verbose_nonfatal); try{ std::string inFile; std::string outFile; std::string varName; std::string inList; // bool calcStdDev; BeginCommandLine() CommandLineString(inFile, "in", ""); CommandLineString(inList, "inlist",""); CommandLineString(varName, "var", ""); CommandLineString(outFile, "out", ""); // CommandLineBool(calcStdDev, "std"); ParseCommandLine(argc, argv); EndCommandLine(argv) AnnounceBanner(); if ((inFile != "") && (inList != "")){ _EXCEPTIONT("Can only open one file (--in) or list (--inlist)."); } //file list vector std::vector<std::string> vecFiles; if (inFile != ""){ vecFiles.push_back(inFile); } if (inList != ""){ GetInputFileList(inList,vecFiles); } //open up first file NcFile readin(vecFiles[0].c_str()); if (!readin.is_valid()){ _EXCEPTION1("Unable to open file %s for reading",\ vecFiles[0].c_str()); } int tLen,latLen,lonLen; NcDim * time = readin.get_dim("time"); tLen = time->size(); NcVar * timeVar = readin.get_var("time"); NcDim * lat = readin.get_dim("lat"); latLen = lat->size(); NcVar * latVar = readin.get_var("lat"); NcDim * lon = readin.get_dim("lon"); lonLen = lon->size(); NcVar * lonVar = readin.get_var("lon"); //read input variable NcVar * inVar = readin.get_var(varName.c_str()); //Create output matrix DataMatrix<double> outMat(latLen,lonLen); densCalc(inVar,outMat); //Option for calculating the yearly standard deviation /* if (calcStdDev){ for (int a=0; a<latLen; a++){ for (int b=0; b<lonLen; b++){ storeMat[0][a][b] = outMat[a][b]; } } } */ //If multiple files, add these values to the output if (vecFiles.size()>1){ DataMatrix<double> addMat(latLen,lonLen); std::cout<<"There are "<<vecFiles.size()<<" files."<<std::endl; for (int v=1; v<vecFiles.size(); v++){ NcFile addread(vecFiles[v].c_str()); NcVar * inVar = addread.get_var(varName.c_str()); densCalc(inVar,addMat); for (int a=0; a<latLen; a++){ for (int b=0; b<lonLen; b++){ outMat[a][b]+=addMat[a][b]; } } /* if (calcStdDev){ for (int a=0; a<latLen; a++){ for (int b=0; b<lonLen; b++){ storeMat[v][a][b] = addMat[a][b]; } } }*/ addread.close(); } //Divide output by number of files double div = 1./((double) vecFiles.size()); for (int a=0; a<latLen; a++){ for (int b=0; b<lonLen; b++){ outMat[a][b]*=div; } } } NcFile readout(outFile.c_str(),NcFile::Replace, NULL,0,NcFile::Offset64Bits); NcDim * outLat = readout.add_dim("lat", latLen); NcDim * outLon = readout.add_dim("lon", lonLen); NcVar * outLatVar = readout.add_var("lat",ncDouble,outLat); NcVar * outLonVar = readout.add_var("lon",ncDouble,outLon); std::cout<<"Copying dimension attributes."<<std::endl; copy_dim_var(latVar,outLatVar); copy_dim_var(lonVar,outLonVar); std::cout<<"Creating density variable."<<std::endl; NcVar * densVar = readout.add_var("dens",ncDouble,outLat,outLon); densVar->set_cur(0,0); densVar->put((&outMat[0][0]),latLen,lonLen); /* if (calcStdDev){ NcVar * stdDevVar = readout.add_var("stddev", ncDouble,outLat,outLon); DataMatrix<double> stdDevMat(latLen,lonLen); yearlyStdDev(storeMat,vecFiles.size(),latLen,lonLen,stdDevMat); stdDevVar->set_cur(0,0); stdDevVar->put(&(stdDevMat[0][0]),latLen,lonLen); std::cout<<" created sd variable"<<std::endl; } */ readout.close(); readin.close(); } catch (Exception &e){ std::cout<<e.ToString()<<std::endl; } }
void ReadCFTimeDataFromNcFile( NcFile * ncfile, const std::string & strFilename, std::vector<Time> & vecTimes, bool fWarnOnMissingCalendar ) { // Empty existing Time vector vecTimes.clear(); // Get time dimension NcDim * dimTime = ncfile->get_dim("time"); if (dimTime == NULL) { _EXCEPTION1("Dimension \"time\" not found in file \"%s\"", strFilename.c_str()); } // Get time variable NcVar * varTime = ncfile->get_var("time"); if (varTime == NULL) { _EXCEPTION1("Variable \"time\" not found in file \"%s\"", strFilename.c_str()); } if (varTime->num_dims() != 1) { _EXCEPTION1("Variable \"time\" has more than one dimension in file \"%s\"", strFilename.c_str()); } if (strcmp(varTime->get_dim(0)->name(), "time") != 0) { _EXCEPTION1("Variable \"time\" does not have dimension \"time\" in file \"%s\"", strFilename.c_str()); } // Calendar attribute NcAtt * attTimeCal = varTime->get_att("calendar"); std::string strCalendar; if (attTimeCal == NULL) { if (fWarnOnMissingCalendar) { Announce("WARNING: Variable \"time\" is missing \"calendar\" attribute; assuming \"standard\""); } strCalendar = "standard"; } else { strCalendar = attTimeCal->as_string(0); } Time::CalendarType eCalendarType = Time::CalendarTypeFromString(strCalendar); // Units attribute NcAtt * attTimeUnits = varTime->get_att("units"); if (attTimeUnits == NULL) { _EXCEPTION1("Variable \"time\" is missing \"units\" attribute in file \"%s\"", strFilename.c_str()); } std::string strTimeUnits = attTimeUnits->as_string(0); // Load in time data DataVector<int> vecTimeInt; DataVector<float> vecTimeFloat; DataVector<double> vecTimeDouble; DataVector<ncint64> vecTimeInt64; if (varTime->type() == ncInt) { vecTimeInt.Initialize(dimTime->size()); varTime->set_cur((long)0); varTime->get(&(vecTimeInt[0]), dimTime->size()); } else if (varTime->type() == ncFloat) { vecTimeFloat.Initialize(dimTime->size()); varTime->set_cur((long)0); varTime->get(&(vecTimeFloat[0]), dimTime->size()); } else if (varTime->type() == ncDouble) { vecTimeDouble.Initialize(dimTime->size()); varTime->set_cur((long)0); varTime->get(&(vecTimeDouble[0]), dimTime->size()); } else if (varTime->type() == ncInt64) { vecTimeInt64.Initialize(dimTime->size()); varTime->set_cur((long)0); varTime->get(&(vecTimeInt64[0]), dimTime->size()); } else { _EXCEPTION1("Variable \"time\" has invalid type " "(expected \"int\", \"int64\", \"float\" or \"double\")" " in file \"%s\"", strFilename.c_str()); } for (int t = 0; t < dimTime->size(); t++) { Time time(eCalendarType); if (varTime->type() == ncInt) { time.FromCFCompliantUnitsOffsetInt( strTimeUnits, vecTimeInt[t]); } else if (varTime->type() == ncFloat) { time.FromCFCompliantUnitsOffsetDouble( strTimeUnits, static_cast<double>(vecTimeFloat[t])); } else if (varTime->type() == ncDouble) { time.FromCFCompliantUnitsOffsetDouble( strTimeUnits, vecTimeDouble[t]); } else if (varTime->type() == ncInt64) { time.FromCFCompliantUnitsOffsetInt( strTimeUnits, (int)(vecTimeInt64[t])); } vecTimes.push_back(time); } }
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; }
int main(int argc, char ** argv) { MPI_Init(&argc, &argv); NcError error(NcError::silent_nonfatal); try { // Input filename std::string strInputFile; // Output filename std::string strOutputFile; // Separate topography file std::string strTopographyFile; // List of variables to extract std::string strVariables; // Extract geopotential height bool fGeopotentialHeight; // Pressure levels to extract std::string strPressureLevels; // Height levels to extract std::string strHeightLevels; // Extract variables at the surface bool fExtractSurface; // Extract total energy bool fExtractTotalEnergy; // Parse the command line BeginCommandLine() CommandLineString(strInputFile, "in", ""); CommandLineString(strOutputFile, "out", ""); CommandLineString(strVariables, "var", ""); CommandLineBool(fGeopotentialHeight, "output_z"); CommandLineBool(fExtractTotalEnergy, "output_energy"); CommandLineString(strPressureLevels, "p", ""); CommandLineString(strHeightLevels, "z", ""); CommandLineBool(fExtractSurface, "surf"); ParseCommandLine(argc, argv); EndCommandLine(argv) AnnounceBanner(); // Check command line arguments if (strInputFile == "") { _EXCEPTIONT("No input file specified"); } if (strOutputFile == "") { _EXCEPTIONT("No output file specified"); } if (strVariables == "") { _EXCEPTIONT("No variables specified"); } // Parse variable string std::vector< std::string > vecVariableStrings; ParseVariableList(strVariables, vecVariableStrings); // Check variables if (vecVariableStrings.size() == 0) { _EXCEPTIONT("No variables specified"); } // Parse pressure level string std::vector<double> vecPressureLevels; ParseLevelArray(strPressureLevels, vecPressureLevels); int nPressureLevels = (int)(vecPressureLevels.size()); for (int k = 0; k < nPressureLevels; k++) { if (vecPressureLevels[k] <= 0.0) { _EXCEPTIONT("Non-positive pressure values not allowed"); } } // Parse height level string std::vector<double> vecHeightLevels; ParseLevelArray(strHeightLevels, vecHeightLevels); int nHeightLevels = (int)(vecHeightLevels.size()); // Check pressure levels if ((nPressureLevels == 0) && (nHeightLevels == 0) && (!fExtractSurface) ) { _EXCEPTIONT("No pressure / height levels to process"); } // Open input file AnnounceStartBlock("Loading input file"); NcFile ncdf_in(strInputFile.c_str(), NcFile::ReadOnly); if (!ncdf_in.is_valid()) { _EXCEPTION1("Unable to open file \"%s\" for reading", strInputFile.c_str()); } // Load time array Announce("Time"); NcVar * varTime = ncdf_in.get_var("time"); if (varTime == NULL) { _EXCEPTION1("File \"%s\" does not contain variable \"time\"", strInputFile.c_str()); } int nTime = varTime->get_dim(0)->size(); DataArray1D<double> dTime(nTime); varTime->set_cur((long)0); varTime->get(&(dTime[0]), nTime); // Load latitude array Announce("Latitude"); NcVar * varLat = ncdf_in.get_var("lat"); if (varLat == NULL) { _EXCEPTION1("File \"%s\" does not contain variable \"lat\"", strInputFile.c_str()); } int nLat = varLat->get_dim(0)->size(); DataArray1D<double> dLat(nLat); varLat->set_cur((long)0); varLat->get(&(dLat[0]), nLat); // Load longitude array Announce("Longitude"); NcVar * varLon = ncdf_in.get_var("lon"); if (varLon == NULL) { _EXCEPTION1("File \"%s\" does not contain variable \"lon\"", strInputFile.c_str()); } int nLon = varLon->get_dim(0)->size(); DataArray1D<double> dLon(nLon); varLon->set_cur((long)0); varLon->get(&(dLon[0]), nLon); // Load level array Announce("Level"); NcVar * varLev = ncdf_in.get_var("lev"); if (varLev == NULL) { _EXCEPTION1("File \"%s\" does not contain variable \"lev\"", strInputFile.c_str()); } int nLev = varLev->get_dim(0)->size(); DataArray1D<double> dLev(nLev); varLev->set_cur((long)0); varLev->get(&(dLev[0]), nLev); // Load level interface array Announce("Interface"); NcVar * varILev = ncdf_in.get_var("ilev"); int nILev = 0; DataArray1D<double> dILev; if (varILev == NULL) { Announce("Warning: Variable \"ilev\" not found"); } else { nILev = varILev->get_dim(0)->size(); if (nILev != nLev + 1) { _EXCEPTIONT("Variable \"ilev\" must have size lev+1"); } dILev.Allocate(nILev); varILev->set_cur((long)0); varILev->get(&(dILev[0]), nILev); } // Load topography Announce("Topography"); NcVar * varZs = ncdf_in.get_var("Zs"); if (varZs == NULL) { _EXCEPTION1("File \"%s\" does not contain variable \"Zs\"", strInputFile.c_str()); } DataArray2D<double> dZs(nLat, nLon); varZs->set_cur((long)0, (long)0); varZs->get(&(dZs[0][0]), nLat, nLon); AnnounceEndBlock("Done"); // Open output file AnnounceStartBlock("Constructing output file"); NcFile ncdf_out(strOutputFile.c_str(), NcFile::Replace); if (!ncdf_out.is_valid()) { _EXCEPTION1("Unable to open file \"%s\" for writing", strOutputFile.c_str()); } CopyNcFileAttributes(&ncdf_in, &ncdf_out); // Output time array Announce("Time"); NcDim * dimOutTime = ncdf_out.add_dim("time"); NcVar * varOutTime = ncdf_out.add_var("time", ncDouble, dimOutTime); varOutTime->set_cur((long)0); varOutTime->put(&(dTime[0]), nTime); CopyNcVarAttributes(varTime, varOutTime); // Output pressure array NcDim * dimOutP = NULL; NcVar * varOutP = NULL; if (nPressureLevels > 0) { Announce("Pressure"); dimOutP = ncdf_out.add_dim("p", nPressureLevels); varOutP = ncdf_out.add_var("p", ncDouble, dimOutP); varOutP->set_cur((long)0); varOutP->put(&(vecPressureLevels[0]), nPressureLevels); } // Output height array NcDim * dimOutZ = NULL; NcVar * varOutZ = NULL; if (nHeightLevels > 0) { Announce("Height"); dimOutZ = ncdf_out.add_dim("z", nHeightLevels); varOutZ = ncdf_out.add_var("z", ncDouble, dimOutZ); varOutZ->set_cur((long)0); varOutZ->put(&(vecHeightLevels[0]), nHeightLevels); } // Output latitude and longitude array Announce("Latitude"); NcDim * dimOutLat = ncdf_out.add_dim("lat", nLat); NcVar * varOutLat = ncdf_out.add_var("lat", ncDouble, dimOutLat); varOutLat->set_cur((long)0); varOutLat->put(&(dLat[0]), nLat); CopyNcVarAttributes(varLat, varOutLat); Announce("Longitude"); NcDim * dimOutLon = ncdf_out.add_dim("lon", nLon); NcVar * varOutLon = ncdf_out.add_var("lon", ncDouble, dimOutLon); varOutLon->set_cur((long)0); varOutLon->put(&(dLon[0]), nLon); CopyNcVarAttributes(varLon, varOutLon); // Output topography Announce("Topography"); NcVar * varOutZs = ncdf_out.add_var( "Zs", ncDouble, dimOutLat, dimOutLon); varOutZs->set_cur((long)0, (long)0); varOutZs->put(&(dZs[0][0]), nLat, nLon); AnnounceEndBlock("Done"); // Done AnnounceEndBlock("Done"); // Load all variables Announce("Loading variables"); std::vector<NcVar *> vecNcVar; for (int v = 0; v < vecVariableStrings.size(); v++) { vecNcVar.push_back(ncdf_in.get_var(vecVariableStrings[v].c_str())); if (vecNcVar[v] == NULL) { _EXCEPTION1("Unable to load variable \"%s\" from file", vecVariableStrings[v].c_str()); } } // Physical constants Announce("Initializing thermodynamic variables"); NcAtt * attEarthRadius = ncdf_in.get_att("earth_radius"); double dEarthRadius = attEarthRadius->as_double(0); NcAtt * attRd = ncdf_in.get_att("Rd"); double dRd = attRd->as_double(0); NcAtt * attCp = ncdf_in.get_att("Cp"); double dCp = attCp->as_double(0); double dGamma = dCp / (dCp - dRd); NcAtt * attP0 = ncdf_in.get_att("P0"); double dP0 = attP0->as_double(0); double dPressureScaling = dP0 * std::pow(dRd / dP0, dGamma); NcAtt * attZtop = ncdf_in.get_att("Ztop"); double dZtop = attZtop->as_double(0); // Input data DataArray3D<double> dataIn(nLev, nLat, nLon); DataArray3D<double> dataInt(nILev, nLat, nLon); // Output data DataArray2D<double> dataOut(nLat, nLon); // Pressure in column DataArray1D<double> dataColumnP(nLev); // Height in column DataArray1D<double> dataColumnZ(nLev); DataArray1D<double> dataColumnIZ(nILev); // Column weights DataArray1D<double> dW(nLev); DataArray1D<double> dIW(nILev); // Loop through all times, pressure levels and variables AnnounceStartBlock("Interpolating"); // Add energy variable NcVar * varEnergy; if (fExtractTotalEnergy) { varEnergy = ncdf_out.add_var("TE", ncDouble, dimOutTime); } // Create output pressure variables std::vector<NcVar *> vecOutNcVarP; if (nPressureLevels > 0) { for (int v = 0; v < vecVariableStrings.size(); v++) { vecOutNcVarP.push_back( ncdf_out.add_var( vecVariableStrings[v].c_str(), ncDouble, dimOutTime, dimOutP, dimOutLat, dimOutLon)); // Copy attributes CopyNcVarAttributes(vecNcVar[v], vecOutNcVarP[v]); } } // Create output height variables std::vector<NcVar *> vecOutNcVarZ; if (nHeightLevels > 0) { for (int v = 0; v < vecVariableStrings.size(); v++) { std::string strVarName = vecVariableStrings[v]; if (nPressureLevels > 0) { strVarName += "z"; } vecOutNcVarZ.push_back( ncdf_out.add_var( strVarName.c_str(), ncDouble, dimOutTime, dimOutZ, dimOutLat, dimOutLon)); // Copy attributes CopyNcVarAttributes(vecNcVar[v], vecOutNcVarZ[v]); } } // Create output surface variable std::vector<NcVar *> vecOutNcVarS; if (fExtractSurface) { for (int v = 0; v < vecVariableStrings.size(); v++) { std::string strVarName = vecVariableStrings[v]; strVarName += "S"; vecOutNcVarS.push_back( ncdf_out.add_var( strVarName.c_str(), ncDouble, dimOutTime, dimOutLat, dimOutLon)); // Copy attributes CopyNcVarAttributes(vecNcVar[v], vecOutNcVarS[v]); } } // Loop over all times for (int t = 0; t < nTime; t++) { char szAnnounce[256]; sprintf(szAnnounce, "Time %i", t); AnnounceStartBlock(szAnnounce); // Rho DataArray3D<double> dataRho(nLev, nLat, nLon); NcVar * varRho = ncdf_in.get_var("Rho"); if (varRho == NULL) { _EXCEPTIONT("Unable to load variable \"Rho\" from file"); } varRho->set_cur(t, 0, 0, 0); varRho->get(&(dataRho[0][0][0]), 1, nLev, nLat, nLon); // Pressure DataArray3D<double> dataP(nLev, nLat, nLon); if (nPressureLevels != 0) { NcVar * varP = ncdf_in.get_var("P"); if (varP == NULL) { _EXCEPTIONT("Unable to load variable \"P\" from file"); } varP->set_cur(t, 0, 0, 0); varP->get(&(dataP[0][0][0]), 1, nLev, nLat, nLon); } /* // Populate pressure array if (nPressureLevels > 0) { // Calculate pointwise pressure for (int k = 0; k < nLev; k++) { for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { dataP[k][i][j] = dPressureScaling * exp(log(dataRho[k][i][j] * dataP[k][i][j]) * dGamma); } } } } */ // Height everywhere DataArray3D<double> dataZ(nLev, nLat, nLon); DataArray3D<double> dataIZ; if (nILev != 0) { dataIZ.Allocate(nILev, nLat, nLon); } // Populate height array if ((nHeightLevels > 0) || (fGeopotentialHeight)) { for (int k = 0; k < nLev; k++) { for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { dataZ[k][i][j] = dZs[i][j] + dLev[k] * (dZtop - dZs[i][j]); } } } for (int k = 0; k < nILev; k++) { for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { dataIZ[k][i][j] = dZs[i][j] + dILev[k] * (dZtop - dZs[i][j]); } } } } // Loop through all pressure levels and variables for (int v = 0; v < vecNcVar.size(); v++) { bool fOnInterfaces = false; // Load in the data array vecNcVar[v]->set_cur(t, 0, 0, 0); if (vecNcVar[v]->get_dim(1)->size() == nLev) { vecNcVar[v]->get(&(dataIn[0][0][0]), 1, nLev, nLat, nLon); Announce("%s (n)", vecVariableStrings[v].c_str()); } else if (vecNcVar[v]->get_dim(1)->size() == nILev) { vecNcVar[v]->get(&(dataInt[0][0][0]), 1, nILev, nLat, nLon); fOnInterfaces = true; Announce("%s (i)", vecVariableStrings[v].c_str()); } else { _EXCEPTION1("Variable \"%s\" has invalid level dimension", vecVariableStrings[v].c_str()); } // At the physical surface if (fExtractSurface) { if (fOnInterfaces) { for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { dataOut[i][j] = dataInt[0][i][j]; } } } else { int kBegin = 0; int kEnd = 3; PolynomialInterp::LagrangianPolynomialCoeffs( 3, dLev, dW, 0.0); // Loop thorugh all latlon indices for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { // Interpolate in the vertical dataOut[i][j] = 0.0; for (int k = kBegin; k < kEnd; k++) { dataOut[i][j] += dW[k] * dataIn[k][i][j]; } } } } // Write variable vecOutNcVarS[v]->set_cur(t, 0, 0); vecOutNcVarS[v]->put(&(dataOut[0][0]), 1, nLat, nLon); } // Loop through all pressure levels for (int p = 0; p < nPressureLevels; p++) { // Loop thorugh all latlon indices for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { // Store column pressure for (int k = 0; k < nLev; k++) { dataColumnP[k] = dataP[k][i][j]; } // Find weights int kBegin = 0; int kEnd = 0; // On a pressure surface InterpolationWeightsLinear( vecPressureLevels[p], dataColumnP, kBegin, kEnd, dW); // Interpolate in the vertical dataOut[i][j] = 0.0; for (int k = kBegin; k < kEnd; k++) { dataOut[i][j] += dW[k] * dataIn[k][i][j]; } } } // Write variable vecOutNcVarP[v]->set_cur(t, p, 0, 0); vecOutNcVarP[v]->put(&(dataOut[0][0]), 1, 1, nLat, nLon); } // Loop through all height levels for (int z = 0; z < nHeightLevels; z++) { // Loop thorugh all latlon indices for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { // Find weights int kBegin = 0; int kEnd = 0; // Interpolate from levels to z surfaces if (!fOnInterfaces) { for (int k = 0; k < nLev; k++) { dataColumnZ[k] = dataZ[k][i][j]; } InterpolationWeightsLinear( vecHeightLevels[z], dataColumnZ, kBegin, kEnd, dW); dataOut[i][j] = 0.0; for (int k = kBegin; k < kEnd; k++) { dataOut[i][j] += dW[k] * dataIn[k][i][j]; } // Interpolate from interfaces to z surfaces } else { for (int k = 0; k < nILev; k++) { dataColumnIZ[k] = dataIZ[k][i][j]; } InterpolationWeightsLinear( vecHeightLevels[z], dataColumnIZ, kBegin, kEnd, dIW); dataOut[i][j] = 0.0; for (int k = kBegin; k < kEnd; k++) { dataOut[i][j] += dIW[k] * dataInt[k][i][j]; } } } } // Write variable vecOutNcVarZ[v]->set_cur(t, z, 0, 0); vecOutNcVarZ[v]->put(&(dataOut[0][0]), 1, 1, nLat, nLon); } } // Output geopotential height if (fGeopotentialHeight) { Announce("Geopotential height"); // Output variables NcVar * varOutZ; NcVar * varOutZs; if (nPressureLevels > 0) { varOutZ = ncdf_out.add_var( "PHIZ", ncDouble, dimOutTime, dimOutP, dimOutLat, dimOutLon); } if (fExtractSurface) { varOutZs = ncdf_out.add_var( "PHIZS", ncDouble, dimOutTime, dimOutLat, dimOutLon); } // Interpolate onto pressure levels for (int p = 0; p < nPressureLevels; p++) { // Loop thorugh all latlon indices for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { int kBegin = 0; int kEnd = 0; for (int k = 0; k < nLev; k++) { dataColumnP[k] = dataP[k][i][j]; } InterpolationWeightsLinear( vecPressureLevels[p], dataColumnP, kBegin, kEnd, dW); // Interpolate in the vertical dataOut[i][j] = 0.0; for (int k = kBegin; k < kEnd; k++) { dataOut[i][j] += dW[k] * dataZ[k][i][j]; } } } // Write variable varOutZ->set_cur(t, p, 0, 0); varOutZ->put(&(dataOut[0][0]), 1, 1, nLat, nLon); } // Interpolate onto the physical surface if (fExtractSurface) { int kBegin = 0; int kEnd = 3; PolynomialInterp::LagrangianPolynomialCoeffs( 3, dLev, dW, 0.0); // Loop thorugh all latlon indices for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { // Interpolate in the vertical dataOut[i][j] = 0.0; for (int k = kBegin; k < kEnd; k++) { dataOut[i][j] += dW[k] * dataZ[k][i][j]; } } } // Write variable varOutZs->set_cur(t, 0, 0); varOutZs->put(&(dataOut[0][0]), 1, nLat, nLon); } } // Extract total energy if (fExtractTotalEnergy) { Announce("Total Energy"); // Zonal velocity DataArray3D<double> dataU(nLev, nLat, nLon); NcVar * varU = ncdf_in.get_var("U"); varU->set_cur(t, 0, 0, 0); varU->get(&(dataU[0][0][0]), 1, nLev, nLat, nLon); // Meridional velocity DataArray3D<double> dataV(nLev, nLat, nLon); NcVar * varV = ncdf_in.get_var("V"); varV->set_cur(t, 0, 0, 0); varV->get(&(dataV[0][0][0]), 1, nLev, nLat, nLon); // Vertical velocity DataArray3D<double> dataW(nLev, nLat, nLon); NcVar * varW = ncdf_in.get_var("W"); varW->set_cur(t, 0, 0, 0); varW->get(&(dataW[0][0][0]), 1, nLev, nLat, nLon); // Calculate total energy double dTotalEnergy = 0.0; double dElementRefArea = dEarthRadius * dEarthRadius * M_PI / static_cast<double>(nLat) * 2.0 * M_PI / static_cast<double>(nLon); for (int k = 0; k < nLev; k++) { for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { double dKineticEnergy = 0.5 * dataRho[k][i][j] * ( dataU[k][i][j] * dataU[k][i][j] + dataV[k][i][j] * dataV[k][i][j] + dataW[k][i][j] * dataW[k][i][j]); double dInternalEnergy = dataP[k][i][j] / (dGamma - 1.0); dTotalEnergy += (dKineticEnergy + dInternalEnergy) * std::cos(M_PI * dLat[i] / 180.0) * dElementRefArea * (dZtop - dZs[i][j]) / static_cast<double>(nLev); } } } // Put total energy into file varEnergy->set_cur(t); varEnergy->put(&dTotalEnergy, 1); } AnnounceEndBlock("Done"); } AnnounceEndBlock("Done"); } catch(Exception & e) { Announce(e.ToString().c_str()); } // Finalize MPI MPI_Finalize(); }
int main(int argc, char ** argv) { try { // Parameters Parameters param; // Output filename std::string strOutputFile; // Horizontal minimum wave number int nKmin; // Horizontal maximum wave number int nKmax; // Parse the command line BeginCommandLine() CommandLineInt(param.nPhiElements, "n", 40); CommandLineInt(nKmin, "kmin", 1); CommandLineInt(nKmax, "kmax", 20); CommandLineDouble(param.dXscale, "X", 1.0); CommandLineDouble(param.dT0, "T0", 300.0); CommandLineDouble(param.dU0, "U0", 20.0); CommandLineDouble(param.dG, "G", 9.80616); CommandLineDouble(param.dOmega, "omega", 7.29212e-5); CommandLineDouble(param.dGamma, "gamma", 1.4); CommandLineString(strOutputFile, "out", "wave.nc"); ParseCommandLine(argc, argv); EndCommandLine(argv) AnnounceBanner(); // Generate latitude values param.GenerateLatituteArray(param.nPhiElements); // Open NetCDF file NcFile ncdf_out(strOutputFile.c_str(), NcFile::Replace); NcDim *dimK = ncdf_out.add_dim("k", nKmax - nKmin + 1); NcDim *dimLat = ncdf_out.add_dim("lat", param.nPhiElements); NcDim *dimEig = ncdf_out.add_dim("eig", param.nPhiElements); // Write parameters and latitudes to file param.WriteToNcFile(ncdf_out, dimLat, dimLatS); // Wave numbers NcVar *varK = ncdf_out.add_var("k", ncInt, dimK); DataVector<int> vecK; vecK.Initialize(nKmax - nKmin + 1); for (int nK = nKmin; nK <= nKmax; nK++) { vecK[nK - nKmin] = nK; } varK->set_cur((long)0); varK->put(vecK, nKmax - nKmin + 1); // Eigenvalues NcVar *varMR = ncdf_out.add_var("mR", ncDouble, dimK, dimEig); NcVar *varMI = ncdf_out.add_var("mI", ncDouble, dimK, dimEig); NcVar *varUR = ncdf_out.add_var("uR", ncDouble, dimK, dimEig, dimLat); NcVar *varUI = ncdf_out.add_var("uI", ncDouble, dimK, dimEig, dimLat); NcVar *varVR = ncdf_out.add_var("vR", ncDouble, dimK, dimEig, dimLatS); NcVar *varVI = ncdf_out.add_var("vI", ncDouble, dimK, dimEig, dimLatS); NcVar *varPR = ncdf_out.add_var("pR", ncDouble, dimK, dimEig, dimLat); NcVar *varPI = ncdf_out.add_var("pI", ncDouble, dimK, dimEig, dimLat); NcVar *varWR = ncdf_out.add_var("wR", ncDouble, dimK, dimEig, dimLat); NcVar *varWI = ncdf_out.add_var("wI", ncDouble, dimK, dimEig, dimLat); NcVar *varRhoR = ncdf_out.add_var("rhoR", ncDouble, dimK, dimEig, dimLat); NcVar *varRhoI = ncdf_out.add_var("rhoI", ncDouble, dimK, dimEig, dimLat); // Allocate temporary arrays DataVector<double> dUR; dUR.Initialize(param.nPhiElements); DataVector<double> dUI; dUI.Initialize(param.nPhiElements); DataVector<double> dVR; dVR.Initialize(param.nPhiElements-1); DataVector<double> dVI; dVI.Initialize(param.nPhiElements-1); DataVector<double> dPR; dPR.Initialize(param.nPhiElements); DataVector<double> dPI; dPI.Initialize(param.nPhiElements); DataVector<double> dWR; dWR.Initialize(param.nPhiElements); DataVector<double> dWI; dWI.Initialize(param.nPhiElements); DataVector<double> dRhoR; dRhoR.Initialize(param.nPhiElements); DataVector<double> dRhoI; dRhoI.Initialize(param.nPhiElements); // Loop over all horizontal wave numbers for (int nK = nKmin; nK <= nKmax; nK++) { // Build matrices char szMessage[100]; sprintf(szMessage, "Building evolution matrices (k = %i)", nK); AnnounceStartBlock(szMessage); DataMatrix<double> matM; DataMatrix<double> matB; GenerateEvolutionMatrix(nK, param, matM, matB); AnnounceEndBlock("Done"); // Solve the matrices AnnounceStartBlock("Solving evolution matrices"); DataVector<double> vecAlphaR; DataVector<double> vecAlphaI; DataVector<double> vecBeta; DataMatrix<double> matVR; vecAlphaR.Initialize(matM.GetRows()); vecAlphaI.Initialize(matM.GetRows()); vecBeta .Initialize(matM.GetRows()); matVR .Initialize(matM.GetRows(), matM.GetColumns()); SolveEvolutionMatrix( matM, matB, vecAlphaR, vecAlphaI, vecBeta, matVR); // Sort eigenvalues std::multimap<double, int> mapSortedRows; for (int i = 0; i < vecBeta.GetRows(); i++) { if (vecBeta[i] != 0.0) { double dLambdaR = vecAlphaR[i] / vecBeta[i]; double dLambdaI = vecAlphaI[i] / vecBeta[i]; double dMR = dLambdaI; double dMI = - dLambdaR - 1.0; double dEvalMagnitude = fabs(dMR); //printf("\n%1.5e %1.5e ", dMR, dMI); // Purely imaginary eigenvalue if (dMR == 0.0) { // Wave must decay with height if (dMI < 0.0) { continue; } // Complex-conjugate pair of eigenvalues } else { // Phase propagation must be downward, and energy // propagation upwards if (dMR < 0.0) { continue; } } //printf("(OK)"); mapSortedRows.insert( std::pair<double, int>(dEvalMagnitude, i)); // Only store one entry for complex-conjugate pairs if (vecAlphaI[i] != 0.0) { i++; } } } Announce("%i eigenmodes found to satisfy entropy condition", mapSortedRows.size()); /* if (mapSortedRows.size() != param.nPhiElements) { _EXCEPTIONT("Mismatch between eigenmode count and latitude count"); } */ AnnounceEndBlock("Done"); // Write the matrices to a file AnnounceStartBlock("Writing results"); int iKix = nK - nKmin; int iWave = 0; std::map<double, int>::const_iterator it; for (it = mapSortedRows.begin(); it != mapSortedRows.end(); it++) { int i = it->second; double dLambdaR = vecAlphaR[i] / vecBeta[i]; double dLambdaI = vecAlphaI[i] / vecBeta[i]; double dMR = dLambdaI; double dMI = - dLambdaR - 1.0; // Dump eigenvalue to NetCDF file varMR->set_cur(iKix, iWave); varMR->put(&dMR, 1, 1); varMI->set_cur(iKix, iWave); varMI->put(&dMI, 1, 1); // Store real part of eigenfunction for (int j = 0; j < param.nPhiElements; j++) { dUR [j] = matVR[i][4*j ]; dPR [j] = matVR[i][4*j+1]; dWR [j] = matVR[i][4*j+2]; dRhoR[j] = matVR[i][4*j+3]; } for (int j = 0; j < param.nPhiElements-1; j++) { dVR[j] = matVR[i][4 * param.nPhiElements + j]; } // Complex eigenvalue / eigenfunction pair if (dLambdaI != 0.0) { // Eigenvalue Lambda is complex conjugate dMR = -dMR; // Dump eigenvalue to NetCDF file varMR->set_cur(iKix, iWave+1); varMR->put(&dMR, 1, 1); varMI->set_cur(iKix, iWave+1); varMI->put(&dMI, 1, 1); // Store imaginary component of vector for (int j = 0; j < param.nPhiElements; j++) { dUI [j] = matVR[i+1][4*j ]; dPI [j] = matVR[i+1][4*j+1]; dWI [j] = matVR[i+1][4*j+2]; dRhoI[j] = matVR[i+1][4*j+3]; } for (int j = 0; j < param.nPhiElements-1; j++) { dVI[j] = matVR[i+1][4 * param.nPhiElements + j]; } // Real eigenvalue / eigenvector pair } else { dUI.Zero(); dPI.Zero(); dWI.Zero(); dRhoI.Zero(); dVI.Zero(); } // Dump the first eigenfunction to the file varUR->set_cur(iKix, iWave, 0); varUR->put(dUR, 1, 1, param.nPhiElements); varVR->set_cur(iKix, iWave, 0); varVR->put(dVR, 1, 1, param.nPhiElements-1); varPR->set_cur(iKix, iWave, 0); varPR->put(dPR, 1, 1, param.nPhiElements); varWR->set_cur(iKix, iWave, 0); varWR->put(dWR, 1, 1, param.nPhiElements); varRhoR->set_cur(iKix, iWave, 0); varRhoR->put(dRhoR, 1, 1, param.nPhiElements); varUI->set_cur(iKix, iWave, 0); varUI->put(dUI, 1, 1, param.nPhiElements); varVI->set_cur(iKix, iWave, 0); varVI->put(dVI, 1, 1, param.nPhiElements-1); varPI->set_cur(iKix, iWave, 0); varPI->put(dPI, 1, 1, param.nPhiElements); varWI->set_cur(iKix, iWave, 0); varWI->put(dWI, 1, 1, param.nPhiElements); varRhoI->set_cur(iKix, iWave, 0); varRhoI->put(dRhoI, 1, 1, param.nPhiElements); // Complex eigenvalue / eigenvector pair if (dLambdaI != 0.0) { for (int j = 0; j < param.nPhiElements; j++) { dUI [j] = - dUI [j]; dPI [j] = - dPI [j]; dWI [j] = - dWI [j]; dRhoI[j] = - dRhoI[j]; } for (int j = 0; j < param.nPhiElements-1; j++) { dVI[j] = - dVI[j]; } varUR->set_cur(iKix, iWave+1, 0); varUR->put(dUR, 1, 1, param.nPhiElements); varVR->set_cur(iKix, iWave+1, 0); varVR->put(dVR, 1, 1, param.nPhiElements-1); varPR->set_cur(iKix, iWave+1, 0); varPR->put(dPR, 1, 1, param.nPhiElements); varWR->set_cur(iKix, iWave+1, 0); varWR->put(dWR, 1, 1, param.nPhiElements); varRhoR->set_cur(iKix, iWave+1, 0); varRhoR->put(dRhoR, 1, 1, param.nPhiElements); varUI->set_cur(iKix, iWave+1, 0); varUI->put(dUI, 1, 1, param.nPhiElements); varVI->set_cur(iKix, iWave+1, 0); varVI->put(dVI, 1, 1, param.nPhiElements-1); varPI->set_cur(iKix, iWave+1, 0); varPI->put(dPI, 1, 1, param.nPhiElements); varWI->set_cur(iKix, iWave+1, 0); varWI->put(dWI, 1, 1, param.nPhiElements); varRhoI->set_cur(iKix, iWave+1, 0); varRhoI->put(dRhoI, 1, 1, param.nPhiElements); } // Increment wave index iWave++; if (dLambdaI != 0.0) { iWave++; } } AnnounceEndBlock("Done"); AnnounceBanner(); } } catch(Exception & e) { Announce(e.ToString().c_str()); } }
int main(int argc, char** argv) { NcError error(NcError::silent_nonfatal); try { // Input filename std::string strInputFile; // Output mesh filename std::string strOutputFile; // Polynomial degree per element int nP = 2; // Parse the command line BeginCommandLine() CommandLineString(strInputFile, "in", ""); CommandLineString(strOutputFile, "out", ""); //CommandLineInt(nP, "np", 2); //CommandLineBool(fCGLL, "cgll"); ParseCommandLine(argc, argv); EndCommandLine(argv) // Check file names if (strInputFile == "") { std::cout << "ERROR: No input file specified" << std::endl; return (-1); } if (strOutputFile == "") { std::cout << "ERROR: No output file specified" << std::endl; return (-1); } if (nP < 1) { std::cout << "ERROR: --np must be >= 2" << std::endl; return (-1); } AnnounceBanner(); // Load input mesh AnnounceStartBlock("Loading input mesh"); Mesh meshIn(strInputFile); meshIn.RemoveZeroEdges(); AnnounceEndBlock("Done"); // Construct edge map AnnounceStartBlock("Constructing edge map"); meshIn.ConstructEdgeMap(); AnnounceEndBlock("Done"); // Build connectivity vector using edge map AnnounceStartBlock("Constructing connectivity"); std::vector< std::set<int> > vecConnectivity; int err = GenerateConnectivityData(meshIn, vecConnectivity); if (err) return err; AnnounceEndBlock("Done"); // Open output file AnnounceStartBlock("Writing connectivity file"); NcFile ncmesh(strInputFile.c_str(), NcFile::ReadOnly); NcVar * varLat = ncmesh.get_var("grid_center_lat"); NcVar * varLon = ncmesh.get_var("grid_center_lon"); // Check if center latitudes and longitudes are already available DataArray1D<double> dAllLats; DataArray1D<double> dAllLons; bool fConvertLatToDegrees = true; bool fConvertLonToDegrees = true; if ((varLat == NULL) || (varLon == NULL)) { Announce("grid_center_lat not found, recalculating face centers"); } else { Announce("grid_center_lat found in file, loading values"); if (varLat->get_dim(0)->size() != vecConnectivity.size()) { _EXCEPTIONT("grid_center_lat dimension mismatch"); } if (varLon->get_dim(0)->size() != vecConnectivity.size()) { _EXCEPTIONT("grid_center_lon dimension mismatch"); } dAllLats.Allocate(vecConnectivity.size()); varLat->set_cur((long)0); varLat->get(dAllLats, vecConnectivity.size()); NcAtt * attLatUnits = varLat->get_att("units"); std::string strLatUnits = attLatUnits->as_string(0); if (strLatUnits == "degrees") { fConvertLatToDegrees = false; } dAllLons.Allocate(vecConnectivity.size()); varLon->set_cur((long)0); varLon->get(dAllLons, vecConnectivity.size()); NcAtt * attLonUnits = varLon->get_att("units"); std::string strLonUnits = attLonUnits->as_string(0); if (strLonUnits == "degrees") { fConvertLonToDegrees = false; } } // Write connectiivty file FILE * fp = fopen(strOutputFile.c_str(), "w"); fprintf(fp, "%lu\n", vecConnectivity.size()); for (size_t f = 0; f < vecConnectivity.size(); f++) { double dLon; double dLat; if ((varLat == NULL) || (varLon == NULL)) { Node nodeCentroid; for (int i = 0; i < meshIn.faces[f].edges.size(); i++) { nodeCentroid.x += meshIn.nodes[meshIn.faces[f][i]].x; nodeCentroid.y += meshIn.nodes[meshIn.faces[f][i]].y; nodeCentroid.z += meshIn.nodes[meshIn.faces[f][i]].z; } double dMagnitude = nodeCentroid.Magnitude(); nodeCentroid.x /= dMagnitude; nodeCentroid.y /= dMagnitude; nodeCentroid.z /= dMagnitude; dLon = atan2(nodeCentroid.y, nodeCentroid.x); dLat = asin(nodeCentroid.z); if (dLon < 0.0) { dLon += 2.0 * M_PI; } } else { dLon = dAllLons[f]; dLat = dAllLats[f]; } if (fConvertLonToDegrees) { dLon *= 180.0 / M_PI; } if (fConvertLatToDegrees) { dLat *= 180.0 / M_PI; } fprintf(fp, "%1.14f,", dLon); fprintf(fp, "%1.14f,", dLat); fprintf(fp, "%lu", vecConnectivity[f].size()); std::set<int>::const_iterator iter = vecConnectivity[f].begin(); for (; iter != vecConnectivity[f].end(); iter++) { fprintf(fp, ",%i", *iter); } if (f != vecConnectivity.size()-1) { fprintf(fp,"\n"); } } fclose(fp); AnnounceEndBlock("Done"); // Announce AnnounceBanner(); return (0); } catch(Exception & e) { Announce(e.ToString().c_str()); return (-1); } catch(...) { return (-2); } }
int SiteinInputer::getSiteinData(SiteIn* sid, const int & recid){ if (recid==-1) return -1; //CID not exists in sitein.nc, so back to calling NcFile siteFile(siteinfname.c_str(), NcFile::ReadOnly); NcVar* ysfV = siteFile.get_var("YSF"); if(ysfV==NULL){ cout <<"cannot get ysf\n"; } ysfV->set_cur(recid); ysfV->get(&sid->ysf, 1); NcVar* envlaiV = siteFile.get_var("LAI"); if(envlaiV==NULL){ cout <<"cannot get lai \n"; } envlaiV->set_cur(recid); envlaiV->get(sid->lai,1, 12); NcVar* vegcV = siteFile.get_var("VEGC"); if(vegcV==NULL){ cout <<"cannot get vegc \n"; } vegcV->set_cur(recid); vegcV->get(&sid->vegc, 1); NcVar* vegnV = siteFile.get_var("VEGN"); if(vegcV==NULL){ cout <<"cannot get vegn \n"; } vegnV->set_cur(recid); vegnV->get(&sid->vegn, 1); NcVar* mossthickV = siteFile.get_var("MOSSTHICK"); if(mossthickV==NULL){ cout <<"cannot get mossthick \n"; } mossthickV->set_cur(recid); mossthickV->get(&sid->mossthick, 1); NcVar* fibthickV = siteFile.get_var("FIBTHICK"); if(fibthickV==NULL){ cout <<"cannot get fibthick \n"; } fibthickV->set_cur(recid); fibthickV->get(&sid->fibthick, 1); NcVar* humthickV = siteFile.get_var("HUMTHICK"); if(humthickV==NULL){ cout <<"cannot get humthick \n"; } humthickV->set_cur(recid); humthickV->get(&sid->humthick, 1); NcVar* soilcV = siteFile.get_var("SOILC"); if(soilcV==NULL){ cout <<"cannot get soilc \n"; } soilcV->set_cur(recid); soilcV->get(&sid->soilc, 1); NcVar* fibcV = siteFile.get_var("FIBC"); if(fibcV==NULL){ cout <<"cannot get fibc \n"; } fibcV->set_cur(recid); fibcV->get(&sid->fibc, 1); NcVar* humcV = siteFile.get_var("HUMC"); if(humcV==NULL){ cout <<"cannot get humc \n"; } humcV->set_cur(recid); humcV->get(&sid->humc, 1); NcVar* mincV = siteFile.get_var("MINC"); if(mincV==NULL){ cout <<"cannot get minc \n"; } mincV->set_cur(recid); mincV->get(&sid->minc, 1); NcVar* orgnV = siteFile.get_var("ORGN"); if(orgnV==NULL){ cout <<"cannot get orgn \n"; } orgnV->set_cur(recid); orgnV->get(&sid->orgn, 1); NcVar* avlnV = siteFile.get_var("AVLN"); if(avlnV==NULL){ cout <<"cannot get avln \n"; } avlnV->set_cur(recid); avlnV->get(&sid->avln, 1); NcVar* mintypeV = siteFile.get_var("MINTYPE"); if(mintypeV==NULL){ cout <<"cannot get mineral type \n"; } mintypeV->set_cur(recid); mintypeV->get(sid->mintype, 1, MAX_MIN_LAY); NcVar* zoutV = siteFile.get_var("ZOUT"); if(zoutV==NULL){ cout <<"cannot get soil depth \n"; } zoutV->set_cur(recid); zoutV->get(sid->initz, 1, MAX_SOI_LAY); NcVar* stoutV = siteFile.get_var("STOUT"); if(stoutV==NULL){ cout <<"cannot get soil temperature \n"; } stoutV->set_cur(recid); stoutV->get(sid->initst, 1, MAX_SOI_LAY); NcVar* smoutV = siteFile.get_var("SMOUT"); if(smoutV==NULL){ cout <<"cannot get soil moisture \n"; } smoutV->set_cur(recid); smoutV->get(sid->initsm, 1, MAX_SOI_LAY); return 0; };
int main(int argc, const char* argv[]) { string fileName; int maxDataSavePts, boundHandlingMethod; double stoppingTol; if (argc == 8) { for (int i = 0; i < argc; i++) { if (argv[i][0] == '-') { switch(argv[i][1]) { case 'n': maxDataSavePts = atoi(argv[i+1]); i++; break; case 'e': stoppingTol = atof(argv[i+1]); i++; break; case 'b': boundHandlingMethod = atof(argv[i+1]); i++; break; } } else { fileName = argv[i]; } } } else { fprintf(stderr, "\nUsage: ./FilePrep <fileName> -n <maxDataSavePts> -e <stoppingTol> -b <boundHandlingMethod>\n"); fprintf(stderr, " <fileName> Name of the NetCDF file to be prepared for simulation.\n"); fprintf(stderr, " -n <maxDataSavePts> Maximum number of initial states to be held in the file.\n"); fprintf(stderr, " -e <stoppingTol> Maximum allowable L2 distance between successive probability distributions.\n\n"); fprintf(stderr, " -b <boundHandlingMethod> 1 for deletion. 2 for resampling."); abort(); } NcFile file(fileName.c_str(), NcFile::Write); if (!file.is_valid()) { fprintf(stderr, "Error: %s could not be opened.\n", fileName.c_str()); abort(); } NcDim* dim = file.add_dim("maxDataSavePts", maxDataSavePts); NcVar* stoppingTolVar = file.add_var("stoppingTol", ncDouble); NcVar* numDataSavePtsVar = file.add_var("numDataSavePts", ncInt, file.get_dim("numMdls")); NcVar* boundHandlingMethodVar = file.add_var("boundHandlingMethod", ncInt, file.get_dim("numMdls")); file.add_var("numBoundedSpeciesStates", ncInt, file.get_dim("numMdls")); file.add_var("speciesStateBounded", ncInt, file.get_dim("numMdls"), file.get_dim("maxSpecies")); file.add_var("speciesStateLowerBounds", ncDouble, file.get_dim("numMdls"), file.get_dim("maxSpecies")); file.add_var("speciesStateUpperBounds", ncDouble, file.get_dim("numMdls"), file.get_dim("maxSpecies")); file.add_var("dataSavePts", ncInt, file.get_dim("numMdls"), dim); file.add_var("speciesStateChanges", ncInt, file.get_dim("numMdls"), file.get_dim("maxSpecies")); file.get_var("state")->rename("initFwdData"); file.add_var("initRevData", ncDouble, file.get_dim("numMdls"), file.get_dim("maxTrials"), file.get_dim("maxTimePts"), file.get_dim("maxSaveSpecies")); file.add_var("fwdData", ncDouble, file.get_dim("numMdls"), dim, file.get_dim("maxTrials"), file.get_dim("maxTimePts"), file.get_dim("maxSaveSpecies")); file.add_var("revData", ncDouble, file.get_dim("numMdls"), dim, file.get_dim("maxTrials"), file.get_dim("maxTimePts"), file.get_dim("maxSaveSpecies")); file.add_var("initFwdAbsCurr", ncInt, file.get_dim("numMdls"), file.get_dim("maxTimePts"), file.get_dim("maxSaveSpecies")); file.add_var("initRevAbsCurr", ncInt, file.get_dim("numMdls"), file.get_dim("maxTimePts"), file.get_dim("maxSaveSpecies")); file.add_var("fwdAbsCurr", ncInt, file.get_dim("numMdls"), dim, file.get_dim("maxTimePts"), file.get_dim("maxSaveSpecies")); file.add_var("revAbsCurr", ncInt, file.get_dim("numMdls"), dim, file.get_dim("maxTimePts"), file.get_dim("maxSaveSpecies")); stoppingTolVar->put(&stoppingTol, 1); int numMdls = (int) file.get_dim("numMdls")->size(); for (int i = 0; i < numMdls; i++) { numDataSavePtsVar->set_cur(i); numDataSavePtsVar->put(&maxDataSavePts, 1); } boundHandlingMethodVar->put(&boundHandlingMethod, 1); }
void gen(const char* path, NcFile::FileFormat format) // Generate a netCDF file { NcFile nc(path, NcFile::Replace, NULL, 0, format); // Create, leave in define mode // Check if the file was opened successfully if (! nc.is_valid()) { cerr << "can't create netCDF file " << path << "\n"; return; } // Create dimensions const int NLATS = 4; const int NLONS = 3; const int NFRTIMES = 2; const int TIMESTRINGLEN = 20; NcDim* latd = nc.add_dim("lat", NLATS); NcDim* lond = nc.add_dim("lon", NLONS); NcDim* frtimed = nc.add_dim("frtime"); // unlimited dimension NcDim* timelend = nc.add_dim("timelen", TIMESTRINGLEN); // Create variables and their attributes NcVar* P = nc.add_var("P", ncFloat, frtimed, latd, lond); P->add_att("long_name", "pressure at maximum wind"); P->add_att("units", "hectopascals"); static float range[] = {0., 1500.}; P->add_att("valid_range", 2, range); P->add_att("_FillValue", -9999.0f); NcVar* lat = nc.add_var("lat", ncFloat, latd); lat->add_att("long_name", "latitude"); lat->add_att("units", "degrees_north"); NcVar* lon = nc.add_var("lon", ncFloat, lond); lon->add_att("long_name", "longitude"); lon->add_att("units", "degrees_east"); NcVar* frtime = nc.add_var("frtime", ncLong, frtimed); frtime->add_att("long_name", "forecast time"); frtime->add_att("units", "hours"); NcVar* reftime = nc.add_var("reftime",ncChar,timelend); reftime->add_att("long_name", "reference time"); reftime->add_att("units", "text_time"); NcVar* scalar = nc.add_var("scalarv", ncInt); scalar->add_att("scalar_att", 1); // Global attributes nc.add_att("history", "created by Unidata LDM from NPS broadcast"); nc.add_att("title", "NMC Global Product Set: Pressure at Maximum Wind"); // Start writing data, implictly leaves define mode static float lats[NLATS] = {-90, -87.5, -85, -82.5}; lat->put(lats, NLATS); static float lons[NLONS] = {-180, -175, -170}; lon->put(lons, NLONS); static int frtimes[NFRTIMES] = {12, 18}; frtime->put(frtimes, NFRTIMES); static const char* s = "1992-3-21 12:00" ; reftime->put(s, strlen(s)); static float P_data[2][4][3] = { {{950, 951, 952}, {953, 954, 955}, {956, 957, 958}, {959, 960, 961}}, {{962, 963, 964}, {965, 966, 967}, {968, 969, 970}, {971, 972, 973}} }; // We could write all P data at once with P->put(&P_data[0][0][0], P->edges()), // but instead we write one record at a time, to show use of setcur(). long rec = 0; // start at zero-th const long nrecs = 1; // # records to write P->put(&P_data[0][0][0], nrecs, NLATS, NLONS); // write zero-th record P->set_cur(++rec); // set to next record P->put(&P_data[1][0][0], nrecs, NLATS, NLONS); // write next record // close of nc takes place in destructor }
int main(int argc, char ** argv) { MPI_Init(&argc, &argv); try { // Number of latitudes int nLat; // Number of longitudes int nLon; // Zonal wavenumber int nK; // Meridional power int nLpow; // Output file std::string strOutputFile; // Parse the command line BeginCommandLine() CommandLineInt(nLat, "lat", 40); CommandLineInt(nLon, "lon", 80); CommandLineString(strOutputFile, "out", "topo.nc"); ParseCommandLine(argc, argv); EndCommandLine(argv) // Generate longitude and latitude arrays AnnounceBanner(); AnnounceStartBlock("Generating longitude and latitude arrays"); DataVector<double> dLon; dLon.Initialize(nLon); Parameters param; param.GenerateLatituteArray(nLat); std::vector<double> & dLat = param.vecNode; double dDeltaLon = 2.0 * M_PI / static_cast<double>(nLon); for (int i = 0; i < nLon; i++) { dLon[i] = (static_cast<double>(i) + 0.5) * dDeltaLon; } AnnounceEndBlock("Done"); // Open NetCDF output file AnnounceStartBlock("Writing to file"); NcFile ncdf_out(strOutputFile.c_str(), NcFile::Replace); // Output coordinates NcDim * dimLat = ncdf_out.add_dim("lat", nLat); NcDim * dimLon = ncdf_out.add_dim("lon", nLon); NcVar * varLat = ncdf_out.add_var("lat", ncDouble, dimLat); varLat->set_cur((long)0); varLat->put(&(param.vecNode[0]), nLat); NcVar * varLon = ncdf_out.add_var("lon", ncDouble, dimLon); varLon->set_cur((long)0); varLon->put(&(dLon[0]), nLon); // Generate topography DataMatrix<double> dTopo; dTopo.Initialize(nLat, nLon); double dK = static_cast<double>(nK); double dLpow = static_cast<double>(nLpow); double dA = 6.37122e6; double dX = 500.0; double dLatM = 0.0; double dLonM = M_PI / 4.0; double dD = 5000.0; double dH0 = 1.0; double dXiM = 4000.0; for (int j = 0; j < nLat; j++) { for (int i = 0; i < nLon; i++) { // Great circle distance double dR = dA / dX * acos(sin(dLatM) * sin(dLat[j]) + cos(dLatM) * cos(dLat[j]) * cos(dLon[i] - dLonM)); double dCosXi = 1.0; //cos(M_PI * dR / dXiM); dTopo[j][i] = dH0 * exp(- dR * dR / (dD * dD)) * dCosXi * dCosXi; } } // Write topography NcVar * varZs = ncdf_out.add_var("Zs", ncDouble, dimLat, dimLon); varZs->set_cur(0, 0); varZs->put(&(dTopo[0][0]), nLat, nLon); AnnounceEndBlock("Done"); Announce("Completed successfully!"); AnnounceBanner(); } catch(Exception & e) { Announce(e.ToString().c_str()); } MPI_Finalize(); }
void FileArome::writeCore(std::vector<Variable::Type> iVariables) { writeTimes(); writeReferenceTime(); writeGlobalAttributes(); for(int v = 0; v < iVariables.size(); v++) { Variable::Type varType = iVariables[v]; std::string variable = getVariableName(varType); NcVar* var; if(hasVariableCore(varType)) { var = getVar(variable); } else { // Create variable if(0) { NcDim* dTime = getDim("time"); NcDim* dSurface = getDim("height0"); NcDim* dLon = getDim("x"); NcDim* dLat = getDim("y"); var = mFile.add_var(variable.c_str(), ncFloat, dTime, dSurface, dLat, dLon); } else { NcDim* dTime = getDim("time"); NcDim* dLon = getDim("x"); NcDim* dLat = getDim("y"); var = mFile.add_var(variable.c_str(), ncFloat, dTime, dLat, dLon); } } float MV = getMissingValue(var); // The output file's missing value indicator for(int t = 0; t < mNTime; t++) { float offset = getOffset(var); float scale = getScale(var); FieldPtr field = getField(varType, t); if(field != NULL) { // TODO: Can't be null if coming from reference float* values = new float[mNLat*mNLon]; int index = 0; for(int lat = 0; lat < mNLat; lat++) { for(int lon = 0; lon < mNLon; lon++) { float value = (*field)(lat,lon,0); if(!Util::isValid(value)) { // Field has missing value indicator and the value is missing // Save values using the file's missing indicator value value = MV; } else { value = ((*field)(lat,lon,0) - offset)/scale; } values[index] = value; index++; } } int numDims = var->num_dims(); if(numDims == 4) { var->set_cur(t, 0, 0, 0); var->put(values, 1, 1, mNLat, mNLon); } else if(numDims == 3) { var->set_cur(t, 0, 0); var->put(values, 1, mNLat, mNLon); } else { std::stringstream ss; ss << "Cannot write variable '" << variable << "' from '" << getFilename() << "'"; Util::error(ss.str()); } setAttribute(var, "coordinates", "longitude latitude"); setAttribute(var, "units", Variable::getUnits(varType)); setAttribute(var, "standard_name", Variable::getStandardName(varType)); delete[] values; } } setMissingValue(var, MV); } }