예제 #1
0
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));
}
예제 #2
0
파일: RLLMesh.cpp 프로젝트: dongli/TTS-I
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();
}
예제 #3
0
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;
@}
예제 #4
0
파일: tst_suite.cpp 프로젝트: mmase/wgrib2
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;
}
예제 #5
0
파일: tst_suite.cpp 프로젝트: mmase/wgrib2
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;
}
예제 #6
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());
}
}
예제 #8
0
파일: nctst.cpp 프로젝트: akiyoshi/wrf-fire
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();
}
예제 #10
0
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());
}
}
예제 #12
0
int main(int argc, char ** argv) {

	MPI_Init(&argc, &argv);

	NcError error(NcError::silent_nonfatal);

try {

	// Input filename
	std::string strInputFile;

	// Output filename
	std::string strOutputFile;

	// Separate topography file
	std::string strTopographyFile;

	// List of variables to extract
	std::string strVariables;

	// Extract geopotential height
	bool fGeopotentialHeight;

	// Pressure levels to extract
	std::string strPressureLevels;

	// Height levels to extract
	std::string strHeightLevels;

	// Extract variables at the surface
	bool fExtractSurface;

	// Extract total energy
	bool fExtractTotalEnergy;

	// Parse the command line
	BeginCommandLine()
		CommandLineString(strInputFile, "in", "");
		CommandLineString(strOutputFile, "out", "");
		CommandLineString(strVariables, "var", "");
		CommandLineBool(fGeopotentialHeight, "output_z");
		CommandLineBool(fExtractTotalEnergy, "output_energy");
		CommandLineString(strPressureLevels, "p", "");
		CommandLineString(strHeightLevels, "z", "");
		CommandLineBool(fExtractSurface, "surf");

		ParseCommandLine(argc, argv);
	EndCommandLine(argv)

	AnnounceBanner();

	// Check command line arguments
	if (strInputFile == "") {
		_EXCEPTIONT("No input file specified");
	}
	if (strOutputFile == "") {
		_EXCEPTIONT("No output file specified");
	}
	if (strVariables == "") {
		_EXCEPTIONT("No variables specified");
	}

	// Parse variable string
	std::vector< std::string > vecVariableStrings;

	ParseVariableList(strVariables, vecVariableStrings);

	// Check variables
	if (vecVariableStrings.size() == 0) {
		_EXCEPTIONT("No variables specified");
	}

	// Parse pressure level string
	std::vector<double> vecPressureLevels;

	ParseLevelArray(strPressureLevels, vecPressureLevels);

	int nPressureLevels = (int)(vecPressureLevels.size());

	for (int k = 0; k < nPressureLevels; k++) {
		if (vecPressureLevels[k] <= 0.0) {
			_EXCEPTIONT("Non-positive pressure values not allowed");
		}
	}

	// Parse height level string
	std::vector<double> vecHeightLevels;

	ParseLevelArray(strHeightLevels, vecHeightLevels);

	int nHeightLevels = (int)(vecHeightLevels.size());

	// Check pressure levels
	if ((nPressureLevels == 0) &&
		(nHeightLevels == 0) &&
		(!fExtractSurface)
	) {
		_EXCEPTIONT("No pressure / height levels to process");
	}

	// Open input file
	AnnounceStartBlock("Loading input file");
	NcFile ncdf_in(strInputFile.c_str(), NcFile::ReadOnly);
	if (!ncdf_in.is_valid()) {
		_EXCEPTION1("Unable to open file \"%s\" for reading",
			strInputFile.c_str());
	}

	// Load time array
	Announce("Time");
	NcVar * varTime = ncdf_in.get_var("time");
	if (varTime == NULL) {
		_EXCEPTION1("File \"%s\" does not contain variable \"time\"",
			strInputFile.c_str());
	}
	int nTime = varTime->get_dim(0)->size();

	DataArray1D<double> dTime(nTime);
	varTime->set_cur((long)0);
	varTime->get(&(dTime[0]), nTime);

	// Load latitude array
	Announce("Latitude");
	NcVar * varLat = ncdf_in.get_var("lat");
	if (varLat == NULL) {
		_EXCEPTION1("File \"%s\" does not contain variable \"lat\"",
			strInputFile.c_str());
	}
	int nLat = varLat->get_dim(0)->size();

	DataArray1D<double> dLat(nLat);
	varLat->set_cur((long)0);
	varLat->get(&(dLat[0]), nLat);

	// Load longitude array
	Announce("Longitude");
	NcVar * varLon = ncdf_in.get_var("lon");
	if (varLon == NULL) {
		_EXCEPTION1("File \"%s\" does not contain variable \"lon\"",
			strInputFile.c_str());
	}
	int nLon = varLon->get_dim(0)->size();

	DataArray1D<double> dLon(nLon);
	varLon->set_cur((long)0);
	varLon->get(&(dLon[0]), nLon);

	// Load level array
	Announce("Level");
	NcVar * varLev = ncdf_in.get_var("lev");
	if (varLev == NULL) {
		_EXCEPTION1("File \"%s\" does not contain variable \"lev\"",
			strInputFile.c_str());
	}
	int nLev = varLev->get_dim(0)->size();

	DataArray1D<double> dLev(nLev);
	varLev->set_cur((long)0);
	varLev->get(&(dLev[0]), nLev);

	// Load level interface array
	Announce("Interface");
	NcVar * varILev = ncdf_in.get_var("ilev");
	int nILev = 0;
	DataArray1D<double> dILev;
	if (varILev == NULL) {
		Announce("Warning: Variable \"ilev\" not found");
	} else {
		nILev = varILev->get_dim(0)->size();
		if (nILev != nLev + 1) {
			_EXCEPTIONT("Variable \"ilev\" must have size lev+1");
		}
		dILev.Allocate(nILev);
		varILev->set_cur((long)0);
		varILev->get(&(dILev[0]), nILev);
	}

	// Load topography
	Announce("Topography");
	NcVar * varZs = ncdf_in.get_var("Zs");
	if (varZs == NULL) {
		_EXCEPTION1("File \"%s\" does not contain variable \"Zs\"",
			strInputFile.c_str());
	}

	DataArray2D<double> dZs(nLat, nLon);
	varZs->set_cur((long)0, (long)0);
	varZs->get(&(dZs[0][0]), nLat, nLon);

	AnnounceEndBlock("Done");

	// Open output file
	AnnounceStartBlock("Constructing output file");

	NcFile ncdf_out(strOutputFile.c_str(), NcFile::Replace);
	if (!ncdf_out.is_valid()) {
		_EXCEPTION1("Unable to open file \"%s\" for writing",
			strOutputFile.c_str());
	}

	CopyNcFileAttributes(&ncdf_in, &ncdf_out);

	// Output time array
	Announce("Time");
	NcDim * dimOutTime = ncdf_out.add_dim("time");
	NcVar * varOutTime = ncdf_out.add_var("time", ncDouble, dimOutTime);
	varOutTime->set_cur((long)0);
	varOutTime->put(&(dTime[0]), nTime);

	CopyNcVarAttributes(varTime, varOutTime);

	// Output pressure array
	NcDim * dimOutP = NULL;
	NcVar * varOutP = NULL;
	if (nPressureLevels > 0) {
		Announce("Pressure");
		dimOutP = ncdf_out.add_dim("p", nPressureLevels);
		varOutP = ncdf_out.add_var("p", ncDouble, dimOutP);
		varOutP->set_cur((long)0);
		varOutP->put(&(vecPressureLevels[0]), nPressureLevels);
	}

	// Output height array
	NcDim * dimOutZ = NULL;
	NcVar * varOutZ = NULL;
	if (nHeightLevels > 0) {
		Announce("Height");
		dimOutZ = ncdf_out.add_dim("z", nHeightLevels);
		varOutZ = ncdf_out.add_var("z", ncDouble, dimOutZ);
		varOutZ->set_cur((long)0);
		varOutZ->put(&(vecHeightLevels[0]), nHeightLevels);
	}

	// Output latitude and longitude array
	Announce("Latitude");
	NcDim * dimOutLat = ncdf_out.add_dim("lat", nLat);
	NcVar * varOutLat = ncdf_out.add_var("lat", ncDouble, dimOutLat);
	varOutLat->set_cur((long)0);
	varOutLat->put(&(dLat[0]), nLat);

	CopyNcVarAttributes(varLat, varOutLat);

	Announce("Longitude");
	NcDim * dimOutLon = ncdf_out.add_dim("lon", nLon);
	NcVar * varOutLon = ncdf_out.add_var("lon", ncDouble, dimOutLon);
	varOutLon->set_cur((long)0);
	varOutLon->put(&(dLon[0]), nLon);

	CopyNcVarAttributes(varLon, varOutLon);

	// Output topography
	Announce("Topography");
	NcVar * varOutZs = ncdf_out.add_var(
		"Zs", ncDouble, dimOutLat, dimOutLon);

	varOutZs->set_cur((long)0, (long)0);
	varOutZs->put(&(dZs[0][0]), nLat, nLon);

	AnnounceEndBlock("Done");

	// Done
	AnnounceEndBlock("Done");

	// Load all variables
	Announce("Loading variables");

	std::vector<NcVar *> vecNcVar;
	for (int v = 0; v < vecVariableStrings.size(); v++) {
		vecNcVar.push_back(ncdf_in.get_var(vecVariableStrings[v].c_str()));
		if (vecNcVar[v] == NULL) {
			_EXCEPTION1("Unable to load variable \"%s\" from file",
				vecVariableStrings[v].c_str());
		}
	}

	// Physical constants
	Announce("Initializing thermodynamic variables");

	NcAtt * attEarthRadius = ncdf_in.get_att("earth_radius");
	double dEarthRadius = attEarthRadius->as_double(0);

	NcAtt * attRd = ncdf_in.get_att("Rd");
	double dRd = attRd->as_double(0);

	NcAtt * attCp = ncdf_in.get_att("Cp");
	double dCp = attCp->as_double(0);

	double dGamma = dCp / (dCp - dRd);

	NcAtt * attP0 = ncdf_in.get_att("P0");
	double dP0 = attP0->as_double(0);

	double dPressureScaling = dP0 * std::pow(dRd / dP0, dGamma);

	NcAtt * attZtop = ncdf_in.get_att("Ztop");
	double dZtop = attZtop->as_double(0);

	// Input data
	DataArray3D<double> dataIn(nLev, nLat, nLon);
	DataArray3D<double> dataInt(nILev, nLat, nLon);

	// Output data
	DataArray2D<double> dataOut(nLat, nLon);

	// Pressure in column
	DataArray1D<double> dataColumnP(nLev);

	// Height in column
	DataArray1D<double> dataColumnZ(nLev);
	DataArray1D<double> dataColumnIZ(nILev);

	// Column weights
	DataArray1D<double> dW(nLev);
	DataArray1D<double> dIW(nILev);

	// Loop through all times, pressure levels and variables
	AnnounceStartBlock("Interpolating");

	// Add energy variable
	NcVar * varEnergy;
	if (fExtractTotalEnergy) {
		varEnergy = ncdf_out.add_var("TE", ncDouble, dimOutTime);
	}

	// Create output pressure variables
	std::vector<NcVar *> vecOutNcVarP;
	if (nPressureLevels > 0) {
		for (int v = 0; v < vecVariableStrings.size(); v++) {
			vecOutNcVarP.push_back(
				ncdf_out.add_var(
					vecVariableStrings[v].c_str(), ncDouble,
						dimOutTime, dimOutP, dimOutLat, dimOutLon));

			// Copy attributes
			CopyNcVarAttributes(vecNcVar[v], vecOutNcVarP[v]);
		}
	}

	// Create output height variables
	std::vector<NcVar *> vecOutNcVarZ;
	if (nHeightLevels > 0) {
		for (int v = 0; v < vecVariableStrings.size(); v++) {
			std::string strVarName = vecVariableStrings[v];
			if (nPressureLevels > 0) {
				strVarName += "z";
			}
			vecOutNcVarZ.push_back(
				ncdf_out.add_var(
					strVarName.c_str(), ncDouble,
						dimOutTime, dimOutZ, dimOutLat, dimOutLon));

			// Copy attributes
			CopyNcVarAttributes(vecNcVar[v], vecOutNcVarZ[v]);
		}
	}

	// Create output surface variable
	std::vector<NcVar *> vecOutNcVarS;
	if (fExtractSurface) {
		for (int v = 0; v < vecVariableStrings.size(); v++) {
			std::string strVarName = vecVariableStrings[v];
			strVarName += "S";

			vecOutNcVarS.push_back(
				ncdf_out.add_var(
					strVarName.c_str(), ncDouble,
						dimOutTime, dimOutLat, dimOutLon));

			// Copy attributes
			CopyNcVarAttributes(vecNcVar[v], vecOutNcVarS[v]);
		}
	}

	// Loop over all times
	for (int t = 0; t < nTime; t++) {

		char szAnnounce[256];
		sprintf(szAnnounce, "Time %i", t); 
		AnnounceStartBlock(szAnnounce);

		// Rho
		DataArray3D<double> dataRho(nLev, nLat, nLon);

		NcVar * varRho = ncdf_in.get_var("Rho");
		if (varRho == NULL) {
			_EXCEPTIONT("Unable to load variable \"Rho\" from file");
		}
		varRho->set_cur(t, 0, 0, 0);
		varRho->get(&(dataRho[0][0][0]), 1, nLev, nLat, nLon);

		// Pressure
		DataArray3D<double> dataP(nLev, nLat, nLon);

		if (nPressureLevels != 0) {
			NcVar * varP = ncdf_in.get_var("P");
			if (varP == NULL) {
				_EXCEPTIONT("Unable to load variable \"P\" from file");
			}
			varP->set_cur(t, 0, 0, 0);
			varP->get(&(dataP[0][0][0]), 1, nLev, nLat, nLon);
		}
/*
		// Populate pressure array
		if (nPressureLevels > 0) {

			// Calculate pointwise pressure
			for (int k = 0; k < nLev; k++) {
			for (int i = 0; i < nLat; i++) {
			for (int j = 0; j < nLon; j++) {
				dataP[k][i][j] = dPressureScaling
					* exp(log(dataRho[k][i][j] * dataP[k][i][j]) * dGamma);
			}
			}
			}
		}
*/
		// Height everywhere
		DataArray3D<double> dataZ(nLev, nLat, nLon);
		DataArray3D<double> dataIZ;
		if (nILev != 0) {
			dataIZ.Allocate(nILev, nLat, nLon);
		}

		// Populate height array
		if ((nHeightLevels > 0) || (fGeopotentialHeight)) {
			for (int k = 0; k < nLev; k++) {
			for (int i = 0; i < nLat; i++) {
			for (int j = 0; j < nLon; j++) {
				dataZ[k][i][j] = dZs[i][j] + dLev[k] * (dZtop - dZs[i][j]);
			}
			}
			}

			for (int k = 0; k < nILev; k++) {
			for (int i = 0; i < nLat; i++) {
			for (int j = 0; j < nLon; j++) {
				dataIZ[k][i][j] = dZs[i][j] + dILev[k] * (dZtop - dZs[i][j]);
			}
			}
			}
		}

		// Loop through all pressure levels and variables
		for (int v = 0; v < vecNcVar.size(); v++) {

			bool fOnInterfaces = false;

			// Load in the data array
			vecNcVar[v]->set_cur(t, 0, 0, 0);

			if (vecNcVar[v]->get_dim(1)->size() == nLev) {
				vecNcVar[v]->get(&(dataIn[0][0][0]), 1, nLev, nLat, nLon);

				Announce("%s (n)", vecVariableStrings[v].c_str());

			} else if (vecNcVar[v]->get_dim(1)->size() == nILev) {
				vecNcVar[v]->get(&(dataInt[0][0][0]), 1, nILev, nLat, nLon);
				fOnInterfaces = true;

				Announce("%s (i)", vecVariableStrings[v].c_str());
			} else {
				_EXCEPTION1("Variable \"%s\" has invalid level dimension",
					vecVariableStrings[v].c_str());
			}

			// At the physical surface
			if (fExtractSurface) {

				if (fOnInterfaces) {
					for (int i = 0; i < nLat; i++) {
					for (int j = 0; j < nLon; j++) {
						dataOut[i][j] = dataInt[0][i][j];
					}
					}

				} else {

					int kBegin = 0;
					int kEnd = 3;

					PolynomialInterp::LagrangianPolynomialCoeffs(
						3, dLev, dW, 0.0);

					// Loop thorugh all latlon indices
					for (int i = 0; i < nLat; i++) {
					for (int j = 0; j < nLon; j++) {

						// Interpolate in the vertical
						dataOut[i][j] = 0.0;
						for (int k = kBegin; k < kEnd; k++) {
							dataOut[i][j] += dW[k] * dataIn[k][i][j];
						}
					}
					}
				}

				// Write variable
				vecOutNcVarS[v]->set_cur(t, 0, 0);
				vecOutNcVarS[v]->put(&(dataOut[0][0]), 1, nLat, nLon);

			}

			// Loop through all pressure levels
			for (int p = 0; p < nPressureLevels; p++) {

				// Loop thorugh all latlon indices
				for (int i = 0; i < nLat; i++) {
				for (int j = 0; j < nLon; j++) {

					// Store column pressure
					for (int k = 0; k < nLev; k++) {
						dataColumnP[k] = dataP[k][i][j];
					}

					// Find weights
					int kBegin = 0;
					int kEnd = 0;

					// On a pressure surface
					InterpolationWeightsLinear(
						vecPressureLevels[p],
						dataColumnP,
						kBegin,
						kEnd,
						dW);

					// Interpolate in the vertical
					dataOut[i][j] = 0.0;
					for (int k = kBegin; k < kEnd; k++) {
						dataOut[i][j] += dW[k] * dataIn[k][i][j];
					}

				}
				}

				// Write variable
				vecOutNcVarP[v]->set_cur(t, p, 0, 0);
				vecOutNcVarP[v]->put(&(dataOut[0][0]), 1, 1, nLat, nLon);
			}

			// Loop through all height levels
			for (int z = 0; z < nHeightLevels; z++) {

				// Loop thorugh all latlon indices
				for (int i = 0; i < nLat; i++) {
				for (int j = 0; j < nLon; j++) {

					// Find weights
					int kBegin = 0;
					int kEnd = 0;

					// Interpolate from levels to z surfaces
					if (!fOnInterfaces) {
						for (int k = 0; k < nLev; k++) {
							dataColumnZ[k] = dataZ[k][i][j];
						}

						InterpolationWeightsLinear(
							vecHeightLevels[z],
							dataColumnZ,
							kBegin,
							kEnd,
							dW);

						dataOut[i][j] = 0.0;
						for (int k = kBegin; k < kEnd; k++) {
							dataOut[i][j] += dW[k] * dataIn[k][i][j];
						}

					// Interpolate from interfaces to z surfaces
					} else {
						for (int k = 0; k < nILev; k++) {
							dataColumnIZ[k] = dataIZ[k][i][j];
						}

						InterpolationWeightsLinear(
							vecHeightLevels[z],
							dataColumnIZ,
							kBegin,
							kEnd,
							dIW);

						dataOut[i][j] = 0.0;
						for (int k = kBegin; k < kEnd; k++) {
							dataOut[i][j] += dIW[k] * dataInt[k][i][j];
						}
					}
				}
				}

				// Write variable
				vecOutNcVarZ[v]->set_cur(t, z, 0, 0);
				vecOutNcVarZ[v]->put(&(dataOut[0][0]), 1, 1, nLat, nLon);
			}
		}

		// Output geopotential height
		if (fGeopotentialHeight) {

			Announce("Geopotential height");

			// Output variables
			NcVar * varOutZ;
			NcVar * varOutZs;

			if (nPressureLevels > 0) {
				varOutZ = ncdf_out.add_var(
					"PHIZ", ncDouble, dimOutTime, dimOutP, dimOutLat, dimOutLon);
			}
			if (fExtractSurface) {
				varOutZs = ncdf_out.add_var(
					"PHIZS", ncDouble, dimOutTime, dimOutLat, dimOutLon);
			}

			// Interpolate onto pressure levels
			for (int p = 0; p < nPressureLevels; p++) {

				// Loop thorugh all latlon indices
				for (int i = 0; i < nLat; i++) {
				for (int j = 0; j < nLon; j++) {

					int kBegin = 0;
					int kEnd = 0;

					for (int k = 0; k < nLev; k++) {
						dataColumnP[k] = dataP[k][i][j];
					}

					InterpolationWeightsLinear(
						vecPressureLevels[p],
						dataColumnP,
						kBegin,
						kEnd,
						dW);

					// Interpolate in the vertical
					dataOut[i][j] = 0.0;
					for (int k = kBegin; k < kEnd; k++) {
						dataOut[i][j] += dW[k] * dataZ[k][i][j];
					}
				}
				}

				// Write variable
				varOutZ->set_cur(t, p, 0, 0);
				varOutZ->put(&(dataOut[0][0]), 1, 1, nLat, nLon);

			}

			// Interpolate onto the physical surface
			if (fExtractSurface) {

				int kBegin = 0;
				int kEnd = 3;

				PolynomialInterp::LagrangianPolynomialCoeffs(
					3, dLev, dW, 0.0);

				// Loop thorugh all latlon indices
				for (int i = 0; i < nLat; i++) {
				for (int j = 0; j < nLon; j++) {

					// Interpolate in the vertical
					dataOut[i][j] = 0.0;
					for (int k = kBegin; k < kEnd; k++) {
						dataOut[i][j] += dW[k] * dataZ[k][i][j];
					}
				}
				}

				// Write variable
				varOutZs->set_cur(t, 0, 0);
				varOutZs->put(&(dataOut[0][0]), 1, nLat, nLon);

			}
		}

		// Extract total energy
		if (fExtractTotalEnergy) {
			Announce("Total Energy");

			// Zonal velocity
			DataArray3D<double> dataU(nLev, nLat, nLon);

			NcVar * varU = ncdf_in.get_var("U");
			varU->set_cur(t, 0, 0, 0);
			varU->get(&(dataU[0][0][0]), 1, nLev, nLat, nLon);

			// Meridional velocity
			DataArray3D<double> dataV(nLev, nLat, nLon);

			NcVar * varV = ncdf_in.get_var("V");
			varV->set_cur(t, 0, 0, 0);
			varV->get(&(dataV[0][0][0]), 1, nLev, nLat, nLon);

			// Vertical velocity
			DataArray3D<double> dataW(nLev, nLat, nLon);

			NcVar * varW = ncdf_in.get_var("W");
			varW->set_cur(t, 0, 0, 0);
			varW->get(&(dataW[0][0][0]), 1, nLev, nLat, nLon);

			// Calculate total energy
			double dTotalEnergy = 0.0;

			double dElementRefArea =
				dEarthRadius * dEarthRadius
				* M_PI / static_cast<double>(nLat)
				* 2.0 * M_PI / static_cast<double>(nLon);

			for (int k = 0; k < nLev; k++) {
			for (int i = 0; i < nLat; i++) {
			for (int j = 0; j < nLon; j++) {
				double dKineticEnergy =
					0.5 * dataRho[k][i][j] *
						( dataU[k][i][j] * dataU[k][i][j]
						+ dataV[k][i][j] * dataV[k][i][j]
						+ dataW[k][i][j] * dataW[k][i][j]);

				double dInternalEnergy =
					dataP[k][i][j] / (dGamma - 1.0);

				dTotalEnergy +=
					(dKineticEnergy + dInternalEnergy)
						* std::cos(M_PI * dLat[i] / 180.0) * dElementRefArea
						* (dZtop - dZs[i][j]) / static_cast<double>(nLev);
			}
			}
			}

			// Put total energy into file
			varEnergy->set_cur(t);
			varEnergy->put(&dTotalEnergy, 1);
		}

		AnnounceEndBlock("Done");
	}

	AnnounceEndBlock("Done");

} catch(Exception & e) {
	Announce(e.ToString().c_str());
}

	// Finalize MPI
	MPI_Finalize();
}
예제 #13
0
//
// 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 );
}
예제 #14
0
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;
}	
예제 #16
0
파일: tst_suite.cpp 프로젝트: mmase/wgrib2
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;
 
}
예제 #17
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);
};
예제 #18
0
파일: tst_suite.cpp 프로젝트: mmase/wgrib2
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;
}
예제 #19
0
파일: Netcdf.cpp 프로젝트: WFRT/Comps
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);
	}
}
예제 #21
0
int main(int argc, const char* argv[]) {
    string fileName;
    int maxDataSavePts, boundHandlingMethod;
    double stoppingTol;
    
    if (argc == 8) {
        for (int i = 0; i < argc; i++) {            
            if (argv[i][0] == '-') {
                switch(argv[i][1]) {
                    case 'n':
                        maxDataSavePts = atoi(argv[i+1]);
                        i++;
                        break;
                    case 'e':
                        stoppingTol = atof(argv[i+1]);
                        i++;
                        break;
                    case 'b':
                        boundHandlingMethod = atof(argv[i+1]);
                        i++;
                        break;
                }
            } else {                
                fileName = argv[i];
            }
        }
    } else {
        fprintf(stderr, "\nUsage: ./FilePrep <fileName> -n <maxDataSavePts> -e <stoppingTol> -b <boundHandlingMethod>\n");
        fprintf(stderr, "                  <fileName> Name of the NetCDF file to be prepared for simulation.\n");
        fprintf(stderr, "    -n      <maxDataSavePts> Maximum number of initial states to be held in the file.\n");
        fprintf(stderr, "    -e         <stoppingTol> Maximum allowable L2 distance between successive probability distributions.\n\n");
        fprintf(stderr, "    -b <boundHandlingMethod> 1 for deletion. 2 for resampling.");
        abort();
    }
        
    NcFile file(fileName.c_str(), NcFile::Write);
    if (!file.is_valid()) {
        fprintf(stderr, "Error: %s could not be opened.\n", fileName.c_str());
        abort();
    }
        
    NcDim* dim = file.add_dim("maxDataSavePts", maxDataSavePts);
    
    NcVar* stoppingTolVar = file.add_var("stoppingTol", ncDouble);
    NcVar* numDataSavePtsVar = file.add_var("numDataSavePts", ncInt, file.get_dim("numMdls")); 
    NcVar* boundHandlingMethodVar = file.add_var("boundHandlingMethod", ncInt, file.get_dim("numMdls"));
    file.add_var("numBoundedSpeciesStates", ncInt, file.get_dim("numMdls"));
    file.add_var("speciesStateBounded", ncInt, file.get_dim("numMdls"), file.get_dim("maxSpecies"));
    file.add_var("speciesStateLowerBounds", ncDouble, file.get_dim("numMdls"), file.get_dim("maxSpecies"));
    file.add_var("speciesStateUpperBounds", ncDouble, file.get_dim("numMdls"), file.get_dim("maxSpecies"));
    file.add_var("dataSavePts", ncInt, file.get_dim("numMdls"), dim);
    file.add_var("speciesStateChanges", ncInt, file.get_dim("numMdls"), file.get_dim("maxSpecies"));
    
    file.get_var("state")->rename("initFwdData");    
    file.add_var("initRevData", ncDouble, file.get_dim("numMdls"), file.get_dim("maxTrials"), file.get_dim("maxTimePts"), file.get_dim("maxSaveSpecies"));
    file.add_var("fwdData", ncDouble, file.get_dim("numMdls"), dim, file.get_dim("maxTrials"), file.get_dim("maxTimePts"), file.get_dim("maxSaveSpecies"));
    file.add_var("revData", ncDouble, file.get_dim("numMdls"), dim, file.get_dim("maxTrials"), file.get_dim("maxTimePts"), file.get_dim("maxSaveSpecies"));
    
    file.add_var("initFwdAbsCurr", ncInt, file.get_dim("numMdls"), file.get_dim("maxTimePts"), file.get_dim("maxSaveSpecies"));
    file.add_var("initRevAbsCurr", ncInt, file.get_dim("numMdls"), file.get_dim("maxTimePts"), file.get_dim("maxSaveSpecies"));
    file.add_var("fwdAbsCurr", ncInt, file.get_dim("numMdls"), dim, file.get_dim("maxTimePts"), file.get_dim("maxSaveSpecies"));
    file.add_var("revAbsCurr", ncInt, file.get_dim("numMdls"), dim, file.get_dim("maxTimePts"), file.get_dim("maxSaveSpecies"));
    
    stoppingTolVar->put(&stoppingTol, 1);
    
    int numMdls = (int) file.get_dim("numMdls")->size();    
    for (int i = 0; i < numMdls; i++) {
        numDataSavePtsVar->set_cur(i);
        numDataSavePtsVar->put(&maxDataSavePts, 1);
    }
    
    boundHandlingMethodVar->put(&boundHandlingMethod, 1);
}
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;
  }
}
예제 #23
0
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;
}
예제 #24
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);
}
예제 #25
0
파일: Arome.cpp 프로젝트: WFRT/gridpp
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);
   }
}