Exemple #1
0
NcAtt* NcVar::get_att( NcToken aname ) const
{
    NcAtt* att = new NcAtt(the_file, this, aname);
    if (! att->is_valid()) {
	delete att;
	return 0;
    }
    return att;
}
Exemple #2
0
int NetcdfSource::readString(QString *stringValue, const QString& stringName)
{
  // TODO more error handling?
  NcAtt *att = _ncfile->get_att((NcToken) stringName.toLatin1().data());
  if (att) {
    *stringValue = QString(att->as_string(0));
    return 1;
  }
  delete att;
  return 0;
}
Exemple #3
0
void DumpableNcFile::dumpgatts( void )
{
    NcAtt* ap;
    for(int n = 0; ap = get_att(n); n++) {
	cout << "\t\t" << ":" << ap->name() << " = " ;
	NcValues* vals = ap->values();
	cout << *vals << " ;" << endl ;
	delete vals;
	delete ap;
    }
}
Exemple #4
0
void dumpatts(NcVar& var)
{
    NcToken vname = var.name();
    NcAtt* ap;
    for(int n = 0; ap = var.get_att(n); n++) {
	cout << "\t\t" << vname << ":" << ap->name() << " = " ;
	NcValues* vals = ap->values();
	cout << *vals << " ;" << endl ;
	delete ap;
	delete vals;
    }
}
Exemple #5
0
bool NetcdfSource::initFile() {
  _ncfile = new NcFile(_filename.toUtf8().data(), NcFile::ReadOnly);
  if (!_ncfile->is_valid()) {
      qDebug() << _filename << ": failed to open in initFile()" << endl;
      return false;
    }

  KST_DBG qDebug() << _filename << ": building field list" << endl;
  _fieldList.clear();
  _fieldList += "INDEX";

  int nb_vars = _ncfile->num_vars();
  KST_DBG qDebug() << nb_vars << " vars found in total" << endl;

  _maxFrameCount = 0;

  for (int i = 0; i < nb_vars; i++) {
    NcVar *var = _ncfile->get_var(i);
    if (var->num_dims() == 0) {
      _scalarList += var->name();
    } else if (var->num_dims() == 1) {
      _fieldList += var->name();
      int fc = var->num_vals() / var->rec_size();
      _maxFrameCount = qMax(_maxFrameCount, fc);
      _frameCounts[var->name()] = fc;
    } else if (var->num_dims() == 2) {
      _matrixList += var->name();
    }
  }

  // Get strings
  int globalAttributesNb = _ncfile->num_atts();
  for (int i = 0; i < globalAttributesNb; ++i) {
    // Get only first value, should be enough for a start especially as strings are complete
    NcAtt *att = _ncfile->get_att(i);
    if (att) {
      QString attrName = QString(att->name());
      char *attString = att->as_string(0);
      QString attrValue = QString(att->as_string(0));
      delete[] attString;
      //TODO port
      //KstString *ms = new KstString(KstObjectTag(attrName, tag()), this, attrValue);
      _stringList += attrName;
    }
    delete att;
  }

  // TODO update(); // necessary?  slows down initial loading
  return true;
}
Exemple #6
0
QMap<QString, QString> DataInterfaceNetCdfVector::metaStrings(const QString& field)
{
  QMap<QString, QString> fieldStrings;
  QString tmpString;
  NcVar *var = netcdf._ncfile->get_var(field.toLatin1().constData());
  for (int i=0; i<var->num_atts(); ++i) {
    NcAtt *att = var->get_att(i);
    // Only handle char/unspecified attributes as fieldStrings, the others as fieldScalars
    if (att->type() == NC_CHAR || att->type() == NC_UNSPECIFIED) {
      fieldStrings[att->name()] = QString(att->values()->as_string(0));
    }
    // qDebug() << att->name() << ": " << att->values()->num() << endl;
  }
  return fieldStrings;
}
string GrabAttribute(const NcVar* dataVar, const int attIndex)
{
    if (NULL == dataVar)
    {
        cerr << "ERROR: Invalid NcVar!\n";
        return("");
    }

    NcAtt* dataAttrib = dataVar->get_att(attIndex);

    if (NULL == dataAttrib)
    {
        cerr << "ERROR: Could not obtain data attribute: index #" << attIndex << endl;
        return("");
    }

    const string returnVal = dataAttrib->as_string(0);

    delete dataAttrib;

    return(returnVal);
}
Exemple #8
0
QMap<QString, double> DataInterfaceNetCdfVector::metaScalars(const QString& field)
{
  QMap<QString, double> fieldScalars;
  NcVar *var = netcdf._ncfile->get_var(field.toLatin1().constData());
  fieldScalars["NbAttributes"] = var->num_atts();
  for (int i=0; i<var->num_atts(); ++i) {
    NcAtt *att = var->get_att(i);
    // Only handle char attributes as fieldStrings, the others as fieldScalars
    if (att->type() == NC_BYTE || att->type() == NC_SHORT || att->type() == NC_INT
        || att->type() == NC_LONG || att->type() == NC_FLOAT || att->type() == NC_DOUBLE) {
      // Some attributes may have multiple values => load the first as is, and for the others
      // add a -2, -3, etc... suffix as obviously we can have only one value per scalar.
      // Do it in two steps to avoid a test in the loop while keeping a "clean" name for the first one
      fieldScalars[QString(att->name())] = att->values()->as_double(0);
      for (int j=1; j<att->values()->num(); ++j) {
        fieldScalars[QString(att->name()) + QString("-") + QString::number(j+1)] = att->values()->as_double(j);
      }
    }
  }
  return fieldScalars;
}
void
avtS3DFileFormat::PopulateDatabaseMetaData(avtDatabaseMetaData *md,
                                           int timeState)
{
    debug5 << "avtS3DFileFormat::PopulateDatabaseMetaData" << endl;
    // Get the metadata from the log file first.
    OpenLogFile();

    // Mesh
    avtMeshMetaData *mesh = new avtMeshMetaData;
    mesh->name = "mesh";
    mesh->meshType = AVT_RECTILINEAR_MESH;
    mesh->numBlocks = procs[0] * procs[1] * procs[2];
    mesh->blockOrigin = 1;
    mesh->cellOrigin = 0;
    mesh->spatialDimension = 3;
    mesh->topologicalDimension = 3;
    mesh->blockTitle = "blocks";
    mesh->blockPieceName = "block";
    mesh->hasSpatialExtents = false;
    mesh->xUnits = "mm";
    mesh->yUnits = "mm";
    mesh->zUnits = "mm";
    md->Add(mesh);

    //
    // Look in the NetCDF file for the first block for the list of variables.
    //

    // Calculate the timestep directory that the data lives in.
    char *pathcopy = strdup(mainFilename);
    string dir = parse_dirname(pathcopy);
    string timestepDir = CreateStringFromDouble(fileTimes[timeState]);

    char path[256];
    SNPRINTF(path,256,"%s%s%s%sfield.00000",dir.c_str(),VISIT_SLASH_STRING, timestepDir.c_str(), VISIT_SLASH_STRING);

    NcError err(NcError::verbose_nonfatal);
 
    NcFile nf(path);
    if (!nf.is_valid())
    {
        EXCEPTION1(InvalidFilesException, path);
    }
    debug5 << "avtS3DFileFormat::PopulateDatabaseMetaData: Got valid file" << endl;

    int nvars = nf.num_vars();
    debug5 << "avtS3DFileFormat::PopulateDatabaseMetaData: Found " << nvars << " variables" << endl;
    for (int i=0 ; i<nvars; i++)
    {
        NcVar *v = nf.get_var(i);
        if (!v)
            continue;
        debug4 << "Found variable " << v->name() << endl;

        // Check dimensionality
        int nvals = v->num_vals();
        if (nvals != 1) // Single scalars are useless.
        {
            avtScalarMetaData *scalar = new avtScalarMetaData();
            scalar->name = v->name();
            scalar->meshName = "mesh";
            scalar->centering = AVT_NODECENT;
            scalar->hasDataExtents = false;
            scalar->treatAsASCII = false;

            NcAtt *units = v->get_att(NcToken("units"));
            if (units)
            {
                long nv = units->num_vals();
                if (nv == 0)
                {
                    scalar->hasUnits = false;
                } else {
                    char *unitString = units->as_string(0);
                    scalar->units = unitString;
                    scalar->hasUnits = true;
                }
            } else
                scalar->hasUnits = false;

            md->Add(scalar);
        } else {
            debug4 << "Unable to process variable " << v->name() <<
                      " since it is a single scalar" << endl;

        }
    }

#if 0
    // Expressions
    Expression tempGradient_expr;
    tempGradient_expr.SetName("Temperature_gradient");
    tempGradient_expr.SetDefinition("gradient(Temperature)");
    tempGradient_expr.SetType(Expression::VectorMeshVar);
    tempGradient_expr.SetHidden(true);
    md->AddExpression(&tempGradient_expr);

    Expression tempUnit_expr;
    tempUnit_expr.SetName("Temperature_grad_unit");
    //tempUnit_expr.SetDefinition("(Temperature_gradient + {1e-6,0,0})/(magnitude(Temperature_gradient) + 1e-6)");
    //tempUnit_expr.SetDefinition("Temperature_gradient/(magnitude(Temperature_gradient) + 1e-6)");
    tempUnit_expr.SetDefinition("normalize(Temperature_gradient)");
    tempUnit_expr.SetType(Expression::VectorMeshVar);
    tempUnit_expr.SetHidden(true);
    md->AddExpression(&tempUnit_expr);

    Expression tempCurv_expr;
    tempCurv_expr.SetName("Temperature_curvature");
    tempCurv_expr.SetDefinition("divergence(Temperature_grad_unit)");
    tempCurv_expr.SetType(Expression::ScalarMeshVar);
    tempUnit_expr.SetHidden(false);
    md->AddExpression(&tempCurv_expr);
#endif
}
RadarData_t ReadRadarFile(const string &filename,
                          const float latmin, const float latmax,
                          const float lonmin, const float lonmax)
{
    RadarData_t inputData;

    // Sets the internal netcdf error handling to nonfatal for this scope
    NcError error_handler(NcError::verbose_nonfatal);

    NcFile radarFile(filename.c_str());

    if (!radarFile.is_valid())
    {
        cerr << "ERROR: Could not open radar file: " << filename << " for reading.\n";

        // Error is indicated by the lack of initialization of
        // the filename member of the struct.
        return(inputData);
    }

    NcVar* latVar = radarFile.get_var("lat");

    if (NULL == latVar)
    {
        cerr << "ERROR: invalid data file.  No variable called 'lat'!\n";
        radarFile.close();
        return(inputData);
    }

    long latCnt = latVar->num_vals();
    double* latVals = new double[latCnt];
    latVar->get(latVals, latCnt);
    inputData.latUnits = GrabAttribute(latVar, 0);
    inputData.latSpacing = strtod(GrabAttribute(latVar, 1).c_str(), NULL);

    const long minLatIndex = lower_bound(latVals, latmin, latCnt);
    const long maxLatIndex = upper_bound(latVals, latmax, latCnt);

    delete latVals;
    latCnt = (maxLatIndex - minLatIndex) + 1;
    latVar->set_cur(minLatIndex);
    inputData.latVals = new double[latCnt];
    latVar->get(inputData.latVals, latCnt);


    NcVar* lonVar = radarFile.get_var("lon");

    if (NULL == lonVar)
    {
        cerr << "ERROR: invalid data file.  No variable called 'lon'!\n";
        radarFile.close();
        return(inputData);
    }

    long lonCnt = lonVar->num_vals();
    double* lonVals = new double[lonCnt];
    lonVar->get(lonVals, lonCnt);
    inputData.lonUnits = GrabAttribute(lonVar, 0);
    inputData.lonSpacing = strtod(GrabAttribute(lonVar, 1).c_str(), NULL);

    const long minLonIndex = lower_bound(lonVals, lonmin, lonCnt);
    const long maxLonIndex = upper_bound(lonVals, lonmax, lonCnt);

    delete lonVals;
    lonCnt = (maxLonIndex - minLonIndex) + 1;
    lonVar->set_cur(minLonIndex);
    inputData.lonVals = new double[lonCnt];
    lonVar->get(inputData.lonVals, lonCnt);

    NcVar* reflectVar = NULL;
    reflectVar = radarFile.get_var("value");

    if ( reflectVar == NULL )
    {
        // Try this variable name
        reflectVar = radarFile.get_var("Reflectivity");
    }

    if (reflectVar == NULL)
    {
        cerr << "ERROR: invalid data file.  No variable called 'value'!\n";
        radarFile.close();
        return(inputData);
    }


    inputData.dataEdges = reflectVar->edges();	// [0] - time, [1] - lat, [2] - lon
    inputData.dataEdges[1] = latCnt;
    inputData.dataEdges[2] = lonCnt;
    inputData.dataVals = new double[inputData.dataEdges[0] * inputData.dataEdges[1] * inputData.dataEdges[2]];
    reflectVar->set_cur(0, minLatIndex, minLonIndex);
    reflectVar->get(inputData.dataVals, inputData.dataEdges);

    inputData.var_LongName = GrabAttribute(reflectVar, 0);
    inputData.var_Units = "dBZ";//GrabAttribute(reflectVar, 1);


    NcVar* timeVar = radarFile.get_var("time");

    if (NULL == timeVar)
    {
        cerr << "ERROR: invalid data file.  No variable called 'time'!\n";
        radarFile.close();
        return(inputData);
    }

    inputData.scanTime = timeVar->as_long(0);
    inputData.timeUnits = GrabAttribute(timeVar, 0);

    NcAtt* titleAttrib = radarFile.get_att("title");

    inputData.fileTitle = (NULL == titleAttrib ? "" : titleAttrib->as_string(0));

    delete titleAttrib;

    radarFile.close();

    // Success!
    inputData.inputFilename = filename;


    return(inputData);
}
void ReadCFTimeDataFromNcFile(
	NcFile * ncfile,
	const std::string & strFilename,
	std::vector<Time> & vecTimes,
	bool fWarnOnMissingCalendar
) {
	// Empty existing Time vector
	vecTimes.clear();

	// Get time dimension
	NcDim * dimTime = ncfile->get_dim("time");
	if (dimTime == NULL) {
		_EXCEPTION1("Dimension \"time\" not found in file \"%s\"",
			strFilename.c_str());
	}

	// Get time variable
	NcVar * varTime = ncfile->get_var("time");
	if (varTime == NULL) {
		_EXCEPTION1("Variable \"time\" not found in file \"%s\"",
			strFilename.c_str());
	}
	if (varTime->num_dims() != 1) {
		_EXCEPTION1("Variable \"time\" has more than one dimension in file \"%s\"",
			strFilename.c_str());
	}
	if (strcmp(varTime->get_dim(0)->name(), "time") != 0) {
		_EXCEPTION1("Variable \"time\" does not have dimension \"time\" in file \"%s\"",
			strFilename.c_str());
	}

	// Calendar attribute
	NcAtt * attTimeCal = varTime->get_att("calendar");
	std::string strCalendar;
	if (attTimeCal == NULL) {
		if (fWarnOnMissingCalendar) {
			Announce("WARNING: Variable \"time\" is missing \"calendar\" attribute; assuming \"standard\"");
		}
		strCalendar = "standard";
	} else {
		strCalendar = attTimeCal->as_string(0);
	}
	Time::CalendarType eCalendarType =
		Time::CalendarTypeFromString(strCalendar);

	// Units attribute
	NcAtt * attTimeUnits = varTime->get_att("units");
	if (attTimeUnits == NULL) {
		_EXCEPTION1("Variable \"time\" is missing \"units\" attribute in file \"%s\"",
			strFilename.c_str());
	}
	std::string strTimeUnits = attTimeUnits->as_string(0);

	// Load in time data
	DataVector<int> vecTimeInt;
	DataVector<float> vecTimeFloat;
	DataVector<double> vecTimeDouble;
	DataVector<ncint64> vecTimeInt64;

	if (varTime->type() == ncInt) {
		vecTimeInt.Initialize(dimTime->size());
		varTime->set_cur((long)0);
		varTime->get(&(vecTimeInt[0]), dimTime->size());

	} else if (varTime->type() == ncFloat) {
		vecTimeFloat.Initialize(dimTime->size());
		varTime->set_cur((long)0);
		varTime->get(&(vecTimeFloat[0]), dimTime->size());

	} else if (varTime->type() == ncDouble) {
		vecTimeDouble.Initialize(dimTime->size());
		varTime->set_cur((long)0);
		varTime->get(&(vecTimeDouble[0]), dimTime->size());

	} else if (varTime->type() == ncInt64) {
		vecTimeInt64.Initialize(dimTime->size());
		varTime->set_cur((long)0);
		varTime->get(&(vecTimeInt64[0]), dimTime->size());

	} else {
		_EXCEPTION1("Variable \"time\" has invalid type "
			"(expected \"int\", \"int64\", \"float\" or \"double\")"
			" in file \"%s\"", strFilename.c_str());
	}

	for (int t = 0; t < dimTime->size(); t++) {
		Time time(eCalendarType);
		if (varTime->type() == ncInt) {
			time.FromCFCompliantUnitsOffsetInt(
				strTimeUnits,
				vecTimeInt[t]);

		} else if (varTime->type() == ncFloat) {
			time.FromCFCompliantUnitsOffsetDouble(
				strTimeUnits,
				static_cast<double>(vecTimeFloat[t]));

		} else if (varTime->type() == ncDouble) {
			time.FromCFCompliantUnitsOffsetDouble(
				strTimeUnits,
				vecTimeDouble[t]);

		} else if (varTime->type() == ncInt64) {
			time.FromCFCompliantUnitsOffsetInt(
				strTimeUnits,
				(int)(vecTimeInt64[t]));

		}

		vecTimes.push_back(time);
	}
}
void CopyNcVarAttributes(
	NcVar * varIn,
	NcVar * varOut
) {
	for (int a = 0; a < varIn->num_atts(); a++) {
		NcAtt * att = varIn->get_att(a);
		long num_vals = att->num_vals();

		NcValues * pValues = att->values();

		if (att->type() == ncByte) {
			varOut->add_att(att->name(), num_vals,
				(const ncbyte*)(pValues->base()));

		} else if (att->type() == ncChar) {
			varOut->add_att(att->name(), num_vals,
				(const char*)(pValues->base()));

		} else if (att->type() == ncShort) {
			varOut->add_att(att->name(), num_vals,
				(const short*)(pValues->base()));

		} else if (att->type() == ncInt) {
			varOut->add_att(att->name(), num_vals,
				(const int*)(pValues->base()));

		} else if (att->type() == ncFloat) {
			varOut->add_att(att->name(), num_vals,
				(const float*)(pValues->base()));

		} else if (att->type() == ncDouble) {
			varOut->add_att(att->name(), num_vals,
				(const double*)(pValues->base()));

		} else {
			_EXCEPTIONT("Invalid attribute type");
		}

		delete pValues;
	}
}
Exemple #13
0
//
// Reads variable data from dump file
//
bool DataVar::initFromFile(const string& filename, const_DomainChunk_ptr dom)
{
    cleanup();
    
#if ESYS_HAVE_NETCDF
    NcError ncerr(NcError::silent_nonfatal);    
    NcFile* input = new NcFile(filename.c_str());
    if (!input->is_valid()) {
        cerr << "Could not open input file " << filename << "." << endl;
        delete input;
        return false;
    }

    NcDim* dim;
    NcAtt* att;

    att = input->get_att("type_id");
    int typeID = att->as_int(0);
    if (typeID != 2) {
        cerr << "WARNING: Only expanded data supported!" << endl;
        delete input;
        return false;
    }

    att = input->get_att("rank");
    rank = att->as_int(0);

    dim = input->get_dim("num_data_points_per_sample");
    ptsPerSample = dim->size();

    att = input->get_att("function_space_type");
    funcSpace = att->as_int(0);

    centering = dom->getCenteringForFunctionSpace(funcSpace);

    dim = input->get_dim("num_samples");
    numSamples = dim->size();

#ifdef _DEBUG
    cout << varName << ":\t" << numSamples << " samples,  "
        << ptsPerSample << " pts/s,  rank: " << rank << endl;
#endif

    domain = dom;
    NodeData_ptr nodes = domain->getMeshForFunctionSpace(funcSpace);
    if (nodes == NULL) {
        delete input;
        return false;
    }

    meshName = nodes->getName();
    siloMeshName = nodes->getFullSiloName();
    initialized = true;

    size_t dimSize = 1;
    vector<long> counts;

    if (rank > 0) {
        dim = input->get_dim("d0");
        int d = dim->size();
        shape.push_back(d);
        counts.push_back(d);
        dimSize *= d;
    }
    if (rank > 1) {
        dim = input->get_dim("d1");
        int d = dim->size();
        shape.push_back(d);
        counts.push_back(d);
        dimSize *= d;
    }
    if (rank > 2) {
        cerr << "WARNING: Rank " << rank << " data is not supported!\n";
        initialized = false;
    }
 
    if (initialized && numSamples > 0) {
        sampleID.insert(sampleID.end(), numSamples, 0);
        NcVar* var = input->get_var("id");
        var->get(&sampleID[0], numSamples);

        size_t dataSize = dimSize*numSamples*ptsPerSample;
        counts.push_back(ptsPerSample);
        counts.push_back(numSamples);
        float* tempData = new float[dataSize];
        var = input->get_var("data");
        var->get(tempData, &counts[0]);

        const float* srcPtr = tempData;
        for (size_t i=0; i < dimSize; i++, srcPtr++) {
            float* c = averageData(srcPtr, dimSize);
            dataArray.push_back(c);
        }
        delete[] tempData;

        initialized = reorderSamples();
    }

    delete input;
#endif // ESYS_HAVE_NETCDF

    return initialized;
}
int main(void)
{
   // These will hold our pressure and temperature data.
   float presIn[NLAT][NLON];
   float tempIn[NLAT][NLON];

   // These will hold our latitudes and longitudes.
   float latsIn[NLAT];
   float lonsIn[NLON];
  
   // Change the error behavior of the netCDF C++ API by creating an
   // NcError object. Until it is destroyed, this NcError object will
   // ensure that the netCDF C++ API silently returns error codes on
   // any failure, and leaves any other error handling to the calling
   // program. In the case of this example, we just exit with an
   // NC_ERR error code.
   NcError err(NcError::silent_nonfatal);

   // Open the file and check to make sure it's valid.
   NcFile dataFile("sfc_pres_temp.nc", NcFile::ReadOnly);
   if(!dataFile.is_valid())
      return NC_ERR;
  
   // There are a number of inquiry functions in netCDF which can be
   // used to learn about an unknown netCDF file. In this case we know
   // that there are 2 netCDF dimensions, 4 netCDF variables, no
   // global attributes, and no unlimited dimension.
   if (dataFile.num_dims() != 2 || dataFile.num_vars() != 4 || 
       dataFile.num_atts() != 0 || dataFile.rec_dim() != 0)  
      return NC_ERR;
     
   // We get back a pointer to each NcVar we request. Get the
   // latitude and longitude coordinate variables.
   NcVar *latVar, *lonVar;
   if (!(latVar = dataFile.get_var("latitude")))
      return NC_ERR;
   if (!(lonVar = dataFile.get_var("longitude")))
      return NC_ERR;
       
   // Read the latitude and longitude coordinate variables into arrays
   // latsIn and lonsIn.
   if (!latVar->get(latsIn, NLAT))
      return NC_ERR;
   if (!lonVar->get(lonsIn, NLON))
      return NC_ERR;
       
   // Check the coordinate variable data. 
   for(int lat = 0; lat < NLAT; lat++)
      if (latsIn[lat] != START_LAT + 5. * lat)
	 return NC_ERR;
   
   // Check longitude values.
   for (int lon = 0; lon < NLON; lon++)
      if (lonsIn[lon] != START_LON + 5. * lon)
	 return NC_ERR;
   
   // We get back a pointer to each NcVar we request. 
   NcVar *presVar, *tempVar;
   if (!(presVar = dataFile.get_var("pressure")))
      return NC_ERR;
   if (!(tempVar = dataFile.get_var("temperature")))
      return NC_ERR;
       
   // Read the data. Since we know the contents of the file we know
   // that the data arrays in this program are the correct size to
   // hold all the data.
   if (!presVar->get(&presIn[0][0], NLAT, NLON))
      return NC_ERR;
   if (!tempVar->get(&tempIn[0][0], NLAT, NLON))
      return NC_ERR;
       
   // Check the data. 
   for (int lat = 0; lat < NLAT; lat++)
      for (int lon = 0; lon < NLON; lon++)
	 if (presIn[lat][lon] != SAMPLE_PRESSURE + (lon * NLAT + lat)
	     || tempIn[lat][lon] != SAMPLE_TEMP + .25 * (lon * NLAT + lat))
	    return NC_ERR;
   
   // Each of the netCDF variables has a "units" attribute. Let's read
   // them and check them.
   NcAtt *att;
   char *units;
   
   if (!(att = latVar->get_att("units")))
      return NC_ERR;
   units = att->as_string(0);
   if (strncmp(units, "degrees_north", strlen("degrees_north")))
      return NC_ERR;
   // Attributes and attribute values should be deleted by the caller
   // when no longer needed, to prevent memory leaks.
   delete units;
   delete att;

   if (!(att = lonVar->get_att("units")))
      return NC_ERR;
   units = att->as_string(0);
   if (strncmp(units, "degrees_east", strlen("degrees_east")))
      return NC_ERR;
   delete units;
   delete att;
   
   if (!(att = presVar->get_att("units")))
      return NC_ERR;
   units = att->as_string(0);
   if (strncmp(units, "hPa", strlen("hPa")))
      return NC_ERR;
   delete units;
   delete att;
   
   if (!(att = tempVar->get_att("units")))
      return NC_ERR;
   units = att->as_string(0);
   if (strncmp(units, "celsius", strlen("celsius")))
      return NC_ERR;
   delete units;
   delete att;

   // The file will be automatically closed by the destructor. This
   // frees up any internal netCDF resources associated with the file,
   // and flushes any buffers.
   cout << "*** SUCCESS reading example file sfc_pres_temp.nc!" << endl;

   return 0;
}
bool
RemapWidget::getVolumeInfo(QString volfile,
			   int &skipheaderbytes,
			   uchar &voxelType,
			   int &voxelUnit,
			   float &vx, float &vy, float &vz,
			   QString &description,
			   QList<float> &rawMap,
			   QList<uchar> &pvlMap,
			   int &depth,
			   int &width,
			   int &height)
{
  NcError err(NcError::verbose_nonfatal);

  NcFile pvlFile(volfile.toAscii().data(), NcFile::ReadOnly);

  if (!pvlFile.is_valid())
    {
      QMessageBox::information(0, "Error",
       QString("%1 is not a valid preprocessed volume file").arg(volfile));
      return false;
    }

  int i;
  NcAtt *att;
  char *attval;
  QString pvalue;

  att = pvlFile.get_att("description");
  if (att)
    {
      attval = att->as_string(0);
      description = attval;
      delete [] attval;
    }

  att = pvlFile.get_att("voxeltype");
  if (att)
    {
      attval = att->as_string(0);
      pvalue = attval;
      if (pvalue == "unsigned char")
	voxelType = Raw2Pvl::_UChar;
      if (pvalue == "char")
	voxelType = Raw2Pvl::_Char;
      if (pvalue == "unsigned short")
	voxelType = Raw2Pvl::_UShort;
      if (pvalue == "short")
	voxelType = Raw2Pvl::_Short;
      if (pvalue == "int")
	voxelType = Raw2Pvl::_Int;
      if (pvalue == "float")
	voxelType = Raw2Pvl::_Float;
      delete [] attval;
    }


  att = pvlFile.get_att("voxelunit");
  if (att)
    { 
      attval = att->as_string(0);
      pvalue = attval;
      voxelUnit = Raw2Pvl::_Nounit;
      if (pvalue == "angstrom")
	voxelUnit = Raw2Pvl::_Angstrom;
      else if (pvalue == "nanometer")
	voxelUnit = Raw2Pvl::_Nanometer;
      else if (pvalue == "micron")
	voxelUnit = Raw2Pvl::_Micron;
      else if (pvalue == "millimeter")
	voxelUnit = Raw2Pvl::_Millimeter;
      else if (pvalue == "centimeter")
	voxelUnit = Raw2Pvl::_Centimeter;
      else if (pvalue == "meter")
	voxelUnit = Raw2Pvl::_Meter;
      else if (pvalue == "kilometer")
	voxelUnit = Raw2Pvl::_Kilometer;
      else if (pvalue == "parsec")
	voxelUnit = Raw2Pvl::_Parsec;
      else if (pvalue == "kiloparsec")
	voxelUnit = Raw2Pvl::_Kiloparsec;
      delete [] attval;
    }
  
  
  att = pvlFile.get_att("gridsize");
  if (att)
    {
      depth = att->as_int(0);
      width = att->as_int(1);
      height = att->as_int(2);
    }

  att = pvlFile.get_att("voxelsize");
  if (att)
    {
      vx = att->as_float(0);
      vy = att->as_float(1);
      vz = att->as_float(2);
    }

  att = pvlFile.get_att("skipheaderbytes");
  if (att)
    skipheaderbytes = att->as_int(0);
  
  att = pvlFile.get_att("mapraw");
  if (att)
    {
      for(i=0; i<att->num_vals(); i++)
	rawMap.append(att->as_float(i));
  
      att = pvlFile.get_att("mappvl");
      for(i=0; i<att->num_vals(); i++)
	pvlMap.append(att->as_ncbyte(i));
    }

  pvlFile.close();
  return true;
}
vtkDataArray *
avtS3DFileFormat::GetVar(int timeState, int domain, const char *varname)
{
    debug5 << "avtS3DFileFormat::GetVar( timeState=" << timeState << ", domain="
        << domain << ", varname=" << varname << ")" << endl;

    // Calculate the timestep directory that the data lives in.
    char *pathcopy = strdup(mainFilename);
    string dir = parse_dirname(pathcopy);
    string timestepDir = CreateStringFromDouble(fileTimes[timeState]);
    debug4 << "Timestep directory is <" << timestepDir <<  ">" << endl;
    
    // Figure out how big this piece is.
    CalculateSubpiece(domain);

    // Open up the NetCDF file.
    char path[256];
    SNPRINTF(path,256,"%s%s%s%sfield.%05d",dir.c_str(),VISIT_SLASH_STRING, timestepDir.c_str(), VISIT_SLASH_STRING, domain);
    debug5 << "avtS3DFileFormat::GetVar: Full path to data file is " << path << endl;

    NcFile nf(path);
    if (!nf.is_valid())
    {
        debug1 << nc_strerror(NcError().get_err()) << endl;
        EXCEPTION1(InvalidFilesException, path);
    }
    debug5 << "avtS3DFileFormat::GetVar: Got valid file." << endl;

    // Pull out the appropriate variable.
    NcVar *v = nf.get_var(varname);
    if (!v)
    {
        debug1 << nc_strerror(NcError().get_err()) << endl;
        EXCEPTION1(InvalidVariableException, varname);
    }

    // Check if it fits the size of the mesh.  Always node-centered, remember.
    int ntuples = localDims[0] * localDims[1] * localDims[2];
    debug5 << "ntuples:" << ntuples << endl;
    int nvals = v->num_vals();
    if (ntuples != nvals)
    {
        debug1 << "The variable " << v->name() <<
                  " does not conform to its mesh (" << nvals << " != " << 
                  ntuples << ")" << endl;
        EXCEPTION1(InvalidVariableException, v->name());
    }

    // Set up the VTK dataset.
    vtkFloatArray *rv = vtkFloatArray::New();
    rv->SetNumberOfTuples(ntuples);
    float *p = (float*)rv->GetVoidPointer(0);
    NcValues *input = v->values();
    if (!input)
    {
        debug1 << nc_strerror(NcError().get_err()) << endl;
        EXCEPTION1(InvalidVariableException, v->name());
    }

    // Get the scaling factor.
    NcAtt *scaling = v->get_att(NcToken("scale_factor"));
    float scaling_factor = 1;
    if (scaling)
    {
        scaling_factor = scaling->as_float(0);
        debug5 << "avtS3DFileFormat::GetVar: Set the scaling factor as " << scaling_factor << endl;
    }

    // Process the variable into the returned data.
    float *base = (float*)input->base();
    for(int i=0;i<ntuples;i++)
    {
        p[i] = *(base + i) * scaling_factor;
    }

    return rv;
}
int main(int argc, char** argv) {

	NcError error(NcError::silent_nonfatal);

try {
	// Input filename
	std::string strInputFile;

	// Output mesh filename
	std::string strOutputFile;

	// Polynomial degree per element
	int nP = 2;

	// Parse the command line
	BeginCommandLine()
		CommandLineString(strInputFile, "in", "");
		CommandLineString(strOutputFile, "out", "");
		//CommandLineInt(nP, "np", 2);
		//CommandLineBool(fCGLL, "cgll");

		ParseCommandLine(argc, argv);
	EndCommandLine(argv)

	// Check file names
	if (strInputFile == "") {
		std::cout << "ERROR: No input file specified" << std::endl;
		return (-1);
	}
	if (strOutputFile == "") {
		std::cout << "ERROR: No output file specified" << std::endl;
		return (-1);
	}
	if (nP < 1) {
		std::cout << "ERROR: --np must be >= 2" << std::endl;
		return (-1);
	}

	AnnounceBanner();

	// Load input mesh
	AnnounceStartBlock("Loading input mesh");

	Mesh meshIn(strInputFile);
	meshIn.RemoveZeroEdges();

	AnnounceEndBlock("Done");

	// Construct edge map
	AnnounceStartBlock("Constructing edge map");

	meshIn.ConstructEdgeMap();

	AnnounceEndBlock("Done");

	// Build connectivity vector using edge map
	AnnounceStartBlock("Constructing connectivity");

    std::vector< std::set<int> > vecConnectivity;
    int err = GenerateConnectivityData(meshIn, vecConnectivity);
    if (err) return err;

	AnnounceEndBlock("Done");

	// Open output file
	AnnounceStartBlock("Writing connectivity file");

	NcFile ncmesh(strInputFile.c_str(), NcFile::ReadOnly);

	NcVar * varLat = ncmesh.get_var("grid_center_lat");
	NcVar * varLon = ncmesh.get_var("grid_center_lon");

	// Check if center latitudes and longitudes are already available
	DataArray1D<double> dAllLats;
	DataArray1D<double> dAllLons;

	bool fConvertLatToDegrees = true;
	bool fConvertLonToDegrees = true;

	if ((varLat == NULL) || (varLon == NULL)) {
		Announce("grid_center_lat not found, recalculating face centers");
	} else {
		Announce("grid_center_lat found in file, loading values");

		if (varLat->get_dim(0)->size() != vecConnectivity.size()) {
			_EXCEPTIONT("grid_center_lat dimension mismatch");
		}
		if (varLon->get_dim(0)->size() != vecConnectivity.size()) {
			_EXCEPTIONT("grid_center_lon dimension mismatch");
		}

		dAllLats.Allocate(vecConnectivity.size());
		varLat->set_cur((long)0);
		varLat->get(dAllLats, vecConnectivity.size());

		NcAtt * attLatUnits = varLat->get_att("units");
		std::string strLatUnits = attLatUnits->as_string(0);
		if (strLatUnits == "degrees") {
			fConvertLatToDegrees = false;
		}

		dAllLons.Allocate(vecConnectivity.size());
		varLon->set_cur((long)0);
		varLon->get(dAllLons, vecConnectivity.size());

		NcAtt * attLonUnits = varLon->get_att("units");
		std::string strLonUnits = attLonUnits->as_string(0);
		if (strLonUnits == "degrees") {
			fConvertLonToDegrees = false;
		}

	}

	// Write connectiivty file
	FILE * fp = fopen(strOutputFile.c_str(), "w");
	fprintf(fp, "%lu\n", vecConnectivity.size());
	for (size_t f = 0; f < vecConnectivity.size(); f++) {
		double dLon;
		double dLat;

		if ((varLat == NULL) || (varLon == NULL)) {
			Node nodeCentroid;
			for (int i = 0; i < meshIn.faces[f].edges.size(); i++) {
				nodeCentroid.x += meshIn.nodes[meshIn.faces[f][i]].x;
				nodeCentroid.y += meshIn.nodes[meshIn.faces[f][i]].y;
				nodeCentroid.z += meshIn.nodes[meshIn.faces[f][i]].z;
			}
			double dMagnitude = nodeCentroid.Magnitude();

			nodeCentroid.x /= dMagnitude;
			nodeCentroid.y /= dMagnitude;
			nodeCentroid.z /= dMagnitude;

			dLon = atan2(nodeCentroid.y, nodeCentroid.x);
			dLat = asin(nodeCentroid.z);

			if (dLon < 0.0) {
				dLon += 2.0 * M_PI;
			}

		} else {
			dLon = dAllLons[f];
			dLat = dAllLats[f];
		}

		if (fConvertLonToDegrees) {
			dLon *= 180.0 / M_PI;
		}
		if (fConvertLatToDegrees) {
			dLat *= 180.0 / M_PI;
		}

		fprintf(fp, "%1.14f,", dLon);
		fprintf(fp, "%1.14f,", dLat);
		fprintf(fp, "%lu", vecConnectivity[f].size());

		std::set<int>::const_iterator iter = vecConnectivity[f].begin();
		for (; iter != vecConnectivity[f].end(); iter++) {
			fprintf(fp, ",%i", *iter);
		}
		if (f != vecConnectivity.size()-1) {
			fprintf(fp,"\n");
		}
	}
	fclose(fp);

	AnnounceEndBlock("Done");

	// Announce
	AnnounceBanner();

	return (0);

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

} catch(...) {
	return (-2);
}
}
int 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();
}
Exemple #19
0
void PolygonManager::init()
{
    string fileName;
    ConfigTools::read("parcel_polygon_file", fileName);
    NOTICE("PolygonManager::init", "Reading polygons from \""+fileName+"\" ...");
    NcFile file(fileName.c_str(), NcFile::ReadOnly);
    if (!file.is_valid()) {
        REPORT_ERROR(string("Failed to open file "+fileName+"."))
    }

    NcError ncError(NcError::silent_nonfatal);

    if (TimeManager::onLine()) {
        NcAtt *timeAtt = file.get_att("time");
        NcAtt *timeStepAtt = file.get_att("time_step");
        NcAtt *stepsAtt = file.get_att("steps");
        if (timeAtt != NULL && timeStepAtt != NULL && stepsAtt != NULL) {
            TimeManager::reset();
            double dt = timeStepAtt->as_double(0);
            double second = timeAtt->as_double(0);
            double steps = stepsAtt->as_int(0);
            TimeManager::setClock(dt, second, steps);
        }
    }
    NcDim *numVertexDim = file.get_dim("num_total_vertex");
    if (numVertexDim == NULL) {
        Message message;
        message << "Failed to find \"num_total_vertex\" dimension in file \"";
        message << fileName << "\"!";
        REPORT_ERROR(message.str());
    }
    NcDim *numEdgeDim = file.get_dim("num_total_edge");
    if (numEdgeDim == NULL) {
        Message message;
        message << "Failed to find \"num_total_edge\" dimension in file \"";
        message << fileName << "\"!";
        REPORT_ERROR(message.str());
    }
    NcDim *numPolygonDim = file.get_dim("num_total_polygon");
    if (numPolygonDim == NULL) {
        Message message;
        message << "Failed to find \"num_total_polygon\" dimension in file \"";
        message << fileName << "\"!";
        REPORT_ERROR(message.str());
    }
    int numVertex = static_cast<int>(numVertexDim->size());
    int numEdge = static_cast<int>(numEdgeDim->size());
    int numPolygon = static_cast<int>(numPolygonDim->size());
    // -------------------------------------------------------------------------
    // vertices part
    vertices.create(numVertex);
    double *oldVtxLon = new double[numVertex];
    double *oldVtxLat = new double[numVertex];
    double *oldVtxLev = new double[numVertex];
    double *newVtxLon = new double[numVertex];
    double *newVtxLat = new double[numVertex];
    double *newVtxLev = new double[numVertex];
    file.get_var("old_vertex_lon")->get(oldVtxLon, numVertex);
    file.get_var("old_vertex_lat")->get(oldVtxLat, numVertex);
    file.get_var("new_vertex_lon")->get(newVtxLon, numVertex);
    file.get_var("new_vertex_lat")->get(newVtxLat, numVertex);
    if (file.get_var("old_vertex_lev") != NULL) {
        file.get_var("old_vertex_lev")->get(oldVtxLev, numVertex);
        file.get_var("new_vertex_lev")->get(newVtxLev, numVertex);
    } else {
        for (int i = 0; i < vertices.size(); ++i) {
            oldVtxLev[i] = 0.0;
            newVtxLev[i] = 0.0;
        }
    }
    // change the units from degree to rad
    for (int i = 0; i < numVertex; ++i) {
        oldVtxLon[i] /= Rad2Deg;
        oldVtxLat[i] /= Rad2Deg;
        newVtxLon[i] /= Rad2Deg;
        newVtxLat[i] /= Rad2Deg;
    }
    Vertex *vertexMap[vertices.size()];
    Vertex *vertex = vertices.front();
    for (int i = 0; i < vertices.size(); ++i) {
        vertexMap[i] = vertex;
        vertex->setCoordinate(newVtxLon[i], newVtxLat[i], newVtxLev[i], NewTimeLevel);
        vertex->setCoordinate(oldVtxLon[i], oldVtxLat[i], oldVtxLev[i], OldTimeLevel);
        vertex = vertex->next;
    }
    delete [] newVtxLon;
    delete [] newVtxLat;
    delete [] newVtxLev;
    delete [] oldVtxLon;
    delete [] oldVtxLat;
    delete [] oldVtxLev;
    // -------------------------------------------------------------------------
    // edges part
    edges.create(numEdge);
    int *firstPoint = new int[numEdge];
    int *secondPoint = new int[numEdge];
    file.get_var("first_point_idx")->get(firstPoint, numEdge);
    file.get_var("second_point_idx")->get(secondPoint, numEdge);
    Edge *edgeMap[edges.size()];
    Edge *edge = edges.front();
    for (int i = 0; i < edges.size(); ++i) {
        edgeMap[i] = edge;
        edge->linkEndPoint(FirstPoint, vertexMap[firstPoint[i]-1]);
        edge->linkEndPoint(SecondPoint, vertexMap[secondPoint[i]-1]);
        edge->calcNormVector();
        edge = edge->next;
    }
    delete [] firstPoint;
    delete [] secondPoint;
    // test point
    double *oldTestLon = new double[numEdge];
    double *oldTestLat = new double[numEdge];
    double *newTestLon = new double[numEdge];
    double *newTestLat = new double[numEdge];
    file.get_var("old_testpoint_lon")->get(oldTestLon, numEdge);
    file.get_var("old_testpoint_lat")->get(oldTestLat, numEdge);
    file.get_var("new_testpoint_lon")->get(newTestLon, numEdge);
    file.get_var("new_testpoint_lat")->get(newTestLat, numEdge);
    for (int i = 0; i < numEdge; ++i) {
        oldTestLon[i] /= Rad2Deg;
        oldTestLat[i] /= Rad2Deg;
        newTestLon[i] /= Rad2Deg;
        newTestLat[i] /= Rad2Deg;
    }
    edge = edges.front();
    for (int i = 0; i < numEdge; ++i) {
        Vertex *testPoint = edge->getTestPoint();
        testPoint->setCoordinate(oldTestLon[i], oldTestLat[i], OldTimeLevel);
        testPoint->setCoordinate(newTestLon[i], newTestLat[i], NewTimeLevel);
        edge = edge->next;
    }
    delete [] oldTestLon;
    delete [] oldTestLat;
    delete [] newTestLon;
    delete [] newTestLat;
    // -------------------------------------------------------------------------
    // polygons part
    polygons.create(numPolygon);
    int edgeNum[numPolygon];
    file.get_var("edge_num")->get(edgeNum, numPolygon);
    int numEdgeIdx = static_cast<int>(file.get_dim("num_edge_idx")->size());
    int *edgeIdx = new int[numEdgeIdx];
    int *edgeOnt = new int[numEdgeIdx];
    file.get_var("edge_idx")->get(edgeIdx, numEdgeIdx);
    file.get_var("edge_ont")->get(edgeOnt, numEdgeIdx);
    Polygon *polygon = polygons.front();
    int counter = 0;
    for (int i = 0; i < polygons.size(); ++i) {
        for (int j = 0; j < edgeNum[i]; ++j) {
            OrientStatus orient;
            if (edgeOnt[counter] == 0) {
                orient = OrientLeft;
            } else if (edgeOnt[counter] == 1) {
                orient = OrientRight;
            } else {
                string message = "Invalid edge_ont in file "+fileName+".";
                REPORT_ERROR(message.c_str());
            }
            edgeMap[edgeIdx[counter]-1]->linkPolygon(orient, polygon);
            counter++;
        }
        polygon->edgePointers.ring();
        // calculate the angles
        EdgePointer *edgePointer = polygon->edgePointers.front();
        for (int j = 0; j < polygon->edgePointers.size(); ++j) {
            edgePointer->calcAngle();
            edgePointer = edgePointer->next;
        }
        polygon->calcArea();
        polygon = polygon->next;
    }
    delete [] edgeIdx;
    delete [] edgeOnt;
    // -------------------------------------------------------------------------
    file.close();
}
Exemple #20
0
eavlNetCDFImporter::eavlNetCDFImporter(const string &filename)
{
    file = new NcFile(filename.c_str(), NcFile::ReadOnly);
     
    if (!file->is_valid())
    {
        THROW(eavlException,"Couldn't open file!\n");
    }

    if (debugoutput) cerr << "num_dims="<<file->num_dims()<<endl;
    if (debugoutput) cerr << "num_vars="<<file->num_vars()<<endl;
    if (debugoutput) cerr << "num_atts="<<file->num_atts()<<endl;

    for (int i=0; i<file->num_dims(); i++)
    {
        NcDim *d = file->get_dim(i);
        if (debugoutput) cerr << "  dim["<<i<<"]: name="<<d->name()<<" size="<<d->size()<<endl;
    }

    for (int i=0; i<file->num_atts(); i++)
    {
        NcAtt *a = file->get_att(i);
        if (debugoutput) cerr << "  att["<<i<<"]: name="<<a->name()<<" numvals="<<a->num_vals()<<endl;
    }

    bool found_grid = false;

    for (int i=0; i<file->num_vars(); i++)
    {
        NcVar *v = file->get_var(i);
        if (debugoutput) 
        {
            cerr << "  var["<<i<<"]: name="<<v->name();
            cerr << "  ndims="<<v->num_dims();
            cerr << "  dims = ";
            for (int j=0; j<v->num_dims(); j++)
            {
                cerr << v->get_dim(j)->name();
                if (j<v->num_dims()-1)
                    cerr << "*";
            }
            cerr << endl;
        }

        // Here's the condition for what we're going to use;
        // we only support one mesh for the moment, so we're picking one.
        // Also, the netcdf files we have have the time dim size as "1"
        if (v->num_dims() == 4 && string(v->get_dim(0)->name())=="time")
        {
            if (!found_grid)
            {
                dims.push_back(v->get_dim(1));
                dims.push_back(v->get_dim(2));
                dims.push_back(v->get_dim(3));
                found_grid = true;
                vars.push_back(v);
                if (debugoutput) cerr << "     * using as first real var\n";
            }
            else
            {
                if (string(v->get_dim(1)->name()) == dims[0]->name() &&
                    string(v->get_dim(2)->name()) == dims[1]->name() &&
                    string(v->get_dim(3)->name()) == dims[2]->name())
                {
                    vars.push_back(v);
                    if (debugoutput) cerr << "     * using as another var; matches the first real one's dims\n";
                }
            }
        }

    }
}
Exemple #21
0
bool
NetworkObject::loadNetCDF(QString flnm)
{
  m_fileName = flnm;

  NcError err(NcError::verbose_nonfatal);

  NcFile ncfFile(flnm.toLatin1().data(), NcFile::ReadOnly);
  NcAtt *att;
  NcVar *var;

  // ---- get gridsize -----
  att = ncfFile.get_att("gridsize");
  m_nX = att->as_int(0);
  m_nY = att->as_int(1);
  m_nZ = att->as_int(2);
  //------------------------

  // ---- get vertex centers -----
  var = ncfFile.get_var("vertex_centers");
  if (!var)
    var = ncfFile.get_var("vertex_center");
  if (!var)
    var = ncfFile.get_var("vertex_centres");
  if (!var)
    var = ncfFile.get_var("vertex_centre");
  
  int nv = var->get_dim(0)->size();
  float *vc = new float [3*nv];
  var->get(vc, nv, 3);
  m_vertexCenters.resize(nv);
  for(int i=0; i<nv; i++)
    m_vertexCenters[i] = Vec(vc[3*i+0], vc[3*i+1], vc[3*i+2]);
  delete [] vc;
  //------------------------


  // ---- get edges -----
  var = ncfFile.get_var("edge_neighbours");
  int ne = var->get_dim(0)->size();
  int *ed = new int [2*ne];
  var->get(ed, ne, 2);
  m_edgeNeighbours.resize(ne);
  for(int i=0; i<ne; i++)
    m_edgeNeighbours[i] = qMakePair(ed[2*i], ed[2*i+1]);
  delete [] ed;
  //------------------------


  Vec bmin = m_vertexCenters[0];
  Vec bmax = m_vertexCenters[0];
  for(int i=0; i<m_vertexCenters.count(); i++)
    {
      bmin = StaticFunctions::minVec(bmin, m_vertexCenters[i]);
      bmax = StaticFunctions::maxVec(bmax, m_vertexCenters[i]);
    }
  m_centroid = (bmin + bmax)/2;
  
  m_enclosingBox[0] = Vec(bmin.x, bmin.y, bmin.z);
  m_enclosingBox[1] = Vec(bmax.x, bmin.y, bmin.z);
  m_enclosingBox[2] = Vec(bmax.x, bmax.y, bmin.z);
  m_enclosingBox[3] = Vec(bmin.x, bmax.y, bmin.z);
  m_enclosingBox[4] = Vec(bmin.x, bmin.y, bmax.z);
  m_enclosingBox[5] = Vec(bmax.x, bmin.y, bmax.z);
  m_enclosingBox[6] = Vec(bmax.x, bmax.y, bmax.z);
  m_enclosingBox[7] = Vec(bmin.x, bmax.y, bmax.z);
    


//  QStringList vatt, eatt;
  int nvars = ncfFile.num_vars();
//  for (int i=0; i < nvars; i++)
//    {
//      var = ncfFile.get_var(i);      
//      QString attname = var->name();
//      attname.toLower();
//      if (attname.contains("vertex_") &&
//	  ( attname != "vertex_centers" ||
//	    attname != "vertex_centres"))
//	vatt.append(attname);
//      else if (attname.contains("edge_") &&
//	       attname != "edge_neighbours")
//	eatt.append(attname);
//    }

  m_vertexAttribute.clear();
  m_edgeAttribute.clear();

  m_vertexRadiusAttribute = -1;
  m_edgeRadiusAttribute = -1;

  int vri = 0;
  int eri = 0;
  for (int i=0; i < nvars; i++)
    {
      var = ncfFile.get_var(i);      
      QString attname = var->name();
      attname.toLower();

      if (attname.contains("vertex_") &&
	  attname != "vertex_center" &&
	  attname != "vertex_centre" &&
	  attname != "vertex_centers" &&
	  attname != "vertex_centres")
	{
	  if (attname == "vertex_radius")
	    m_vertexRadiusAttribute = vri;
	  vri++;

	  QVector<float> val;
	  val.clear();

	  if (var->type() == ncByte || var->type() == ncChar)
	    {
	      uchar *v = new uchar[nv];
	      var->get((ncbyte *)v, nv);
	      for(int j=0; j<nv; j++)
		val.append(v[j]);
	      delete [] v;
	    }
	  else if (var->type() == ncShort)
	    {
	      short *v = new short[nv];
	      var->get((short *)v, nv);
	      for(int j=0; j<nv; j++)
		val.append(v[j]);
	      delete [] v;
	    }
	  else if (var->type() == ncInt)
	    {
	      int *v = new int[nv];
	      var->get((int *)v, nv);
	      for(int j=0; j<nv; j++)
		val.append(v[j]);
	      delete [] v;
	    }
	  else if (var->type() == ncFloat)
	    {
	      float *v = new float[nv];
	      var->get((float *)v, nv);
	      for(int j=0; j<nv; j++)
		val.append(v[j]);
	      delete [] v;
	    }

	  if (val.count() > 0)
	    m_vertexAttribute.append(qMakePair(attname, val));
	}
      else if (attname.contains("edge_") &&
	       attname != "edge_neighbours")
	{
	  if (attname == "edge_radius")
	    m_edgeRadiusAttribute = eri;
	  eri++;

	  QVector<float> val;
	  val.clear();

	  if (var->type() == ncByte || var->type() == ncChar)
	    {
	      uchar *v = new uchar[ne];
	      var->get((ncbyte *)v, ne);
	      for(int j=0; j<ne; j++)
		val.append(v[j]);
	      delete [] v;
	    }
	  else if (var->type() == ncShort)
	    {
	      short *v = new short[ne];
	      var->get((short *)v, ne);
	      for(int j=0; j<ne; j++)
		val.append(v[j]);
	      delete [] v;
	    }
	  else if (var->type() == ncInt)
	    {
	      int *v = new int[ne];
	      var->get((int *)v, ne);
	      for(int j=0; j<ne; j++)
		val.append(v[j]);
	      delete [] v;
	    }
	  else if (var->type() == ncFloat)
	    {
	      float *v = new float[ne];
	      var->get((float *)v, ne);
	      for(int j=0; j<ne; j++)
		val.append(v[j]);
	      delete [] v;
	    }

	  if (val.count() > 0)
	    m_edgeAttribute.append(qMakePair(attname, val));
	}
    }

  ncfFile.close();
  
  if (!Global::batchMode())
    {
      QString str;
      str = QString("Grid Size : %1 %2 %3\n").arg(m_nX).arg(m_nY).arg(m_nZ);
      str += QString("Vertices : %1\n").arg(m_vertexCenters.count());
      str += QString("Edges : %1\n").arg(m_edgeNeighbours.count());
      str += QString("\n");
      str += QString("Vertex Attributes : %1\n").arg(m_vertexAttribute.count());
      for(int i=0; i<m_vertexAttribute.count(); i++)
	str += QString(" %1\n").arg(m_vertexAttribute[i].first);
      str += QString("\n");
      str += QString("Edge Attributes : %1\n").arg(m_edgeAttribute.count());
      for(int i=0; i<m_edgeAttribute.count(); i++)
	str += QString(" %1\n").arg(m_edgeAttribute[i].first);
      
      QMessageBox::information(0, "Network loaded", str);
    }

  m_Vatt = 0;
  m_Eatt = 0;
  m_Vminmax.clear();
  m_Eminmax.clear();
  m_userVminmax.clear();
  m_userEminmax.clear();

  for(int i=0; i<m_vertexAttribute.count(); i++)
    {
      float vmin = m_vertexAttribute[i].second[0];
      float vmax = m_vertexAttribute[i].second[0];
      for(int j=1; j<m_vertexAttribute[i].second.count(); j++)
	{
	  vmin = qMin((float)m_vertexAttribute[i].second[j], vmin);
	  vmax = qMax((float)m_vertexAttribute[i].second[j], vmax);
	}
      m_Vminmax.append(qMakePair(vmin, vmax));
      m_userVminmax.append(qMakePair((vmin+vmax)/2, vmax));
    }


  for(int i=0; i<m_edgeAttribute.count(); i++)
    {
      float emin = m_edgeAttribute[i].second[0];
      float emax = m_edgeAttribute[i].second[0];
      for(int j=1; j<m_edgeAttribute[i].second.count(); j++)
	{
	  emin = qMin((float)m_edgeAttribute[i].second[j], emin);
	  emax = qMax((float)m_edgeAttribute[i].second[j], emax);
	}
      m_Eminmax.append(qMakePair(emin, emax));
      m_userEminmax.append(qMakePair((emin+emax)/2, emax));
    }

  return true;
}