void PointCounter::output(const string &fileName) const { NcFile file(fileName.c_str(), NcFile::Replace); if (!file.is_valid()) { string message = "Failed to open file "+fileName+"."; REPORT_ERROR(message.c_str()); } NcDim *numLonDim = file.add_dim("lon", counters.extent(0)); NcDim *numLatDim = file.add_dim("lat", counters.extent(1)); NcDim *numBndsDim = file.add_dim("bnds", 2); //NcDim *numLevDim = file.add_dim("lev", counters.extent(2)); NcVar *lonBndsVar = file.add_var("lon_bnds", ncDouble, numLonDim, numBndsDim); NcVar *latBndsVar = file.add_var("lat_bnds", ncDouble, numLatDim, numBndsDim); //NcVar *levVar = file.add_var("lev", ncDouble, numLevDim); lonBndsVar->add_att("long_name", "longitude bounds"); lonBndsVar->add_att("units", "degree_east"); latBndsVar->add_att("long_name", "latitude bounds"); latBndsVar->add_att("units", "degree_north"); int numLonBnds = mesh[0].getNumLon()-2, numLatBnds = mesh[0].getNumLat()-1; double lonBnds[numLonBnds][2], latBnds[numLatBnds][2]; for (int i = 0; i < numLonBnds; ++i) { lonBnds[i][0] = mesh[0].lon(i)*Rad2Deg; lonBnds[i][1] = mesh[0].lon(i+1)*Rad2Deg; } for (int j = 0; j < numLatBnds; ++j) { latBnds[j][0] = mesh[0].lat(j)*Rad2Deg; latBnds[j][1] = mesh[0].lat(j+1)*Rad2Deg; } lonBndsVar->put(&lonBnds[0][0], numLonBnds, 2); latBndsVar->put(&latBnds[0][0], numLatBnds, 2); NcVar *countersVar = file.add_var("counters", ncInt, numLatDim, numLonDim); countersVar->add_att("long_name", "contained point numbers in grid boxes"); int counters[this->counters.extent(1)][this->counters.extent(0)]; for (int j = 0; j < this->counters.extent(1); ++j) for (int i = 0; i < this->counters.extent(0); ++i) counters[j][i] = this->counters(i, j, 0); countersVar->put(&counters[0][0], this->counters.extent(1), this->counters.extent(0)); }
void RLLMesh::output(const string &fileName) const { NcFile file(fileName.c_str(), NcFile::Replace); if (!file.is_valid()) { Message message; message << "Failed to create point counter mesh file \""; message << fileName << "\"!"; REPORT_ERROR(message.str()); } NcDim *lonDim = file.add_dim("lon", lon.size()); NcDim *latDim = file.add_dim("lat", lat.size()); NcVar *lonVar = file.add_var("lon", ncDouble, lonDim); NcVar *latVar = file.add_var("lat", ncDouble, latDim); double lonTmp[lon.size()], latTmp[lat.size()]; for (int i = 0; i < lon.size(); ++i) lonTmp[i] = lon(i)*Rad2Deg; for (int j = 0; j < lat.size(); ++j) latTmp[j] = lat(j)*Rad2Deg; lonVar->put(lonTmp, lon.size()); latVar->put(latTmp, lat.size()); file.close(); }
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; @}
int TestSuite::testVar() { try { string FILE_NAME = "tst_vars.nc"; int NDIMS = 4; int NLAT = 6; int NLON = 12; // Names of things. string LAT_NAME = "latitude"; string LON_NAME = "longitude"; int MAX_ATT_LEN = 80; // These are used to construct some example data. float START_LAT = 25.0; float START_LON = -125.0; string UNITS = "units"; string DEGREES_EAST = "degrees_east"; string DEGREES_NORTH = "degrees_north"; // For the units attributes. string LAT_UNITS = "degrees_north"; string LON_UNITS = "degrees_east"; // Return this code to the OS in case of failure. #define NC_ERR 2 // We will write latitude and longitude fields. float lats[NLAT],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; // Create the file. NcFile test(FILE_NAME, NcFile::Replace); // Define the dimensions. NetCDF will hand back an ncDim object for // each. NcDim* latDim = test.addDim(LAT_NAME, NLAT); NcDim* lonDim = test.addDim(LON_NAME, NLON); // Define the coordinate variables. NcVar* latVar = test.addVar(LAT_NAME, ncFloat, latDim); NcVar* lonVar = test.addVar(LON_NAME, ncFloat, lonDim); // Define units attributes for coordinate vars. This attaches a // text attribute to each of the coordinate variables, containing // the units. latVar->addAtt(UNITS,ncString, DEGREES_NORTH); lonVar->addAtt(UNITS,ncString, DEGREES_EAST); // Write the coordinate variable data to the file. latVar->put(lats, NLAT); lonVar->put(lons, NLON); NcValues *latVals = latVar->getValues(); cout<<"toString returns lats: "<<latVals->toString()<<endl; cout<<"toChar returns "<<latVals->toChar(1)<<endl; cout<<"toShort returns "<<latVals->toShort(1)<<endl; cout<<"toInt returns "<<latVals->toInt(1)<<endl; cout<<"toLong returns "<<latVals->toLong(1)<<endl; latVals->print(cout); NcValues *lonVals = lonVar->getValues(); cout<<"toString returns lats: "<<lonVals->toString()<<endl; lonVals->print(cout); cout<<"no segmentation fault thus far"<<endl; //test varaibles here } catch(NcException e) { e.what(); return 1; } try { cout<<"should test adding a variable with more than 5 dimensions here"<<endl; // test creating a variable with more than 5 dimensions } catch (NcException e) { e.what(); return 1; } try //write the file with float's b/c that's all NcValues can handle at the moment { int NX = 6; int NY = 12; float 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; // The default behavior of the C++ API is to throw an exception i // an error occurs. A try catch block in necessary. // Create the file. The Replace parameter tells netCDF to overwrite // this file, if it already exists. string filename ="simples_xy.nc"; NcFile dataFile(filename, NcFile::Replace); // When we create netCDF dimensions, we get back a pointer to an // NcDim for each one. NcDim* xDim = dataFile.addDim("x", NX); NcDim* yDim = dataFile.addDim("y", NY); // Define the variable. The type of the variable in this case is // ncInt (32-bit integer). NcVar *data = dataFile.addVar("data", ncFloat, 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,0,0,0); // 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 simples_xy.nc!" << endl; } catch(std::exception e) {e.what();} try { int NX = 6; int NY = 12; // Return this in event of a problem. // int NC_ERR = 2; // This is the array we will read. float dataIn[NX][NY]; // Open the file. The ReadOnly parameter tells netCDF we want // read-only access to the file. NcFile dataFile("simples_xy.nc", NcFile::ReadOnly); // Retrieve the variable named "data" NcVar *data = dataFile.getVar("data"); //call getType on 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 1; NcValues* dataVar= data->getValues(); cout<<dataVar->toString()<<endl;; dataVar->print(cout); } catch(NcException e) { e.what(); return 1; } cout<<"***************** Testing Variables was successful *****************"<<endl; return 0; }
int TestSuite::testFile(string fName, NcFile::FileMode fMode) { string UNITS = "UNITS:"; cout<<"*** Testing tst_file in tst_suite "; int NLAT = 6; int NLON = 12; int NDIMS = 4; int NLVL = 2; int NREC = 2; /* These are used to construct some example data. */ int SAMPLE_PRESSURE = 900; float SAMPLE_TEMP = 9.0; float START_LAT = 25.0; float START_LON = -125.0; /* We will write surface temperature and pressure fields. */ float pres_out[NLAT][NLON]; float pres_in[NLAT][NLON]; float temp_out[NLAT][NLON]; float temp_in[NLAT][NLON]; float lats[NLAT], lons[NLON],lats_in[NLAT],lons_in[NLON]; std::string chararray []={"I"," hope"," this"," is"," stored "," properly" }; std::string chararray_in[NLAT]; int outInts[NLAT],outInts_in[NLAT]; /* It's good practice for each netCDF variable to carry a "units" * attribute. */ char pres_units[] = "hPa"; char temp_units[] = "celsius"; /* Loop indexes. */ int lat, lon; /* Create some pretend data. If this wasn't an example program, we * would have some real data to write, for example, model * output. */ for (lat = 0; lat < NLAT; lat++) { lats[lat] = START_LAT + 5.*lat; } for(lat = 0; lat < NLAT; lat++) { outInts[lat]= 450; } for (lon = 0; lon < NLON; lon++) { lons[lon] = START_LON + 5.*lon; } for (lat = 0; lat < NLAT; lat++) { for (lon = 0; lon < NLON; lon++) { pres_out[lat][lon] = SAMPLE_PRESSURE + (lon * NLAT + lat); temp_out[lat][lon] = SAMPLE_TEMP + .25 * (lon * NLAT + lat); } } // nc_set_log_level(3); try { NcFile f("tst_file.nc",NcFile::Replace); NcGroup *root = f.getRootGroup(); NcDim *latDim = root->addDim(string("lat"),NLAT); NcDim *lonDim = root->addDim(string("lon"),NLON); NcVar *latVar = root->addVar(string("latVar"),ncDouble,latDim); NcVar *lonVar = root->addVar(string("lonVar"),ncFloat,lonDim); NcVar *outIntsVar = root->addVar(string("outintsVar"),ncInt,latDim); NcVar *charArrVar = root->addVar(string("CharArray"),ncString,latDim); latVar->addAtt(string(UNITS),ncChar,string("degrees_north")); lonVar->addAtt(string(UNITS),ncChar,string("degrees_south")); outIntsVar->put(&outInts[0],NLAT,0,0,0,0); charArrVar->put(&chararray[0],NLAT,0,0,0,0); latVar->put(&lats[0],NLAT,0,0,0,0); lonVar->put(&lons[0],NLON,0,0,0,0); NcVar *presVar = root->addVar(string("press"),ncFloat,latDim,lonDim); NcVar *tempVar = root->addVar(string("temp"),ncFloat,latDim,lonDim); presVar->addAtt(string("UNITS:"),ncChar,string(pres_units)); tempVar->addAtt(string("UNITS:"),ncChar,string(temp_units)); presVar->put(&pres_out[0][0],NLAT,NLON,0,0,0); tempVar->put(&temp_out[0][0],NLAT,NLON,0,0,0); //NcValues *ncvalues = presVar->getValues(); { //another scope for variables NcGroup::varIterator variableItr; variableItr = root->beginVar(); while(variableItr != root->endVar()) { variableItr++; } NcVar::attIterator varAttItr; varAttItr = latVar->beginAtt(); while(varAttItr != latVar->endAtt()) { varAttItr++; } } } catch(NcException e) { cout<<"FAILURE***"<<endl; e.what(); return 1; } try { NcFile f1("tst_file.nc",NcFile::ReadOnly); NcGroup * root =f1.getRootGroup(); NcGroup::dimIterator dimItr; //get an iterator to move over the dimensions dimItr = root->beginDim(); //created in the file while(dimItr != root->endDim()) dimItr++; NcGroup::attIterator attItr; attItr= root->beginAtt(); while(attItr !=root->endAtt()) attItr++; NcGroup::varIterator variableItr; NcVar::attIterator varAttItr; variableItr = root->beginVar(); while(variableItr != root->endVar()) { varAttItr = variableItr->beginAtt(); while(varAttItr != variableItr->endAtt()) varAttItr++; variableItr++; } } catch(NcException e) { cout<<"FAILURE***"<<endl; e.what(); return 1; } cout<<" OK***"<<endl; return 0; }
void PolygonManager::output(const string &fileName) { // ------------------------------------------------------------------------- NcFile file(fileName.c_str(), NcFile::Replace); if (!file.is_valid()) { string message = "Failed to open file "+fileName+"."; REPORT_ERROR(message.c_str()); } // ------------------------------------------------------------------------- // time information if (TimeManager::onLine()) { file.add_att("time", TimeManager::getSeconds()); file.add_att("time_step", TimeManager::getTimeStep()); file.add_att("steps", TimeManager::getSteps()); } // ------------------------------------------------------------------------- // dimensions NcDim *numVertexDim = file.add_dim("num_total_vertex", vertices.size()); NcDim *numEdgeDim = file.add_dim("num_total_edge", edges.size()); NcDim *numPolygonDim = file.add_dim("num_total_polygon", polygons.size()); // ------------------------------------------------------------------------- // vertices part NcVar *oldVtxLonVar = file.add_var("old_vertex_lon", ncDouble, numVertexDim); NcVar *oldVtxLatVar = file.add_var("old_vertex_lat", ncDouble, numVertexDim); NcVar *newVtxLonVar = file.add_var("new_vertex_lon", ncDouble, numVertexDim); NcVar *newVtxLatVar = file.add_var("new_vertex_lat", ncDouble, numVertexDim); oldVtxLonVar->add_att("long_name", "old vertex longitude"); oldVtxLonVar->add_att("units", "degree_east"); oldVtxLatVar->add_att("long_name", "old vertex latitude"); oldVtxLatVar->add_att("units", "degree_north"); newVtxLonVar->add_att("long_name", "new vertex longitude"); newVtxLonVar->add_att("units", "degree_east"); newVtxLatVar->add_att("long_name", "new vertex latitude"); newVtxLatVar->add_att("units", "degree_north"); double *oldVtxLon = new double[vertices.size()]; double *oldVtxLat = new double[vertices.size()]; double *newVtxLon = new double[vertices.size()]; double *newVtxLat = new double[vertices.size()]; Vertex *vertex = vertices.front(); for (int i = 0; i < vertices.size(); ++i) { oldVtxLon[i] = vertex->getCoordinate(OldTimeLevel).getLon()*Rad2Deg; oldVtxLat[i] = vertex->getCoordinate(OldTimeLevel).getLat()*Rad2Deg; newVtxLon[i] = vertex->getCoordinate(NewTimeLevel).getLon()*Rad2Deg; newVtxLat[i] = vertex->getCoordinate(NewTimeLevel).getLat()*Rad2Deg; vertex = vertex->next; } oldVtxLonVar->put(oldVtxLon, vertices.size()); oldVtxLatVar->put(oldVtxLat, vertices.size()); newVtxLonVar->put(newVtxLon, vertices.size()); newVtxLatVar->put(newVtxLat, vertices.size()); delete [] oldVtxLon; delete [] oldVtxLat; delete [] newVtxLon; delete [] newVtxLat; // ------------------------------------------------------------------------- // edges part NcVar *firstPointVar = file.add_var("first_point_idx", ncInt, numEdgeDim); NcVar *secondPointVar = file.add_var("second_point_idx", ncInt, numEdgeDim); firstPointVar->add_att("long_name", "first point index of edge"); secondPointVar->add_att("long_name", "second point index of edge"); int *idx1 = new int[edges.size()]; int *idx2 = new int[edges.size()]; Edge *edge = edges.front(); for (int i = 0; i < edges.size(); ++i) { idx1[i] = edge->getEndPoint(FirstPoint)->getID(); idx2[i] = edge->getEndPoint(SecondPoint)->getID(); edge = edge->next; } firstPointVar->put(idx1, edges.size()); secondPointVar->put(idx2, edges.size()); delete [] idx1; delete [] idx2; // test point NcVar *oldTestLonVar = file.add_var("old_testpoint_lon", ncDouble, numEdgeDim); NcVar *oldTestLatVar = file.add_var("old_testpoint_lat", ncDouble, numEdgeDim); NcVar *newTestLonVar = file.add_var("new_testpoint_lon", ncDouble, numEdgeDim); NcVar *newTestLatVar = file.add_var("new_testpoint_lat", ncDouble, numEdgeDim); oldTestLonVar->add_att("long_name", "old test point longitude"); oldTestLonVar->add_att("units", "degree_east"); oldTestLatVar->add_att("long_name", "old test point latitude"); oldTestLatVar->add_att("units", "degree_north"); newTestLonVar->add_att("long_name", "new test point longitude"); newTestLonVar->add_att("units", "degree_east"); newTestLatVar->add_att("long_name", "new test point latitude"); newTestLatVar->add_att("units", "degree_north"); #if defined TTS_ONLINE || PREPROCESS double *oldTestLon = new double[edges.size()]; double *oldTestLat = new double[edges.size()]; double *newTestLon = new double[edges.size()]; double *newTestLat = new double[edges.size()]; edge = edges.front(); for (int i = 0; i < edges.size(); ++i) { Vertex *testPoint = edge->getTestPoint(); oldTestLon[i] = testPoint->getCoordinate(OldTimeLevel).getLon()*Rad2Deg; oldTestLat[i] = testPoint->getCoordinate(OldTimeLevel).getLat()*Rad2Deg; newTestLon[i] = testPoint->getCoordinate(NewTimeLevel).getLon()*Rad2Deg; newTestLat[i] = testPoint->getCoordinate(NewTimeLevel).getLat()*Rad2Deg; edge = edge->next; } oldTestLonVar->put(oldTestLon, edges.size()); oldTestLatVar->put(oldTestLat, edges.size()); newTestLonVar->put(newTestLon, edges.size()); newTestLatVar->put(newTestLat, edges.size()); delete [] oldTestLon; delete [] oldTestLat; delete [] newTestLon; delete [] newTestLat; #endif // ------------------------------------------------------------------------- // polygons part NcVar *edgeNumVar = file.add_var("edge_num", ncInt, numPolygonDim); NcVar *areaVar = file.add_var("area", ncDouble, numPolygonDim); edgeNumVar->add_att("long_name", "edge number of polygon"); areaVar->add_att("long_name", "polygon area"); int edgeNum[polygons.size()]; double area[polygons.size()]; int counter = 0; Polygon *polygon = polygons.front(); for (int i = 0; i < polygons.size(); ++i) { edgeNum[i] = polygon->edgePointers.size(); area[i] = polygon->getArea(); counter += edgeNum[i]; polygon = polygon->next; } int numEdgeIdx = counter; NcDim *numEdgeIdxDim = file.add_dim("num_edge_idx", numEdgeIdx); NcVar *edgeIdxVar = file.add_var("edge_idx", ncInt, numEdgeIdxDim); NcVar *edgeOntVar = file.add_var("edge_ont", ncInt, numEdgeIdxDim); edgeIdxVar->add_att("long_name", "edge index of polygon"); edgeOntVar->add_att("long_name", "edge orientation of polygon"); int *edgeIdx = new int[counter]; int *edgeOnt = new int[counter]; counter = 0; polygon = polygons.front(); for (int i = 0; i < polygons.size(); ++i) { EdgePointer *edgePointer = polygon->edgePointers.front(); for (int j = 0; j < polygon->edgePointers.size(); ++j) { edgeIdx[counter] = edgePointer->edge->getID(); edgeOnt[counter] = edgePointer->orient; counter++; edgePointer = edgePointer->next; } polygon = polygon->next; } edgeNumVar->put(edgeNum, polygons.size()); areaVar->put(area, polygons.size()); edgeIdxVar->put(edgeIdx, numEdgeIdx); edgeOntVar->put(edgeOnt, numEdgeIdx); delete [] edgeIdx; delete [] edgeOnt; // ------------------------------------------------------------------------- file.close(); }
int main(int argc, char** argv) { NcError error(NcError::verbose_nonfatal); try { // Input file std::string strInputFile; // Input file list std::string strInputFileList; // Input file format std::string strInputFormat; // NetCDF file containing latitude and longitude arrays std::string strLatLonFile; // Output file (NetCDF) std::string strOutputFile; // Output variable name std::string strOutputVariable; // Column in which the longitude index appears int iLonIxCol; // Column in which the latitude index appears int iLatIxCol; // Begin latitude double dLatBegin; // End latitude double dLatEnd; // Begin longitude double dLonBegin; // End longitude double dLonEnd; // Number of latitudes in output int nLat; // Number of longitudes in output int nLon; // Parse the command line BeginCommandLine() CommandLineString(strInputFile, "in", ""); CommandLineString(strInputFileList, "inlist", ""); CommandLineStringD(strInputFormat, "in_format", "std", "(std|visit)"); CommandLineString(strOutputFile, "out", ""); CommandLineString(strOutputVariable, "outvar", "density"); CommandLineInt(iLonIxCol, "iloncol", 8); CommandLineInt(iLatIxCol, "ilatcol", 9); CommandLineDouble(dLatBegin, "lat_begin", -90.0); CommandLineDouble(dLatEnd, "lat_end", 90.0); CommandLineDouble(dLonBegin, "lon_begin", 0.0); CommandLineDouble(dLonEnd, "lon_end", 360.0); CommandLineInt(nLat, "nlat", 180); CommandLineInt(nLon, "nlon", 360); ParseCommandLine(argc, argv); EndCommandLine(argv) AnnounceBanner(); // Check input if ((strInputFile == "") && (strInputFileList == "")) { _EXCEPTIONT("No input file (--in) or (--inlist) specified"); } if ((strInputFile != "") && (strInputFileList != "")) { _EXCEPTIONT("Only one input file (--in) or (--inlist) allowed"); } if (strInputFormat != "std") { _EXCEPTIONT("UNIMPLEMENTED: Only \"--in_format std\" supported"); } // Check output if (strOutputFile == "") { _EXCEPTIONT("No output file (--out) specified"); } // Check output variable if (strOutputVariable == "") { _EXCEPTIONT("No output variable name (--outvar) specified"); } // Number of latitudes and longitudes if (nLat == 0) { _EXCEPTIONT("UNIMPLEMENTED: --nlat must be specified currently"); } if (nLon == 0) { _EXCEPTIONT("UNIMPLEMENTED: --nlon must be specified currently"); } // Input file list std::vector<std::string> vecInputFiles; if (strInputFile != "") { vecInputFiles.push_back(strInputFile); } if (strInputFileList != "") { GetInputFileList(strInputFileList, vecInputFiles); } int nFiles = vecInputFiles.size(); // Density DataMatrix<int> nCounts; nCounts.Initialize(nLat, nLon); // Loop through all files in list AnnounceStartBlock("Processing files"); std::string strBuffer; strBuffer.reserve(1024); for (int f = 0; f < nFiles; f++) { Announce("File \"%s\"", vecInputFiles[f].c_str()); FILE * fp = fopen(vecInputFiles[f].c_str(), "r"); if (fp == NULL) { _EXCEPTION1("Unable to open input file \"%s\"", vecInputFiles[f].c_str()); } for (;;) { // Read in the next line fgets(&(strBuffer[0]), 1024, fp); int nLength = strlen(&(strBuffer[0])); // Check for end of file if (feof(fp)) { break; } // Check for comment line if (strBuffer[0] == '#') { continue; } // Check for new storm if (strncmp(&(strBuffer[0]), "start", 5) == 0) { continue; } // Parse line double dLon; double dLat; int iCol = 0; int iLast = 0; bool fWhitespace = true; for (int i = 0; i <= nLength; i++) { if ((strBuffer[i] == ' ') || (strBuffer[i] == ',') || (strBuffer[i] == '\t') || (strBuffer[i] == '\0') ) { if (!fWhitespace) { if (iCol == iLonIxCol) { strBuffer[i] = '\0'; dLon = atof(&(strBuffer[iLast])); } if (iCol == iLatIxCol) { strBuffer[i] = '\0'; dLat = atof(&(strBuffer[iLast])); } } fWhitespace = true; } else { if (fWhitespace) { iLast = i; iCol++; } fWhitespace = false; } } // Latitude and longitude index int iLon = static_cast<int>(static_cast<double>(nLon) * (dLon - dLonBegin) / (dLonEnd - dLonBegin)); int iLat = static_cast<int>(static_cast<double>(nLat) * (dLat - dLatBegin) / (dLatEnd - dLatBegin)); if (iLon == (-1)) { iLon = 0; } if (iLon == nLon) { iLon = nLon - 1; } if (iLat == (-1)) { iLat = 0; } if (iLat == nLat) { iLat = nLat - 1; } if ((iLat < 0) || (iLat >= nLat)) { _EXCEPTION1("Latitude index (%i) out of range", iLat); } if ((iLon < 0) || (iLon >= nLon)) { _EXCEPTION1("Longitude index (%i) out of range", iLon); } nCounts[iLat][iLon]++; } fclose(fp); } AnnounceEndBlock("Done"); // Output results AnnounceStartBlock("Output results"); // Load the netcdf output file NcFile ncOutput(strOutputFile.c_str(), NcFile::Replace); if (!ncOutput.is_valid()) { _EXCEPTION1("Unable to open output file \"%s\"", strOutputFile.c_str()); } // Create output NcDim * dimLat = ncOutput.add_dim("lat", nLat); NcDim * dimLon = ncOutput.add_dim("lon", nLon); NcVar * varLat = ncOutput.add_var("lat", ncDouble, dimLat); NcVar * varLon = ncOutput.add_var("lon", ncDouble, dimLon); varLat->add_att("units", "degrees_north"); varLon->add_att("units", "degrees_east"); DataVector<double> dLat(nLat); DataVector<double> dLon(nLon); for (int j = 0; j < nLat; j++) { dLat[j] = dLatBegin + (dLatEnd - dLatBegin) * (static_cast<double>(j) + 0.5) / static_cast<double>(nLat); } for (int i = 0; i < nLon; i++) { dLon[i] = dLonBegin + (dLonEnd - dLonBegin) * (static_cast<double>(i) + 0.5) / static_cast<double>(nLon); } varLat->put(&(dLat[0]), nLat); varLon->put(&(dLon[0]), nLon); // Output counts NcVar * varCount = ncOutput.add_var( strOutputVariable.c_str(), ncInt, dimLat, dimLon); varCount->put(&(nCounts[0][0]), nLat, nLon); ncOutput.close(); AnnounceEndBlock("Done"); AnnounceBanner(); } catch(Exception & e) { Announce(e.ToString().c_str()); } }
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(); }
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) { 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) { 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(); }
// // Creates NetCDF product // bool NetCDFProduct(MSG_header *PRO_head, MSG_data* PRO_data, int totalsegs, int *segsindexes, MSG_header *header, MSG_data *msgdat) { struct tm *tmtime; char NcName[1024]; char reftime[64]; char projname[16]; int wd, hg; int bpp; int ncal; float *cal; NcVar *ivar; NcVar *tvar; NcDim *tdim; NcDim *ldim; NcDim *cdim; NcDim *caldim; int npix = header[0].image_structure->number_of_columns; int nlin = header[0].image_structure->number_of_lines; size_t npixperseg = npix*nlin; size_t total_size = totalsegs*npixperseg; MSG_SAMPLE *pixels = new MSG_SAMPLE[total_size]; memset(pixels, 0, total_size*sizeof(MSG_SAMPLE)); size_t pos = 0; for (int i = 0; i < totalsegs; i ++) { if (segsindexes[i] >= 0) memcpy(pixels+pos, msgdat[segsindexes[i]].image->data, npixperseg*sizeof(MSG_SAMPLE)); pos += npixperseg; } nlin = nlin*totalsegs; // Manage subarea if (is_subarea) { if (AreaLinStart < 0 || AreaLinStart > nlin - AreaNlin || AreaNlin > nlin - AreaLinStart) { std::cerr << "Wrong Subarea in lines...." << std::endl; throw; } if (AreaPixStart < 0 || AreaPixStart > npix - AreaNpix || AreaNpix > npix - AreaPixStart) { std::cerr << "Wrong Subarea in Pixels...." << std::endl; throw; } size_t newsize = AreaNpix * AreaNlin; MSG_SAMPLE *newpix = new MSG_SAMPLE[newsize]; memset(newpix, 0, newsize*sizeof(MSG_SAMPLE)); for (int i = 0; i < AreaNlin; i ++) memcpy(newpix + i * AreaNpix, pixels + (AreaLinStart + i) * npix + AreaPixStart, AreaNpix * sizeof(MSG_SAMPLE)); delete [ ] pixels; pixels = newpix; total_size = newsize; } else { AreaNpix = npix; AreaNlin = nlin; } tmtime = PRO_data->prologue->image_acquisition.PlannedAquisitionTime.TrueRepeatCycleStart.get_timestruct( ); t_enum_MSG_spacecraft spc = header[0].segment_id->spacecraft_id; uint_1 chn = header[0].segment_id->spectral_channel_id; float sublon = header[0].image_navigation->subsatellite_longitude; int cfac = header[0].image_navigation->column_scaling_factor; int lfac = header[0].image_navigation->line_scaling_factor; int coff = header[0].image_navigation->column_offset; int loff = header[0].image_navigation->line_offset; float sh = header[0].image_navigation->satellite_h; char *channelstring = strdup(MSG_channel_name(spc, chn).c_str( )); char *channel = chname(channelstring, strlen(channelstring) + 1); // Build up output NetCDF file name and open it sprintf( NcName, "%s_%4d%02d%02d_%02d%02d.nc", channel, tmtime->tm_year + 1900, tmtime->tm_mon + 1, tmtime->tm_mday, tmtime->tm_hour, tmtime->tm_min ); NcFile ncf ( NcName , NcFile::Replace ); if (! ncf.is_valid()) return false; // Fill arrays on creation ncf.set_fill(NcFile::Fill); // Add Global Attributes if (! ncf.add_att("Satellite", MSG_spacecraft_name(spc).c_str())) return false; sprintf(reftime, "%04d-%02d-%02d %02d:%02d:00 UTC", tmtime->tm_year + 1900, tmtime->tm_mon + 1, tmtime->tm_mday, tmtime->tm_hour, tmtime->tm_min); if (! ncf.add_att("Antenna", "Fixed") ) return false; if (! ncf.add_att("Receiver", "HIMET") ) return false; if (! ncf.add_att("Time", reftime) ) return false; if (! ncf.add_att("Area_Name", "SpaceView" ) ) return false; sprintf(projname, "GEOS(%3.1f)", sublon); if (! ncf.add_att("Projection", projname) ) return false; if (! ncf.add_att("Columns", AreaNpix ) ) return false; if (! ncf.add_att("Lines", AreaNlin ) ) return false; if (! ncf.add_att("SampleX", 1.0 ) ) return false; if (! ncf.add_att("SampleY", 1.0 ) ) return false; if (! ncf.add_att("AreaStartPix", AreaPixStart ) ) return false; if (! ncf.add_att("AreaStartLin", AreaLinStart ) ) return false; if (! ncf.add_att("Column_Scale_Factor", cfac) ) return false; if (! ncf.add_att("Line_Scale_Factor", lfac) ) return false; if (! ncf.add_att("Column_Offset", coff) ) return false; if (! ncf.add_att("Line_Offset", loff) ) return false; if (! ncf.add_att("Orbit_Radius", sh) ) return false; if (! ncf.add_att("Longitude", sublon) ) return false; if (! ncf.add_att("NortPolar", 1) ) return false; if (! ncf.add_att("NorthSouth", 1) ) return false; if (! ncf.add_att("title", TITLE) ) return false; if (! ncf.add_att("Institution", INSTITUTION) ) return false; if (! ncf.add_att("Type", TYPE) ) return false; if (! ncf.add_att("Version", HIMET_VERSION) ) return false; if (! ncf.add_att("Conventions", "COARDS") ) return false; if (! ncf.add_att("history", "Created from raw data") ) return false; // Dimensions wd = AreaNpix; hg = AreaNlin; bpp = header[0].image_structure->number_of_bits_per_pixel; ncal = (int) pow(2.0, bpp); tdim = ncf.add_dim("time"); if (!tdim->is_valid()) return false; ldim = ncf.add_dim("line", hg); if (!ldim->is_valid()) return false; cdim = ncf.add_dim("column", wd); if (!cdim->is_valid()) return false; caldim = ncf.add_dim("calibration", ncal); if (!caldim->is_valid()) return false; // Get calibration values cal = PRO_data->prologue->radiometric_proc.get_calibration((int) chn, bpp); // Add Calibration values NcVar *cvar = ncf.add_var("calibration", ncFloat, caldim); if (!cvar->is_valid()) return false; cvar->add_att("long_name", "Calibration coefficients"); cvar->add_att("variable", channel); if (chn > 3 && chn < 12) cvar->add_att("units", "K"); else cvar->add_att("units", "mW m^-2 sr^-1 (cm^-1)^-1"); if (!cvar->put(cal, ncal)) return false; tvar = ncf.add_var("time", ncDouble, tdim); if (!tvar->is_valid()) return false; tvar->add_att("long_name", "Time"); tvar->add_att("units", "seconds since 2000-01-01 00:00:00 UTC"); double atime; time_t ttime; extern long timezone; ttime = mktime(tmtime); atime = ttime - 946684800 - timezone; if (!tvar->put(&atime, 1)) return false; ivar = ncf.add_var(channel, ncShort, tdim, ldim, cdim); if (!ivar->is_valid()) return false; if (!ivar->add_att("add_offset", 0.0)) return false; if (!ivar->add_att("scale_factor", 1.0)) return false; if (!ivar->add_att("chnum", chn)) return false; // Write output values if (!ivar->put((const short int *) pixels, 1, hg, wd)) return false; // Close NetCDF output (void) ncf.close( ); delete [ ] pixels; delete [ ] cal; return( true ); }
void TracerManager::output(const string &fileName) { // ------------------------------------------------------------------------- // output polygon stuffs polygonManager.output(fileName); #ifdef TTS_REMAP // ------------------------------------------------------------------------- NcFile file(fileName.c_str(), NcFile::Write); if (!file.is_valid()) { Message message; message << "Failed to open tracer output file \""; message << fileName << "\" for appending meshed density field!"; REPORT_ERROR(message.str()); } // ------------------------------------------------------------------------- // output tracer densities on the polygons NcDim *numPolygonDim = file.get_dim("num_total_polygon"); double q0[polygonManager.polygons.size()]; for (int l = 0; l < tracerNames.size(); ++l) { char varName[30]; sprintf(varName, "q%d", l); NcVar *qVar = file.add_var(varName, ncDouble, numPolygonDim); Polygon *polygon = polygonManager.polygons.front(); for (int i = 0; i < polygonManager.polygons.size(); ++i) { q0[i] = polygon->tracers[l].getDensity(); polygon = polygon->next; } qVar->put(q0, polygonManager.polygons.size()); } // ------------------------------------------------------------------------- // output tracer densities on the mesh const RLLMesh &mesh = tracerDensities[0].getMesh(); int numLon = mesh.getNumLon()-2; int numLat = mesh.getNumLat(); double lon[numLon], lat[numLat]; for (int i = 0; i < numLon; ++i) lon[i] = mesh.lon(i+1)*Rad2Deg; for (int j = 0; j < numLat; ++j) lat[j] = mesh.lat(j)*Rad2Deg; NcDim *lonDim = file.add_dim("lon", numLon); NcDim *latDim = file.add_dim("lat", numLat); NcVar *lonVar = file.add_var("lon", ncDouble, lonDim); lonVar->add_att("long_name", "longitude"); lonVar->add_att("units", "degrees_east"); lonVar->put(lon, numLon); NcVar *latVar = file.add_var("lat", ncDouble, latDim); latVar->add_att("long_name", "latitude"); latVar->add_att("units", "degrees_north"); latVar->put(lat, numLat); NcVar *areaVar = file.add_var("area_mesh", ncDouble, latDim, lonDim); areaVar->add_att("long_name", "area of fixed mesh cell"); areaVar->add_att("units", "m2"); double area[numLat][numLon]; for (int i = 0; i < numLon; ++i) for (int j = 0; j < numLat; ++j) area[j][i] = tracerDensities[0].getMesh(Field::Bound).area(i, j); areaVar->put(&area[0][0], numLat, numLon); double q[numLat][numLon]; for (int l = 0; l < tracerNames.size(); ++l) { char varName[30]; sprintf(varName, "q%d_mesh", l); NcVar *qVar = file.add_var(varName, ncDouble, latDim, lonDim); qVar->add_att("long_name", tracerNames[l].c_str()); for (int i = 0; i < numLon; ++i) for (int j = 0; j < numLat; ++j) q[j][i] = tracerDensities[l].values(i+1, j, 0).getNew(); qVar->put(&q[0][0], numLat, numLon); } // ------------------------------------------------------------------------- file.close(); #endif NOTICE("TracerManager", fileName+" is generated."); }
bool OutputManagerReference::OpenFile( const std::string & strFileName ) { #ifdef TEMPEST_NETCDF // Determine processor rank; only proceed if root node int nRank = 0; #ifdef TEMPEST_MPIOMP MPI_Comm_rank(MPI_COMM_WORLD, &nRank); #endif // The active model const Model & model = m_grid.GetModel(); // Open NetCDF file on root process if (nRank == 0) { // Check for existing NetCDF file if (m_pActiveNcOutput != NULL) { _EXCEPTIONT("NetCDF file already open"); } // Append .nc extension to file std::string strNcFileName = strFileName + ".nc"; // Open new NetCDF file m_pActiveNcOutput = new NcFile(strNcFileName.c_str(), NcFile::Replace); if (m_pActiveNcOutput == NULL) { _EXCEPTION1("Error opening NetCDF file \"%s\"", strNcFileName.c_str()); } if (!m_pActiveNcOutput->is_valid()) { _EXCEPTION1("Error opening NetCDF file \"%s\"", strNcFileName.c_str()); } // Create nodal time dimension NcDim * dimTime = m_pActiveNcOutput->add_dim("time"); if (dimTime == NULL) { _EXCEPTIONT("Error creating \"time\" dimension"); } m_varTime = m_pActiveNcOutput->add_var("time", ncDouble, dimTime); if (m_varTime == NULL) { _EXCEPTIONT("Error creating \"time\" variable"); } std::string strUnits = "days since " + model.GetStartTime().ToDateString(); std::string strCalendarName = model.GetStartTime().GetCalendarName(); m_varTime->add_att("long_name", "time"); m_varTime->add_att("units", strUnits.c_str()); m_varTime->add_att("calendar", strCalendarName.c_str()); m_varTime->add_att("bounds", "time_bnds"); // Create levels dimension NcDim * dimLev = m_pActiveNcOutput->add_dim("lev", m_dREtaCoord.GetRows()); // Create interfaces dimension NcDim * dimILev = m_pActiveNcOutput->add_dim("ilev", m_grid.GetRElements()+1); // Create latitude dimension NcDim * dimLat = m_pActiveNcOutput->add_dim("lat", m_nYReference); // Create longitude dimension NcDim * dimLon = m_pActiveNcOutput->add_dim("lon", m_nXReference); // Output physical constants const PhysicalConstants & phys = model.GetPhysicalConstants(); m_pActiveNcOutput->add_att("earth_radius", phys.GetEarthRadius()); m_pActiveNcOutput->add_att("g", phys.GetG()); m_pActiveNcOutput->add_att("omega", phys.GetOmega()); m_pActiveNcOutput->add_att("alpha", phys.GetAlpha()); m_pActiveNcOutput->add_att("Rd", phys.GetR()); m_pActiveNcOutput->add_att("Cp", phys.GetCp()); m_pActiveNcOutput->add_att("T0", phys.GetT0()); m_pActiveNcOutput->add_att("P0", phys.GetP0()); m_pActiveNcOutput->add_att("rho_water", phys.GetRhoWater()); m_pActiveNcOutput->add_att("Rvap", phys.GetRvap()); m_pActiveNcOutput->add_att("Mvap", phys.GetMvap()); m_pActiveNcOutput->add_att("Lvap", phys.GetLvap()); // Output grid parameters m_pActiveNcOutput->add_att("Ztop", m_grid.GetZtop()); // Output equation set const EquationSet & eqn = model.GetEquationSet(); m_pActiveNcOutput->add_att("equation_set", eqn.GetName().c_str()); // Create variables for (int c = 0; c < eqn.GetComponents(); c++) { if ((m_fOutputAllVarsOnNodes) || (m_grid.GetVarLocation(c) == DataLocation_Node) ) { m_vecComponentVar.push_back( m_pActiveNcOutput->add_var( eqn.GetComponentShortName(c).c_str(), ncDouble, dimTime, dimLev, dimLat, dimLon)); } else { m_vecComponentVar.push_back( m_pActiveNcOutput->add_var( eqn.GetComponentShortName(c).c_str(), ncDouble, dimTime, dimILev, dimLat, dimLon)); } } for (int c = 0; c < eqn.GetTracers(); c++) { m_vecTracersVar.push_back( m_pActiveNcOutput->add_var( eqn.GetTracerShortName(c).c_str(), ncDouble, dimTime, dimLev, dimLat, dimLon)); } // Vorticity variable if (m_fOutputVorticity) { m_varVorticity = m_pActiveNcOutput->add_var( "ZETA", ncDouble, dimTime, dimLev, dimLat, dimLon); } // Divergence variable if (m_fOutputDivergence) { m_varDivergence = m_pActiveNcOutput->add_var( "DELTA", ncDouble, dimTime, dimLev, dimLat, dimLon); } // Temperature variable if (m_fOutputTemperature) { m_varTemperature = m_pActiveNcOutput->add_var( "T", ncDouble, dimTime, dimLev, dimLat, dimLon); } // Surface pressure variable if (m_fOutputSurfacePressure) { m_varSurfacePressure = m_pActiveNcOutput->add_var( "PS", ncDouble, dimTime, dimLat, dimLon); } // Richardson number variable if (m_fOutputRichardson) { m_varRichardson = m_pActiveNcOutput->add_var( "Ri", ncDouble, dimTime, dimLev, dimLat, dimLon); } // User data variables const UserDataMeta & metaUserData = model.GetUserDataMeta(); m_vecUserData2DVar.resize(metaUserData.GetUserData2DItemCount()); for (int i = 0; i < metaUserData.GetUserData2DItemCount(); i++) { m_vecUserData2DVar[i] = m_pActiveNcOutput->add_var( metaUserData.GetUserData2DItemName(i).c_str(), ncDouble, dimTime, dimLat, dimLon); } // Output longitudes and latitudes NcVar * varLon = m_pActiveNcOutput->add_var("lon", ncDouble, dimLon); NcVar * varLat = m_pActiveNcOutput->add_var("lat", ncDouble, dimLat); varLon->put(m_dXCoord, m_dXCoord.GetRows()); varLat->put(m_dYCoord, m_dYCoord.GetRows()); varLon->add_att("long_name", "longitude"); varLon->add_att("units", "degrees_east"); varLat->add_att("long_name", "latitude"); varLat->add_att("units", "degrees_north"); // Output levels NcVar * varLev = m_pActiveNcOutput->add_var("lev", ncDouble, dimLev); varLev->put( m_dREtaCoord, m_dREtaCoord.GetRows()); varLev->add_att("long_name", "level"); varLev->add_att("units", "level"); // Output interface levels NcVar * varILev = m_pActiveNcOutput->add_var("ilev", ncDouble, dimILev); varILev->put( m_grid.GetREtaStretchInterfaces(), m_grid.GetREtaStretchInterfaces().GetRows()); varILev->add_att("long_name", "interface level"); varILev->add_att("units", "level"); // Topography variable m_varTopography = m_pActiveNcOutput->add_var("Zs", ncDouble, dimLat, dimLon); // Fresh output file m_fFreshOutputFile = true; } #ifdef TEMPEST_MPIOMP // Wait for all processes to complete MPI_Barrier(MPI_COMM_WORLD); #endif #endif return true; }
int TestSuite::testExamples() { #define FILE_NAME "pres_temp_4D.nc" // We are writing 4D data, a 2 x 6 x 12 lvl-lat-lon grid, with 2 // timesteps of data. #define NDIMS 4 #define NLVL 2 #define NLAT 6 #define NLON 12 #define NREC 2 // Names of things. #define LVL_NAME "level" #define LAT_NAME "latitude" #define LON_NAME "longitude" #define REC_NAME "time" #define PRES_NAME "pressure" #define TEMP_NAME "temperature" #define MAX_ATT_LEN 80 // These are used to construct some example data. #define SAMPLE_PRESSURE 900 #define SAMPLE_TEMP 9.0 #define START_LAT 25.0 #define START_LON -125.0 string UNITS = "units"; string DEGREES_EAST = "degrees_east"; string DEGREES_NORTH = "degrees_north"; // For the units attributes. string PRES_UNITS = "hPa"; string TEMP_UNITS = "celsius"; string LAT_UNITS = "degrees_north"; string LON_UNITS = "degrees_east"; // Return this code to the OS in case of failure. #define NC_ERR 2 // We will write latitude and longitude fields. float lats[NLAT],lons[NLON]; // Program variables to 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; //used in the data generation loop // 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++; } try { // Create the file. NcFile test(FILE_NAME, NcFile::Replace); // Define the dimensions. NetCDF will hand back an ncDim object for // each. NcDim* lvlDim = test.addDim(LVL_NAME, NLVL); NcDim* latDim = test.addDim(LAT_NAME, NLAT); NcDim* lonDim = test.addDim(LON_NAME, NLON); NcDim* recDim = test.addDim(REC_NAME); //adds an unlimited dimension // Define the coordinate variables. NcVar* latVar = test.addVar(LAT_NAME, ncFloat, latDim); NcVar* lonVar = test.addVar(LON_NAME, ncFloat, lonDim); // Define units attributes for coordinate vars. This attaches a // text attribute to each of the coordinate variables, containing // the units. latVar->addAtt(UNITS,ncChar, DEGREES_NORTH); lonVar->addAtt(UNITS,ncChar, DEGREES_EAST); // Define the netCDF variables for the pressure and temperature // data. NcVar* pressVar = test.addVar(PRES_NAME, ncFloat, recDim, lvlDim, latDim, lonDim); NcVar* tempVar = test.addVar(TEMP_NAME, ncFloat, recDim, lvlDim, latDim, lonDim); // Define units attributes for coordinate vars. This attaches a // text attribute to each of the coordinate variables, containing // the units. pressVar->addAtt(UNITS,ncChar, PRES_UNITS); tempVar->addAtt(UNITS,ncChar ,TEMP_UNITS); // Write the coordinate variable data to the file. latVar->put(lats, NLAT); lonVar->put(lons, NLON); // 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++) { pressVar->putRec(&pres_out[0][0][0], rec); tempVar->putRec(&temp_out[0][0][0], rec); } //NcValues * pressVals = pressVar->getValues(); //pressVals->print(cout); // 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 " << FILE_NAME << "!" << endl; } catch(NcException e) { e.what(); return 1; } return 0; }
void CCohortdriver::createSoilClimate(BgcData *bd, EnvData *ed, Vegetation_Env *ve, string& datadir){ string file = datadir+ "calirestart.nc"; NcFile* resFile = new NcFile(file.c_str(), NcFile::Replace); NcDim * chtD = resFile->add_dim("CHTID", 1); NcDim * monD = resFile->add_dim("MON", 12); NcDim * layD = resFile->add_dim("LAYER", MAX_SOI_LAY); NcVar* drgV = resFile->add_var("DRG",ncInt, chtD); NcVar* vegV = resFile->add_var("VEG",ncInt, chtD); NcVar* numslV = resFile->add_var("NUMSL",ncInt, chtD); NcVar* rsoilcV = resFile->add_var("RSOILC", ncDouble, layD); NcVar* nsoilcV = resFile->add_var("NSOILC", ncDouble, layD); NcVar* dzV = resFile->add_var("DZ", ncDouble, layD); NcVar* typeV = resFile->add_var("TYPE", ncDouble, layD); NcVar* poroV = resFile->add_var("PORO", ncDouble, layD); NcVar* rootfracV = resFile->add_var("ROOTFRAC", ncDouble, layD); NcVar* taV = resFile->add_var("TA",ncDouble, monD); NcVar* growV = resFile->add_var("GROW",ncDouble, monD); NcVar* co2V = resFile->add_var("CO2",ncDouble, monD); NcVar* petV = resFile->add_var("PET",ncDouble, monD); NcVar* eetV = resFile->add_var("EET",ncDouble, monD); NcVar* parV = resFile->add_var("PAR",ncDouble, monD); NcVar* envlaiV = resFile->add_var("ENVLAI",ncFloat, monD); NcVar* tsV = resFile->add_var("TS", ncDouble, monD, layD); NcVar* ch4V = resFile->add_var("CH4",ncDouble, monD, layD); NcVar* liqV = resFile->add_var("LIQ",ncDouble, monD, layD); NcVar* vwcV = resFile->add_var("VSM",ncDouble, monD, layD); NcVar* swsV = resFile->add_var("SWS",ncDouble, monD, layD); NcVar* iceV = resFile->add_var("ICE",ncDouble, monD, layD); NcVar* yreetV = resFile->add_var("YREET",ncDouble, chtD); NcVar* yrpetV = resFile->add_var("YRPET",ncDouble, chtD); NcVar* yrco2V = resFile->add_var("YRCO2",ncDouble, chtD); NcVar* prveetmxV = resFile->add_var("PRVEETMX",ncDouble, chtD); NcVar* prvpetmxV = resFile->add_var("PRVPETMX",ncDouble, chtD); numslV->put(&ed->m_soid.actual_num_soil, 1); drgV->put(&ed->cd->drgtype, 1); vegV->put(&ed->cd->vegtype, 1); poroV->put(&ed->m_sois.por[0], MAX_SOI_LAY); typeV->put(&ed->m_sois.type[0], MAX_SOI_LAY); dzV->put(&ed->m_sois.dz[0], MAX_SOI_LAY); rsoilcV->put(&bd->m_sois.reac[0], MAX_SOI_LAY); nsoilcV->put(&bd->m_sois.nonc[0], MAX_SOI_LAY); rootfracV->put(&ed->m_sois.rootfrac[0], MAX_SOI_LAY); tsV->put(&ed->eq_ts[0][0], 12, MAX_SOI_LAY); ch4V->put(&ed->eq_ch4[0][0], 12, MAX_SOI_LAY); liqV->put(&ed->eq_liq[0][0], 12, MAX_SOI_LAY); iceV->put(&ed->eq_ice[0][0], 12, MAX_SOI_LAY); vwcV->put(&ed->eq_vwc[0][0], 12, MAX_SOI_LAY); swsV->put(&ed->eq_sws[0][0], 12, MAX_SOI_LAY); taV->put(&ed->eq_ta[0], 12); petV->put(&ed->eq_pet[0], 12); eetV->put(&ed->eq_eet[0], 12); co2V->put(&ed->eq_co2[0], 12); parV->put(&ed->eq_par[0], 12); growV->put(&ed->eq_grow[0], 12); envlaiV->put(&ve->envlaiall[0], 12); yreetV->put(&ed->eq_y_eet, 1); yrpetV->put(&ed->eq_y_pet, 1); yrco2V->put(&ed->eq_y_co2, 1); prveetmxV->put(&ed->eq_prveetmx); prvpetmxV->put(&ed->eq_prvpetmx); resFile->close(); delete resFile; //Yuan: if not, memory leaking may occur // exit(0); };
int TestSuite::testTypes() { try { NcFile f("tst_types.nc",NcFile::Replace); NcEnumType *state; NcGroup * root; root = f.getRootGroup(); state =f.addEnumType("state"); state->addMember("sitting",10); state->addMember("standing",11); state->addMember("walking",12); state->addMember("running",13); enum estuff{sitting =10, standing =11, walking =12,running = 13}; estuff s; s = standing; NcVar *var = root->addVar("enumVar",state); var->put(&s);// how do I store and variable that is of enumaration type cout<<" done with enum stuff*****************************************************"<<endl; NcCompoundType *myStruct; struct s1 { int i1; int i2; }; myStruct = f.addCompoundType("basicCompoundType",sizeof(s1)); myStruct->addMember("i1",NC_INT); myStruct->addMember("i2",NC_INT); s1 tempStruct; tempStruct.i1= 23; tempStruct.i2= 15; NcVar *var1= root->addVar("basicCompoundVariable",myStruct); var1->put(&tempStruct); //var1->addAtt("basicCompoundAtt",myStruct,&tempStruct); cout<<"done with basic compound stuff *********************************************"<<endl; struct cs { s1 s; int j; string k; }; NcCompoundType * compStruct; compStruct= f.addCompoundType("mediumCompoundType",sizeof(cs)); compStruct->addMember("s",myStruct); compStruct->addMember("j",NC_INT); compStruct->addMember("k",NC_STRING); cs struct2; struct2.s = tempStruct; struct2.j =15; struct2.k = "it works"; NcVar *var2= root->addVar("mediumCompoundVariable",compStruct); var2->put(&struct2); cout<<"*******************done with medium compund stuff*******************"<<endl; struct cs3 { s1 a; s1 b; estuff k; int i; }; NcCompoundType *compStruct2 = f.addCompoundType("complexCompoundType",sizeof(cs3)); compStruct2->addMember("a",myStruct); compStruct2->addMember("b",myStruct); compStruct2->addMember("k",state); compStruct2->addMember("i",NC_INT); cs3 comps2v; comps2v.a = tempStruct; comps2v.b = tempStruct; comps2v.k = s; comps2v.i = 1985; NcVar *var3= root->addVar("complexCompoundVariable",compStruct2); var3->put(&comps2v); cout<<"*********************done with complex compound stuff***************************************"<<endl; cout<<"****************************now doing variable length stuff****************************"<<endl; nc_vlen_t data1[3]; int *phoney; /* Create phoney data. */ for (int i=0; i<3; i++) { if (!(phoney = new int[i+1])) return NC_ENOMEM; for (int j=0; j<i+1; j++) phoney[j] = -99; data1[i].p = phoney; data1[i].len = i+1; } NcVLenType *vlen; vlen=f.addVLenType("variableLengthType",ncInt); //NcVar *vlenVar = root->addVar("variableLengthVariable",vlen); string stuff = "hello world"; //vlenVar->addAtt("vlenatt",vlen,data1); cout<<"about to call put for variable vlenvar"<<endl; //vlenVar->put(&data1); cout<<"I just called put for the variable lenght data. I'm in the tst_...cpp file, hopefully it works"<<endl; cout<<"*********************now dealing with opaque stuff*************************"<<endl; unsigned char data[5][5]; for(int i = 0;i < 5; i++) { for(int j =0; j<5; j++) { data[i][j]= 'a'; } } NcOpaqueType *opaque; opaque = f.addOpaqueType("opaqueType",sizeof(data)); NcVar *ovar = root->addVar("opaqueVar",opaque); //ovar->put(&data); cout<<"********************done with opaque stuff ******************************"<<endl; } catch(NcException e) { e.what(); return 1; } try { cout<<"I'm going to try reading now"<<endl; NcFile f("tst_types.nc",NcFile::ReadOnly); cout<<"hopefully all the stuff has been read correctly"<<endl; } catch(NcException e) { e.what(); return 1; } return 0; }
void InputNetcdf::writeCore(const Data& iData, int iDate, int iInit, const std::vector<float>& iOffsets, const std::vector<Location>& iLocations, const std::vector<Member>& iMembers, const std::vector<std::string>& iVariables) const { // Set up file Key::Input key; key.date = iDate; key.init = iInit; key.location = 0; std::string filename = getFilename(key); // Global::createDirectory(filename); NcFile ncfile(filename.c_str(), NcFile::Replace); if(!ncfile.is_valid()) { std::stringstream ss; ss << " InputNetcdf: Could not write file: " << filename; Global::logger->write(ss.str(), Logger::error); } // Write dimensions NcDim* dimOffset = ncfile.add_dim("Offset", (long) iOffsets.size()); NcDim* dimLocation = ncfile.add_dim("Location", (long) iLocations.size()); NcDim* dimMember = ncfile.add_dim("Member", (long) iMembers.size()); // Write offsets NcVar* varOffsets = ncfile.add_var("Offset", ncFloat, dimOffset); writeVariable(varOffsets, iOffsets); // Write lat/lons NcVar* varLats = ncfile.add_var("Lat", ncFloat, dimLocation); NcVar* varLons = ncfile.add_var("Lon", ncFloat, dimLocation); NcVar* varElevs = ncfile.add_var("Elev", ncFloat, dimLocation); NcVar* varIds = ncfile.add_var("Id", ncInt, dimLocation); std::vector<float> lats; std::vector<float> lons; std::vector<float> elevs; std::vector<float> ids; for(int i = 0; i < (int) iLocations.size(); i++) { lats.push_back(iLocations[i].getLat()); lons.push_back(iLocations[i].getLon()); elevs.push_back(iLocations[i].getElev()); ids.push_back(iLocations[i].getId()); } writeVariable(varLats, lats); writeVariable(varLons, lons); writeVariable(varElevs, elevs); writeVariable(varIds, ids); // Write resolution NcVar* varRes = ncfile.add_var("Resolution", ncFloat, dimMember); std::vector<float> resolutions; for(int i = 0; i < (int) iMembers.size(); i++) { resolutions.push_back(iMembers[i].getResolution()); } writeVariable(varRes, resolutions); // Preallocate int N = iOffsets.size() * iLocations.size() * iMembers.size(); float* values = new float[N]; std::vector<std::string> localVariables; // Write each variable for(int v = 0; v < (int) iVariables.size(); v++) { for(int i = 0; i < N; i++) values[i] = Global::MV; std::string variable = iVariables[v]; std::string localVariable = variable; //bool found = getLocalVariableName(variable, localVariable); //if(!found) { // std::stringstream ss; // ss << "InputNetcdf::write: Do not know what to map " << variable << " to. Skipping."; // Global::logger->write(ss.str(), Logger::message); // } if(std::find(localVariables.begin(), localVariables.end(), localVariable) != localVariables.end()) { std::cout << "Variable " << localVariable << " has already been written once. Discarding duplicate." << std::endl; } else { localVariables.push_back(localVariable); // Populate values; for(int l = 0; l < (int) iLocations.size(); l++) { for(int o = 0; o < (int) iOffsets.size(); o++) { float offset = iOffsets[o]; for(int m = 0; m < (int) iMembers.size(); m++) { float value = iData.getValue(iDate, iInit, offset, iLocations[l], iMembers[m], variable); int index = o*iLocations.size()*iMembers.size() + l*iMembers.size() + m; assert(index < N); values[index] = value; } } } // Write values long count[3] = {iOffsets.size(), iLocations.size(), iMembers.size()}; NcVar* ncvar = ncfile.add_var(localVariable.c_str(), ncFloat, dimOffset, dimLocation, dimMember); ncvar->put(values, count); } } delete[] values; ncfile.close(); }
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, 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); }
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; } }
int main(void) { // We will write surface temperature and pressure fields. float presOut[NLAT][NLON]; float tempOut[NLAT][NLON]; float lats[NLAT]; float lons[NLON]; // 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." 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; // 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++) for(int lon = 0;lon < NLON; lon++) { presOut[lat][lon] = SAMPLE_PRESSURE + (lon * NLAT + lat); tempOut[lat][lon] = SAMPLE_TEMP + .25 * (lon * NLAT +lat); } try { // Create the file. The Replace parameter tells netCDF to overwrite // this file, if it already exists. NcFile sfc(FILE_NAME, NcFile::Replace); // Define the dimensions. NetCDF will hand back an ncDim object for // each. NcDim* latDim = sfc.addDim(LAT_NAME, NLAT); NcDim* lonDim = sfc.addDim(LON_NAME, NLON); // Define coordinate netCDF variables. They will hold the // coordinate information, that is, the latitudes and // longitudes. An pointer to a NcVar object is returned for // each. NcVar *latVar = sfc.addVar(LAT_NAME, ncFloat, latDim);//creates variable NcVar *lonVar = sfc.addVar(LON_NAME, ncFloat, lonDim); // Write the coordinate variable data. This will put the latitudes // and longitudes of our data grid into the netCDF file. latVar->put(&lats[0], NLAT, 0, 0, 0, 0); lonVar->put(&lons[0], NLON, 0, 0, 0, 0); // Define units attributes for coordinate vars. This attaches a // text attribute to each of the coordinate variables, containing // the units. Note that we are not writing a trailing NULL, just // "units", because the reading program may be fortran which does // not use null-terminated strings. In general it is up to the // reading C program to ensure that it puts null-terminators on // strings where necessary. lonVar->addAtt(UNITS,ncChar, DEGREES_EAST); latVar->addAtt(UNITS,ncChar ,DEGREES_NORTH); // Define the netCDF data variables. NcVar *presVar = sfc.addVar(PRES_NAME, ncFloat, latDim, lonDim); NcVar *tempVar = sfc.addVar(TEMP_NAME, ncFloat, latDim, lonDim); // Define units attributes for vars. presVar->addAtt(UNITS,ncString, string("hPa")); tempVar->addAtt(UNITS,ncString ,string("celsius")); // 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. presVar->put(&presOut[0][0], NLAT, NLON, 0, 0, 0); tempVar->put(&tempOut[0][0], NLAT, NLON, 0, 0, 0); // 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 " << FILE_NAME << "!" << endl; } catch(NcException e) { e.what(); } return 0; }
bool OutputClusters(const string &filename, const vector<Cluster> &theClusters, const RadarData_t &radarInfo, const ClustParams_t &clustParam) { NcFile clusterFile(filename.c_str(), NcFile::Replace); if (!clusterFile.is_valid()) { cerr << "Could not create file: " << filename << "\n"; return(false); } size_t pixelCnt = 0; for (vector<Cluster>::const_iterator aClust = theClusters.begin(); aClust != theClusters.end(); aClust++) { pixelCnt += aClust->size(); } NcDim* pixelDim = clusterFile.add_dim("pixel_index", pixelCnt); NcDim* latDim = clusterFile.add_dim("lat", radarInfo.dataEdges[1]); NcDim* lonDim = clusterFile.add_dim("lon", radarInfo.dataEdges[2]); NcVar* clustMember = clusterFile.add_var("clusterIndex", ncInt, pixelDim); clustMember->add_att("Description", "pixel cluster membership"); NcVar* xLoc = clusterFile.add_var("pixel_xLoc", ncInt, pixelDim); xLoc->add_att("Description", "x-index of pixel in domain (lat,lon)"); NcVar* yLoc = clusterFile.add_var("pixel_yLoc", ncInt, pixelDim); yLoc->add_att("Description", "y-index of pixel in domain (lat,lon)"); NcVar* lats = clusterFile.add_var("lat", ncDouble, latDim); lats->add_att("units", radarInfo.latUnits.c_str()); lats->add_att("spacing", radarInfo.latSpacing); NcVar* lons = clusterFile.add_var("lon", ncDouble, lonDim); lons->add_att("units", radarInfo.lonUnits.c_str()); lons->add_att("spacing", radarInfo.lonSpacing); clusterFile.add_att("title", "SPA Cluster Results of Radar Reflectivities"); clusterFile.add_att("data_source", radarInfo.inputFilename.c_str()); clusterFile.add_att("time", radarInfo.scanTime); // Need to do type-casting to double because the netcdf libraries can't seem to properly save a float. // Also, the truncf() is used to -- somewhat -- handle mantisa issues. clusterFile.add_att("Upper_Sensitivity", (double) (truncf(100.0 * clustParam.upperSensitivity)/100.0)); clusterFile.add_att("Lower_Sensitivity", (double) (truncf(100.0 * clustParam.lowerSensitivity)/100.0)); clusterFile.add_att("Padding_Level", (double) (truncf(100.0 * clustParam.paddingLevel)/100.0)); clusterFile.add_att("Reach", (double) (truncf(100.0 * clustParam.reach)/100.0)); clusterFile.add_att("Subcluster_Depth", clustParam.subClustDepth); int* clustIndicies = new int[pixelCnt]; int* xPixels = new int[pixelCnt]; int* yPixels = new int[pixelCnt]; size_t pixelIndex = 0; for (size_t clustIndex = 0; clustIndex < theClusters.size(); clustIndex++) { for (Cluster::const_iterator aMember = theClusters[clustIndex].begin(); aMember != theClusters[clustIndex].end(); aMember++, pixelIndex++) { clustIndicies[pixelIndex] = clustIndex; xPixels[pixelIndex] = aMember->XLoc; yPixels[pixelIndex] = aMember->YLoc; } } clustMember->put(clustIndicies, pixelCnt); xLoc->put(xPixels, pixelCnt); yLoc->put(yPixels, pixelCnt); lats->put(radarInfo.latVals, radarInfo.dataEdges[1]); lons->put(radarInfo.lonVals, radarInfo.dataEdges[2]); clusterFile.close(); delete [] clustIndicies; delete [] xPixels; delete [] yPixels; return(true); }
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); } }