Jython code to read data from HDF/netCDF/etc files

Post any questions, ideas, or topics related to Jython and Python scripting.
Post Reply
User avatar
Posts: 296
Joined: Tue Dec 23, 2008 3:40 pm

Jython code to read data from HDF/netCDF/etc files

Post by tomw »

There are times when McV cannot understand the structure of some HDF or NetCDF (or other file types supported by the netCDF/java library), and you cannot make NcML that helps. All may not be lost. It still might be possible to write a little Jython code, put it into your Jython User Library, and then write a small Formula to call it.

I offer the following, very simple and very "hard-wired" example (see all the caveats, below!!):

Code: Select all

def testhdf(filename, paramname):
    from ucar.nc2 import NetcdfFile as nf;
    from visad import Gridded2DSet, RealTupleType;
    fn = filename;
    pn = paramname;
    a = nf.open(fn);
    #vars = a.getVariables();
    #print vars;
    lat = a.findVariable("Latitude");
    lon = a.findVariable("Longitude");
    llon = lon.read().get1DJavaArray(java.lang.Float);
    llat = lat.read().get1DJavaArray(java.lang.Float);
    ttst = tst.read().get1DJavaArray(java.lang.Float);
    shape = lat.getShape();
    for i in xrange(len(llat)):
      if (llat[i]<-99.):
        llat[i] = java.lang.Float.NaN;
      if (llon[i] < -999.):
        llon[i] = java.lang.Float.NaN;
      if (ttst[i] < -999.):
        ttst[i] = java.lang.Float.NaN;
    gs = Gridded2DSet(RealTupleType.SpatialEarth2DTuple, [llon,llat], shape[1], shape[0], None, None, None,0,0);
    ff = field(gs, "SST", ttst);
    return ff;

And then, to use this to display the "paramname" variable, just create a new Formula, with this as the formula:

Code: Select all

testhdf(filename[isuser=true, default=/temp/AIRS.hdf],param[isuser=true, default=TSurfStd])

putting in whatever is appropriate for the "default=" values of the filename and parameter. You would then just invoke the Formula from the Field Selector panel, choose whatever Display type you want, and click "Display". Then you would get a pop-up window where youset the values of the "filename" and "param"...

Lots of caveats here:

* latitude and longitude are assumed to be in the variables named "Latitude" and "Longitude", with units of "degrees_north" and "degrees_east", respectively, and have the same (2-D) dimensions as the data variable(s).

* all variables (including latitude/longitude) have a missing value of < -999.0

* units of the "data variable" are not assigned, which might have "interesting" ramifications if combined with other data...beware!

* this only works with 2-D variables; you would have to change the code a bit to slice off a "level" of a 3-D variable

* (There are 3 statements which are "commented out" using #, which I had in there when creating this in the Jython Shell.)

Now, having said all that, this still might be useful...or inspire you to create your own.

(Details: The key thing is to get the data and then create the appropriate VisAD Data object, using the appropriate domain samples from the file. Here the VisAD class "Gridded2DSet" is used to create the sampling set from the latitude and longitude values, and the "field()" method from JPythonMethods is used to then create the VisAD Data object (as a "FlatField").)
Post Reply