Example #1
0
def HDF_proj_WKT(hdf_filepath):
    # returns the projection of the HDF file in Well Known Text (WKT) format

    # first determine the HDF type
    hdf_type = HDF_type(hdf_filepath)

    if hdf_type == 'hdf4':
        # for HDF4 assume corner coordinates are stored in the StructMetadata.0 section
        hdf_file = SD(hdf_filepath, SDC.READ)

        try:
            # access grid metadata section of StructMetadata.0
            fattr = hdf_file.attributes(full=1)
            structmeta = fattr['StructMetadata.0']
            gridmeta = structmeta[0]

            # determine the projection GCTP code from the grid metadata
            proj_regex = re.compile(r'''Projection=(?P<projection>\w+)''',
                                    re.VERBOSE)
            match = proj_regex.search(gridmeta)
            proj = match.group('projection')

            # support MODIS sinusoidal projection for now, add others later
            if proj == 'GCTP_SNSOID':
                sinu_proj4 = "+proj=sinu +R=6371007.181 +nadgrids=@null +wktext"
                srs = osr.SpatialReference()
                srs.ImportFromProj4(sinu_proj4)
                return srs.ExportToWkt()
        except:
            #prjfile = open('/home/rkalyana/GeoEDF/GeoEDF/connector/filter/modis/6933.prj', 'r')
            #prj_txt = prjfile.read()
            #srs = osr.SpatialReference()
            #srs.ImportFromESRI([prj_txt])
            #prjfile.close()
            #return srs.ExportToWkt()
            raise GeoEDFError(
                'Error determining the projection or unsupported projection')

    else:  # HDF5 file; only SMAP files in EASE Grid 2.0 are supported at the moment
        hdf_file = h5py.File(hdf_filepath, mode='r')

        # check to see if this is a EASE Grid 2.0 file
        if 'EASE2_global_projection' in hdf_file.keys():
            ease_proj4 = "+proj=cea +lat_0=0 +lon_0=0 +lat_ts=30 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m"
            srs = osr.SpatialReference()
            srs.ImportFromProj4(ease_proj4)
            return srs.ExportToWkt()
        else:
            raise GeoEDFError(
                'Error determining the projection or unsupported projection')
    def __init__(self,
                 datatype,
                 version,
                 fname,
                 variables=None,
                 verbose=False):
        self.datatype = datatype
        self.version = version
        self.fname = fname
        self.verbose = verbose
        self.dataset = {}
        print(version.capitalize())
        if version == 'HDF4':
            hdf = SD(self.fname, SDC.READ)
            if variables is None:
                for d in hdf.datasets():
                    self.dataset[d] = np.array(hdf.select(d).get())
                    if verbose: print(d)
            else:
                for d in variables:
                    self.dataset[d] = np.array(hdf.select(d).get())
                    if verbose: print('reading', d)

        elif version == 'HDF5':
            hdf = h5py.File(fname, 'r')
            if variables is None:
                allvariables = list(hdf.keys())
                print('allvariables', allvariables)
                for d in allvariables:
                    self.dataset[d] = np.array(hdf[d])
                    if verbose: print(d)
            else:
                for d in variables:
                    self.dataset[d] = np.array(hdf[d])
                    if verbose: print(d)

        else:
            print(datatype, '  not supported')
        if verbose:
            for key in self.dataset:
                print('variable: ',key, ' dimension', self.dataset[key].shape,\
                       'min, max', np.nanmin(self.dataset[key]),np.nanmax(self.dataset[key]))
            print('finished')
Example #3
0
def HDF_subdataset_data(hdf_filepath, subdataset_substrs):

    # process the names of the subdatasets, finding any that contain a member of
    # subdataset_substrs as a substring
    # subdataset_substrs is a list

    # returned dictionary indexed by subdataset name
    # contains data grid and value range
    hdf_data = dict()

    # first determine the HDF type
    hdf_type = HDF_type(hdf_filepath)

    if hdf_type == 'hdf4':
        hdf_file = SD(hdf_filepath, SDC.READ)
        try:
            dset_names = hdf_file.datasets().keys()
            # loop through input subdataset substrings
            for subdset_substr in subdataset_substrs:
                # loop through datasets in HDF file
                for dset_name in dset_names:
                    # if substring found
                    if subdset_substr in dset_name:
                        # if this subdataset has not been processed before
                        if dset_name not in hdf_data:
                            try:
                                data2D = hdf_file.select(dset_name)
                                data = data2D[:, :].astype(np.float64)
                                hdf_data[dset_name] = dict()
                                hdf_data[dset_name]['data'] = data
                                #hdf_data[dset_name]['range'] = data2D.getrange()
                                hdf_data[dset_name][
                                    'fillValue'] = data2D.getfillvalue()
                            except:
                                raise GeoEDFError(
                                    'Error retrieving subdataset %s data from HDF file'
                                    % dset_name)
        except:
            raise GeoEDFError(
                'Error retrieving subdatasets from HDF4 file %s' %
                hdf_filepath)
    else:
        hdf_file = h5py.File(hdf_filepath, mode='r')
        # assume this follows the structure of HDF-EOS files where all subdatasets are in a "Geophysical_Data" group
        if 'Geophysical_Data' in hdf_file.keys():
            dset_names = hdf_file['Geophysical_Data'].keys()
            # loop through input subdataset substrings
            for subdset_substr in subdataset_substrs:
                # loop through subdatasets in HDF file
                for dset_name in dset_names:
                    # if substring matches
                    if subdset_substr in dset_name:
                        # if subdataset not processed yet
                        if dset_name not in hdf_data:
                            try:
                                # construct fully qualified subdataset name
                                fq_dset_name = '/Geophysical_Data/%s' % dset_name
                                data = hdf_file[fq_dset_name]
                                hdf_data[dset_name] = dict()
                                hdf_data[dset_name]['data'] = data[:]
                                hdf_data[dset_name][
                                    'fillValue'] = data.fillvalue
                            except:
                                raise GeoEDFError(
                                    'Error retrieving subdataset %s data from HDF file'
                                    % dset_name)
        else:
            raise GeoEDFError(
                'Cannot handle HDF5 files that do not follow the HDF-EOS standards'
            )

    return hdf_data
Example #4
0
def HDF_corner_coords(hdf_filepath):

    # return a tuple of upper left and lower right coordinates in lat-lon

    # first determine the HDF type
    hdf_type = HDF_type(hdf_filepath)

    if hdf_type == 'hdf4':
        # for HDF4 assume corner coordinates are stored in the StructMetadata.0 section
        hdf_file = SD(hdf_filepath, SDC.READ)

        try:
            # access grid metadata section of StructMetadata.0
            fattr = hdf_file.attributes(full=1)
            structmeta = fattr['StructMetadata.0']
            gridmeta = structmeta[0]

            # parse the text to retrieve corner coordinates in meters
            ul_regex = re.compile(
                r'''UpperLeftPointMtrs=\(
                                  (?P<upper_left_x>[+-]?\d+\.\d+)
                                  ,
                                  (?P<upper_left_y>[+-]?\d+\.\d+)
                                  \)''', re.VERBOSE)
            match = ul_regex.search(gridmeta)
            x0 = np.float(match.group('upper_left_x'))
            y0 = np.float(match.group('upper_left_y'))

            lr_regex = re.compile(
                r'''LowerRightMtrs=\(
                                  (?P<lower_right_x>[+-]?\d+\.\d+)
                                  ,
                                  (?P<lower_right_y>[+-]?\d+\.\d+)
                                  \)''', re.VERBOSE)
            match = lr_regex.search(gridmeta)
            x1 = np.float(match.group('lower_right_x'))
            y1 = np.float(match.group('lower_right_y'))

            # construct the projection transformer to convert from meters to lat-lon

            # determine the projection GCTP code from the grid metadata
            proj_regex = re.compile(r'''Projection=(?P<projection>\w+)''',
                                    re.VERBOSE)
            match = proj_regex.search(gridmeta)
            proj = match.group('projection')

            # support MODIS sinusoidal projection for now, add others later
            if proj == 'GCTP_SNSOID':
                #sinu = pyproj.Proj("+proj=sinu +R=6371007.181 +nadgrids=@null +wktext")
                #wgs84 = pyproj.Proj("+init=EPSG:4326")
                #lon0, lat0 = pyproj.transform(sinu, wgs84, x0, y0)
                #lon1, lat1 = pyproj.transform(sinu, wgs84, x1, y1)

                #return (lon0, lat0, lon1, lat1)
                return (x0, y0, x1, y1)

            else:
                raise GeoEDFError(
                    'Only MODIS sinusoidal grids are supported currently')

        except Exception as e:
            #x0, y0, x1, y1 = -17357881.81713629,7324184.56362408,17357881.81713629,-7324184.56362408
            #return (x0,y0,x1,y1)
            raise GeoEDFError(
                'Error retrieving corner coordinates of HDF file')

    else:  # HDF5 file; only SMAP files in EASE Grid 2.0 are supported at the moment
        hdf_file = h5py.File(hdf_filepath, mode='r')

        # check to see if this is a EASE Grid 2.0 file
        if 'EASE2_global_projection' in hdf_file.keys():
            # hardcoded corner coordinates, since this is not stored in the file metadata
            x0, y0, x1, y1 = -17357881.81713629, 7324184.56362408, 17357881.81713629, -7324184.56362408

            #ease = pyproj.Proj(("+proj=cea +lat_0=0 +lon_0=0 +lat_ts=30 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m"))
            #wgs84 = pyproj.Proj("+init=EPSG:4326")
            #lon0, lat0 = pyproj.transform(ease, wgs84, x0, y0)
            #lon1, lat1 = pyproj.transform(ease, wgs84, x1, y1)

            #return (lon0, lat0, lon1, lat1)
            return (x0, y0, x1, y1)

        else:
            raise GeoEDFError(
                'Only EASE Grid 2.0 HDF5 files are supported currently')