Exemple #1
0
 def scan_grib(self, gribs, kwargs):
     v_selected = kwargs['shortName']
     v_pert = kwargs.get('perturbationNumber', -1)
     grib_append = gribs.append
     if not utils.is_container(v_selected):
         v_selected = [v_selected]
     if self._grbindx:
         for v in v_selected:
             grib_index_select(self._grbindx, 'shortName', str(v))
             if v_pert != -1:
                 grib_index_select(self._grbindx, 'perturbationNumber',
                                   int(v_pert))
             while 1:
                 gid = grib_new_from_index(self._grbindx)
                 if gid is None:
                     break
                 if GRIBReader._find(gid, **kwargs):
                     grib_append(gid)
                 else:
                     # release unused grib
                     grib_release(gid)
     elif self._file_handler:
         while 1:
             gid = grib_new_from_file(self._file_handler)
             if gid is None:
                 break
             if GRIBReader._find(gid, **kwargs):
                 grib_append(gid)
             else:
                 # release unused grib
                 grib_release(gid)
Exemple #2
0
def grib_generator(filename, auto_regularise=True):
    """
    Returns a generator of :class:`~iris.fileformats.grib.GribWrapper`
    fields from the given filename.

    Args:

    * filename (string):
        Name of the file to generate fields from.

    Kwargs:

    * auto_regularise (*True* | *False*):
        If *True*, any field defined on a reduced grid will be interpolated
        to an equivalent regular grid. If *False*, any field defined on a
        reduced grid will be loaded on the raw reduced grid with no shape
        information. The default behaviour is to interpolate fields on a
        reduced grid to an equivalent regular grid.

    """
    with open(filename, 'rb') as grib_fh:
        while True:
            grib_message = gribapi.grib_new_from_file(grib_fh)
            if grib_message is None:
                break

            grib_wrapper = GribWrapper(grib_message, grib_fh, auto_regularise)

            yield grib_wrapper

            # finished with the grib message - claimed by the ecmwf c library.
            gribapi.grib_release(grib_message)
Exemple #3
0
 def get_grib_info(self, select_args):
     _gribs_for_utils = self._get_gids(**select_args)
     if len(_gribs_for_utils) > 0:
         type_of_step = grib_get(_gribs_for_utils[1],
                                 'stepType')  # instant, avg, cumul
         # FIXME this is not correct: GRIB missing values needs bitmap
         self._mv = grib_get_double(_gribs_for_utils[0], 'missingValue')
         start_grib, end_grib, self._step_grib, self._step_grib2, self._change_step_at = self._find_start_end_steps(
             _gribs_for_utils)
         for g in _gribs_for_utils:
             grib_release(g)
         _gribs_for_utils = None
         del _gribs_for_utils
         import gc
         gc.collect()
         info = GRIBInfo(input_step=self._step_grib,
                         input_step2=self._step_grib2,
                         change_step_at=self._change_step_at,
                         type_of_param=type_of_step,
                         start=start_grib,
                         end=end_grib,
                         mv=self._mv)
         return info
     # no messages found
     else:
         raise ValueError('No messages found in grib file')
Exemple #4
0
 def __exit__(self, exception_type, exception_value, traceback):
     """Release GRIB message handle and inform file of release."""
     # This assert should never trigger
     # assert self.gid is not None
     gribapi.grib_release(self.gid)
     if self.grib_index:
         self.grib_index.open_messages.remove(self)
Exemple #5
0
def grib_generator(filename, auto_regularise=True):
    """
    Returns a generator of :class:`~iris.fileformats.grib.GribWrapper`
    fields from the given filename.

    Args:

    * filename (string):
        Name of the file to generate fields from.

    Kwargs:

    * auto_regularise (*True* | *False*):
        If *True*, any field defined on a reduced grid will be interpolated
        to an equivalent regular grid. If *False*, any field defined on a
        reduced grid will be loaded on the raw reduced grid with no shape
        information. The default behaviour is to interpolate fields on a
        reduced grid to an equivalent regular grid.

    """
    with open(filename, 'rb') as grib_fh:
        while True:
            grib_message = gribapi.grib_new_from_file(grib_fh)
            if grib_message is None:
                break

            grib_wrapper = GribWrapper(grib_message, grib_fh, auto_regularise)

            yield grib_wrapper

            # finished with the grib message - claimed by the ecmwf c library.
            gribapi.grib_release(grib_message)
Exemple #6
0
 def check(self, dtype):
     data = np.random.random(1920 * 2560).astype(dtype)
     cube = iris.cube.Cube(data,
                           standard_name='geopotential_height',
                           units='km')
     grib_message = gribapi.grib_new_from_samples("GRIB2")
     data_section(cube, grib_message)
     gribapi.grib_release(grib_message)
Exemple #7
0
    def __getitem__(self, keys):
        with open(self.path, 'rb') as grib_fh:
            grib_fh.seek(self.offset)
            grib_message = gribapi.grib_new_from_file(grib_fh)
            data = _message_values(grib_message, self.shape)
            gribapi.grib_release(grib_message)

        return data.__getitem__(keys)
Exemple #8
0
    def __getitem__(self, keys):
        with open(self.path, 'rb') as grib_fh:
            grib_fh.seek(self.offset)
            grib_message = gribapi.grib_new_from_file(grib_fh)
            data = _message_values(grib_message, self.shape)
            gribapi.grib_release(grib_message)

        return data.__getitem__(keys)
Exemple #9
0
 def close(self):
     for g in self._selected_grbs:
         grib_release(g)
     self._selected_grbs = None
     if self._grbindx:
         grib_index_release(self._grbindx)
         self._grbindx = None
     if self._file_handler:
         self._file_handler.close()
         self._file_handler = None
Exemple #10
0
    def __getitem__(self, keys):
        with open(self.path, "rb") as grib_fh:
            grib_fh.seek(self.offset)
            grib_message = gribapi.grib_new_from_file(grib_fh)

            if self.regularise and _is_quasi_regular_grib(grib_message):
                _regularise(grib_message)

            data = _message_values(grib_message, self.shape)
            gribapi.grib_release(grib_message)

        return data.__getitem__(keys)
Exemple #11
0
def merge_prev_months(month, fin, fouts, writer):
    while True:
        gid = gribapi.grib_new_from_file(fin)
        if (not gid): break
        date = int(gribapi.grib_get(gid, "dataDate"))
        mon = (date % 10000) / 100
        if (mon == month):
            code = make_grib_tuple(gribapi.grib_get(gid, "param"))
            if (code in accum_codes): continue
            fix_Pa_pressure_levels(gid)
            writer(gid, fouts)
        gribapi.grib_release(gid)
Exemple #12
0
    def __getitem__(self, keys):
        # Avoid fetching file data just to return an 'empty' result.
        # Needed because of how dask.array.from_array behaves since Dask v2.0.
        result = _array_slice_ifempty(keys, self.shape, self.dtype)
        if result is None:
            with open(self.path, 'rb') as grib_fh:
                grib_fh.seek(self.offset)
                grib_message = gribapi.grib_new_from_file(grib_fh)
                data = _message_values(grib_message, self.shape)
                gribapi.grib_release(grib_message)

            result = data.__getitem__(keys)

        return result
Exemple #13
0
def write_lsm(gribfield_mod, input_path_oifs, output_path_oifs, exp_name_oifs,
              grid_name_oce, num_fields, gid):
    '''
    This function copies the input gribfile to the output folder and modifies
    it by writing the whole gribfield_mod, including the altered land sea mask
    and soil type fields into the new file
    '''

    input_file_oifs = input_path_oifs + 'ICMGG' + exp_name_oifs + 'INIT'
    output_file_oifs = output_path_oifs + 'ICMGG' + exp_name_oifs + 'INIT_' + grid_name_oce
    copy2(input_file_oifs, output_file_oifs)

    with open(output_file_oifs, 'r+') as f:
        for i in range(num_fields):
            gribapi.grib_set_values(gid[i], gribfield_mod[i])
            gribapi.grib_write(gid[i], f)
            gribapi.grib_release(gid[i])
Exemple #14
0
def grib_generator(filename, auto_regularise=True):
    """
    Returns a generator of :class:`~iris.fileformats.grib.GribWrapper`
    fields from the given filename.

    .. deprecated:: 1.10

    The function:
    :meth:`iris.fileformats.grib.message.GribMessage.messages_from_filename`
    provides alternative means of obtainig GRIB messages from a file.

    Args:

    * filename (string):
        Name of the file to generate fields from.

    Kwargs:

    * auto_regularise (*True* | *False*):
        If *True*, any field defined on a reduced grid will be interpolated
        to an equivalent regular grid. If *False*, any field defined on a
        reduced grid will be loaded on the raw reduced grid with no shape
        information. The default behaviour is to interpolate fields on a
        reduced grid to an equivalent regular grid.

    """
    warn_deprecated('Deprecated at version 1.10')
    with open(filename, 'rb') as grib_fh:
        while True:
            grib_message = gribapi.grib_new_from_file(grib_fh)
            if grib_message is None:
                break

            grib_wrapper = GribWrapper(grib_message, grib_fh, auto_regularise)

            yield grib_wrapper

            # finished with the grib message - claimed by the ecmwf c library.
            gribapi.grib_release(grib_message)
Exemple #15
0
def grib_generator(filename, auto_regularise=True):
    """
    Returns a generator of :class:`~iris_grib.GribWrapper`
    fields from the given filename.

    .. deprecated:: 1.10

    The function:
    :meth:`iris_grib.message.GribMessage.messages_from_filename`
    provides alternative means of obtainig GRIB messages from a file.

    Args:

    * filename (string):
        Name of the file to generate fields from.

    Kwargs:

    * auto_regularise (*True* | *False*):
        If *True*, any field defined on a reduced grid will be interpolated
        to an equivalent regular grid. If *False*, any field defined on a
        reduced grid will be loaded on the raw reduced grid with no shape
        information. The default behaviour is to interpolate fields on a
        reduced grid to an equivalent regular grid.

    """
    warn_deprecated('Deprecated at version 1.10')
    with open(filename, 'rb') as grib_fh:
        while True:
            grib_message = gribapi.grib_new_from_file(grib_fh)
            if grib_message is None:
                break

            grib_wrapper = GribWrapper(grib_message, grib_fh, auto_regularise)

            yield grib_wrapper

            # finished with the grib message - claimed by the ecmwf c library.
            gribapi.grib_release(grib_message)
Exemple #16
0
def save_messages(messages, target, append=False):
    """
    Save messages to a GRIB2 file.
    The messages will be released as part of the save.

    Args:

    * messages:
        An iterable of grib_api message IDs.
    * target:
        A filename or open file handle.

    Kwargs:

    * append:
        Whether to start a new file afresh or add the cube(s) to the end of
        the file. Only applicable when target is a filename, not a file
        handle. Default is False.

    """
    # grib file (this bit is common to the pp and grib savers...)
    if isinstance(target, six.string_types):
        grib_file = open(target, "ab" if append else "wb")
    elif hasattr(target, "write"):
        if hasattr(target, "mode") and "b" not in target.mode:
            raise ValueError("Target not binary")
        grib_file = target
    else:
        raise ValueError("Can only save grib to filename or writable")

    try:
        for message in messages:
            gribapi.grib_write(message, grib_file)
            gribapi.grib_release(message)
    finally:
        # (this bit is common to the pp and grib savers...)
        if isinstance(target, six.string_types):
            grib_file.close()
Exemple #17
0
def save_messages(messages, target, append=False):
    """
    Save messages to a GRIB2 file.
    The messages will be released as part of the save.

    Args:

    * messages:
        An iterable of grib_api message IDs.
    * target:
        A filename or open file handle.

    Kwargs:

    * append:
        Whether to start a new file afresh or add the cube(s) to the end of
        the file. Only applicable when target is a filename, not a file
        handle. Default is False.

    """
    # grib file (this bit is common to the pp and grib savers...)
    if isinstance(target, str):
        grib_file = open(target, "ab" if append else "wb")
    elif hasattr(target, "write"):
        if hasattr(target, "mode") and "b" not in target.mode:
            raise ValueError("Target not binary")
        grib_file = target
    else:
        raise ValueError("Can only save grib to filename or writable")

    try:
        for message in messages:
            gribapi.grib_write(message, grib_file)
            gribapi.grib_release(message)
    finally:
        # (this bit is common to the pp and grib savers...)
        if isinstance(target, str):
            grib_file.close()
def plotData():

    #
    #  G R I B A P I
    #
    f = open(INPUT)
    gid = gribapi.grib_new_from_file(f)
    values = gribapi.grib_get_values(gid)
    #    print values.dtype
    #    print values.shape

    Ni = gribapi.grib_get(gid, 'Ni')
    Nj = gribapi.grib_get(gid, 'Nj')
    print 'GRIB_API: %d (%dx%d=%d) values found in %s' % (len(values), Nj, Ni,
                                                          Nj * Ni, INPUT)
    latitudeOfFirstGridPointInDegrees = gribapi.grib_get(
        gid, 'latitudeOfFirstGridPointInDegrees')
    longitudeOfFirstGridPointInDegrees = gribapi.grib_get(
        gid, 'longitudeOfFirstGridPointInDegrees')
    latitudeOfLastGridPointInDegrees = gribapi.grib_get(
        gid, 'latitudeOfLastGridPointInDegrees')
    longitudeOfLastGridPointInDegrees = gribapi.grib_get(
        gid, 'longitudeOfLastGridPointInDegrees')
    jDirectionIncrementInDegrees = gribapi.grib_get(
        gid, 'jDirectionIncrementInDegrees')
    iDirectionIncrementInDegrees = gribapi.grib_get(
        gid, 'iDirectionIncrementInDegrees')

    #    for key in ('max','min','average'):
    #        print ' %s=%.10e' % (key,gribapi.grib_get(gid,key))

    gribapi.grib_release(gid)
    f.close()

    #
    #  M A G I C S
    #
    Magics.init()
    Magics.setc("OUTPUT_FORMAT", "ps")
    Magics.setc("OUTPUT_NAME", "py_arrays_from_grib")

    Magics.setr("INPUT_FIELD_INITIAL_LATITUDE",
                latitudeOfFirstGridPointInDegrees)
    Magics.setr("INPUT_FIELD_INITIAL_LONGITUDE",
                longitudeOfFirstGridPointInDegrees)
    Magics.setr("INPUT_FIELD_LATITUDE_STEP", -jDirectionIncrementInDegrees)
    Magics.setr("INPUT_FIELD_LONGITUDE_STEP", iDirectionIncrementInDegrees)
    values2 = numpy.array(values - 273.15)  # convert degree K to C
    #    print values2.dtype
    #    print values2.shape
    val = values2.reshape(Nj, Ni)
    #    print val.dtype
    #    print val.shape
    Magics.set2r("INPUT_FIELD", val)

    #    Magics.setc ("contour_grid_value_plot",         "on")
    #    Magics.setc ("contour_grid_value_plot_type",    "value")
    #    Magics.seti ("contour_grid_value_lat_frequency", 8)
    #    Magics.seti ("contour_grid_value_lon_frequency", 8)
    #    Magics.setr ("contour_grid_value_height",        0.3)
    #    Magics.setc ("contour",          "off")
    Magics.cont()

    Magics.coast()
    Magics.finalize()
Exemple #19
0
 def __exit__(self, type, value, traceback):
     """Release GRIB message handle and inform file of release."""
     gribapi.grib_release(self.gid)
     if self.grib_index:
         self.grib_index.open_messages.remove(self)
Exemple #20
0
    def __del__(self):
        """
        Release the gribapi reference to the message at end of object's life.

        """
        gribapi.grib_release(self._message_id)
Exemple #21
0
# missingValue=gribapi.grib_get(gidPlot,"missingValue")
# values=gribapi.grib_get_values(gidPlot)
# msg=np.reshape(values,(Nj,Ni),'C')
# msgmasked = np.ma.masked_values(msg,missingValue)
# xx,yy=np.meshgrid(lons,lats)
# map = Basemap(llcrnrlon=250,llcrnrlat=-10,urcrnrlon=310,urcrnrlat=40)
# map.drawcoastlines()
# map.drawcountries()
# cs=map.contourf(xx,yy,msgmasked)
# map.colorbar(cs)
# plt.show()
#####

# RELEASE ALL MESSAGES
for i in range(mcount):
    gribapi.grib_release(i + 1)
#####

# OPEN OUTPUT FILE
fout = open(outFile, 'w')
#####

# WRITE RECORDS
writeRec1()
writeRec2()
writeRec3()
writeRec4()
writeRec5()
writeRec6()
writeRec7()
writeRec8()
Exemple #22
0
 def release(self):
     gribapi.grib_release(self.record)
Exemple #23
0
    def __del__(self):
        """
        Release the gribapi reference to the message at end of object's life.

        """
        gribapi.grib_release(self._message_id)
Exemple #24
0
def writeRec9():
    PRES = 1013.0  # Sea level presure (replicate Sara's file)
    # total accumulated rainfall from past hour (replicate Sara's file)
    RAIN = 0.0
    SC = 0  # snow cover
    RADSW = 0.0  # SW radiation at surface (replicate Sara's file)
    RADLW = 0.0  # LW radiation at top (replicate Sara's file)
    VAPMR = 0.0  # Vagour mixing ratio (replicate Sara's file)
    for t in range(nfiles):
        print("Processing file " + filenames[t])
        dateTime = parse(date) + dt.timedelta(hours=t * 6)
        MYR = dateTime.year  # Year of data block
        MMO = dateTime.month  # Month of data block
        MDAY = dateTime.day  # Day of data block
        MHR = dateTime.hour  # Hour of data block
        # GRIB file processing:
        f = open(filePaths[t], 'r')  # Open GRIB file
        gribapi.grib_multi_support_on()  # Turn on multi-message support
        mcount = gribapi.grib_count_in_file(f)  # number of messages in file
        [gribapi.grib_new_from_file(f)
         for i in range(mcount)]  # Get handles for all messages
        f.close()  # Close GRIB file
        # Initialse 3D arrays for holding required fields:
        HGTgrd = np.zeros(shape=(Nj, Ni, NZ))
        TMPgrd = np.zeros(shape=(Nj, Ni, NZ))
        Ugrd = np.zeros(shape=(Nj, Ni, NZ))
        Vgrd = np.zeros(shape=(Nj, Ni, NZ))
        Wgrd = np.zeros(shape=(Nj, Ni, NZ))
        RHgrd = np.zeros(shape=(Nj, Ni, NZ))
        # Loop through included levels and store the values in the appropriate k index of the 3D arrays
        for k in range(NZ):
            HGTvals = gribapi.grib_get_values(int(gidHGT[k]))
            HGTgrd[:, :, k] = np.reshape(HGTvals, (Nj, Ni), 'C')
            TMPvals = gribapi.grib_get_values(int(gidTMP[k]))
            TMPgrd[:, :, k] = np.reshape(TMPvals, (Nj, Ni), 'C')
            Uvals = gribapi.grib_get_values(int(gidU[k]))
            Ugrd[:, :, k] = np.reshape(Uvals, (Nj, Ni), 'C')
            Vvals = gribapi.grib_get_values(int(gidV[k]))
            Vgrd[:, :, k] = np.reshape(Vvals, (Nj, Ni), 'C')
            Wvals = gribapi.grib_get_values(int(gidW[k]))
            Wgrd[:, :, k] = np.reshape(Wvals, (Nj, Ni), 'C')
            RHvals = gribapi.grib_get_values(int(gidRH[k]))
            RHgrd[:, :, k] = np.reshape(RHvals, (Nj, Ni), 'C')
        WSgrd = np.sqrt(Ugrd**2 + Vgrd**2)  # Calculate wins speed (pythagoras)
        # Calculate wind direction:
        # radians, between [-pi,pi], positive anticlockwise from positive x-axis
        WDgrd = np.arctan2(Vgrd, Ugrd)
        # degrees, between [-180,180], positive anticlockwise from positive x-axis
        WDgrd *= 180 / np.pi
        # degrees, between [0,360], positive anticlockwise from negative x-axis (Since we specify the direction the wind is blowing FROM, not TO)
        WDgrd += 180
        # degrees, between [-360,0], positive clockwise from negative x-axis (Since wind direction is positive clockwise)
        WDgrd = -WDgrd
        # degrees, between [-270,90], positive clockwise from positive y-axis (Since wind direction is from North)
        WDgrd += 90
        # degrees, between [0,360], positive clockwise from positive y-axis (DONE!)
        WDgrd = np.mod(WDgrd, 360)
        if t > 0:
            dateTime = parse(date) + dt.timedelta(hours=(t * 6) - 3)
            print('interpolating')
            print(dateTime)
            MYR = dateTime.year  # Year of data block
            MMO = dateTime.month  # Month of data block
            MDAY = dateTime.day  # Day of data block
            MHR = dateTime.hour  # Hour of data block
            HGTgrd = np.mean(np.array([HGTgrd + HGTgrd_ini]), axis=0)
            TMPgrd = np.mean(np.array([TMPgrd + TMPgrd_ini]), axis=0)
            Wgrd = np.mean(np.array([Wgrd + Wgrd_ini]), axis=0)
            RHgrd = np.mean(np.array([RHgrd + RHgrd_ini]), axis=0)
            WDgrd = np.mean(np.array([WDgrd + WDgrd_ini]), axis=0)
            WSgrd = np.mean(np.array([WSgrd + WSgrd_ini]), axis=0)
            inds = HGTgrd.argsort(axis=2)
            HGTgrd = take_along_axis(HGTgrd, inds, axis=2)
            TMPgrd = take_along_axis(TMPgrd, inds, axis=2)
            Wgrd = take_along_axis(Wgrd, inds, axis=2)
            RHgrd = take_along_axis(RHgrd, inds, axis=2)
            WSgrd = take_along_axis(WSgrd, inds, axis=2)
            WDgrd = take_along_axis(WDgrd, inds, axis=2)
            # Loop over grid cells:
            for j in range(NY):
                JX = j + 1  # J-index of grid cell
                for i in range(NX):
                    IX = i + 1  # i-index of grid cell
                    fout.write(
                        ('{:4d}' + '{:02d}' * 3 + '{:3d}' * 2 +
                         '{:7.1f}{:5.2f}{:2d}' + '{:8.1f}' * 2 + '\n').format(
                             MYR, MMO, MDAY, MHR, IX, JX, PRES, RAIN, SC,
                             RADSW, RADLW))
                    for k in range(NZ):
                        PRES2 = levsIncl[k]  # Pressure (mb)
                        # Elevation (m above sea level)
                        Z = int(HGTgrd[iLatMinGRIB + j, iLonMinGRIB + i, k])
                        # Temperature (Kelvin)
                        TEMPK = TMPgrd[iLatMinGRIB + j, iLonMinGRIB + i, k]
                        # Wind direction (degrees)
                        WD = int(WDgrd[iLatMinGRIB + j, iLonMinGRIB + i, k])
                        # Wind speed (m/s)
                        WS = WSgrd[iLatMinGRIB + j, iLonMinGRIB + i, k]
                        # Vertical velocity (m/s)
                        W = Wgrd[iLatMinGRIB + j, iLonMinGRIB + i, k]
                        # Relative humidity (%)
                        RH = int(RHgrd[iLatMinGRIB + j, iLonMinGRIB + i, k])
                        fout.write((
                            '{:4d}{:6d}{:6.1f}{:4d}{:5.1f}{:6.2f}{:3d}{:5.2f}\n'
                        ).format(PRES2, Z, TEMPK, WD, WS, W, RH, VAPMR))
            # Release all messages:
            for i in range(mcount):
                gribapi.grib_release(i + 1)
        # GRIB file processing:
        dateTime = parse(date) + dt.timedelta(hours=t * 6)
        print('processing')
        print(dateTime)
        MYR = dateTime.year  # Year of data block
        MMO = dateTime.month  # Month of data block
        MDAY = dateTime.day  # Day of data block
        MHR = dateTime.hour  # Hour of data block
        f = open(filePaths[t], 'r')  # Open GRIB file
        gribapi.grib_multi_support_on()  # Turn on multi-message support
        mcount = gribapi.grib_count_in_file(f)  # number of messages in file
        [gribapi.grib_new_from_file(f)
         for i in range(mcount)]  # Get handles for all messages
        f.close()  # Close GRIB file
        # Initialse 3D arrays for holding required fields:
        HGTgrd = np.zeros(shape=(Nj, Ni, NZ))
        TMPgrd = np.zeros(shape=(Nj, Ni, NZ))
        Ugrd = np.zeros(shape=(Nj, Ni, NZ))
        Vgrd = np.zeros(shape=(Nj, Ni, NZ))
        Wgrd = np.zeros(shape=(Nj, Ni, NZ))
        RHgrd = np.zeros(shape=(Nj, Ni, NZ))
        # Loop through included levels and store the values in the appropriate k index of the 3D arrays
        for k in range(NZ):
            HGTvals = gribapi.grib_get_values(int(gidHGT[k]))
            HGTgrd[:, :, k] = np.reshape(HGTvals, (Nj, Ni), 'C')
            TMPvals = gribapi.grib_get_values(int(gidTMP[k]))
            TMPgrd[:, :, k] = np.reshape(TMPvals, (Nj, Ni), 'C')
            Uvals = gribapi.grib_get_values(int(gidU[k]))
            Ugrd[:, :, k] = np.reshape(Uvals, (Nj, Ni), 'C')
            Vvals = gribapi.grib_get_values(int(gidV[k]))
            Vgrd[:, :, k] = np.reshape(Vvals, (Nj, Ni), 'C')
            Wvals = gribapi.grib_get_values(int(gidW[k]))
            Wgrd[:, :, k] = np.reshape(Wvals, (Nj, Ni), 'C')
            RHvals = gribapi.grib_get_values(int(gidRH[k]))
            RHgrd[:, :, k] = np.reshape(RHvals, (Nj, Ni), 'C')
        HGTgrd_ini = HGTgrd
        TMPgrd_ini = TMPgrd
        Wgrd_ini = Wgrd
        RHgrd_ini = RHgrd
        WSgrd = np.sqrt(Ugrd**2 + Vgrd**2)  # Calculate wins speed (pythagoras)
        # Calculate wind direction:
        # radians, between [-pi,pi], positive anticlockwise from positive x-axis
        WDgrd = np.arctan2(Vgrd, Ugrd)
        # degrees, between [-180,180], positive anticlockwise from positive x-axis
        WDgrd *= 180 / np.pi
        # degrees, between [0,360], positive anticlockwise from negative x-axis (Since we specify the direction the wind is blowing FROM, not TO)
        WDgrd += 180
        # degrees, between [-360,0], positive clockwise from negative x-axis (Since wind direction is positive clockwise)
        WDgrd = -WDgrd
        # degrees, between [-270,90], positive clockwise from positive y-axis (Since wind direction is from North)
        WDgrd += 90
        # degrees, between [0,360], positive clockwise from positive y-axis (DONE!)
        WDgrd = np.mod(WDgrd, 360)
        WDgrd_ini = WDgrd
        WSgrd_ini = WSgrd
        inds = HGTgrd.argsort(axis=2)
        HGTgrd = take_along_axis(HGTgrd, inds, axis=2)
        TMPgrd = take_along_axis(TMPgrd, inds, axis=2)
        Wgrd = take_along_axis(Wgrd, inds, axis=2)
        RHgrd = take_along_axis(RHgrd, inds, axis=2)
        WSgrd = take_along_axis(WSgrd, inds, axis=2)
        WDgrd = take_along_axis(WDgrd, inds, axis=2)
        # Loop over grid cells:
        for j in range(NY):
            JX = j + 1  # J-index of grid cell
            for i in range(NX):
                IX = i + 1  # i-index of grid cell
                fout.write(
                    ('{:4d}' + '{:02d}' * 3 + '{:3d}' * 2 +
                     '{:7.1f}{:5.2f}{:2d}' + '{:8.1f}' * 2 + '\n').format(
                         MYR, MMO, MDAY, MHR, IX, JX, PRES, RAIN, SC, RADSW,
                         RADLW))
                for k in range(NZ):
                    PRES2 = levsIncl[k]  # Pressure (mb)
                    # Elevation (m above sea level)
                    Z = int(HGTgrd[iLatMinGRIB + j, iLonMinGRIB + i, k])
                    # Temperature (Kelvin)
                    TEMPK = TMPgrd[iLatMinGRIB + j, iLonMinGRIB + i, k]
                    # Wind direction (degrees)
                    WD = int(WDgrd[iLatMinGRIB + j, iLonMinGRIB + i, k])
                    # Wind speed (m/s)
                    WS = WSgrd[iLatMinGRIB + j, iLonMinGRIB + i, k]
                    # Vertical velocity (m/s)
                    W = Wgrd[iLatMinGRIB + j, iLonMinGRIB + i, k]
                    # Relative humidity (%)
                    RH = int(RHgrd[iLatMinGRIB + j, iLonMinGRIB + i, k])
                    fout.write(
                        ('{:4d}{:6d}{:6.1f}{:4d}{:5.1f}{:6.2f}{:3d}{:5.2f}\n'
                         ).format(PRES2, Z, TEMPK, WD, WS, W, RH, VAPMR))
        # Release all messages:
        for i in range(mcount):
            gribapi.grib_release(i + 1)
Exemple #25
0
def save(source, target, append=False, sample_file=_sample_file):
    """
    Takes a dataset (source) and writes its contents
    as grib 1 to file-like target.  Grib 1 is used (instead
    of grib 2) because some older forecast visualization
    software can't read grib 2.

    This is a heavily modified but none-the-less derivative of
    the grib saving functions from the iris package.

    Parameters
    ----------
    source : Dataset
        A netcdf-like file holding the dataset we want to write
        as grib.  This must contain time, longitude and latitude
        coordinates in order to infer the grib grid and time params
    target : string path or file-like
        Where the contents should be written.  If target is a string
        the file is created or appended to.
    append : boolean
        When creating a new file from string you can optionally
        append to the file.
    """
    if not _has_gribapi:
        raise ImportError("gripapi is required to write grib files.")

    if isinstance(target, basestring):
        grib_file = open(target, "ab" if append else "wb")
    elif hasattr(target, "write"):
        if hasattr(target, "mode") and "b" not in target.mode:
            raise ValueError("Target not binary")
        grib_file = target
    else:
        raise ValueError("Can only save grib to filename or writable")
    if not 'latitude' in source.variables or not 'longitude' in source.variables:
        raise ValueError("Did not find either latitude or longitude.")
    if source['latitude'].ndim != 1 or source['longitude'].ndim != 1:
        raise ValueError("Latitude and Longitude should be regular.")
    if not 'time' in source.variables:
        raise ValueError("Expected time coordinate")
    # sort the lats and lons
    source = source.indexed(latitude=np.argsort(source['latitude'].values))
    lons = source['longitude'].values
    if np.any(np.abs(np.diff(lons)) > 180.):
        # the latitudes must cross the dateline since we only allow 180
        # degree wide bounding boxes, and there is more than a 180 degree
        # difference between longitudes.  Instead we try converting to
        # 0 to 360 degree longitudes before sorting.
        lons = np.mod(lons, 360)
        if np.any(np.abs(np.diff(lons)) > 180.):
            # TODO: I'm sure theres a way to deal with arbitrary longitude
            # specifications for global data ... but its not a high priority
            # so that will wait for later.
            raise ValueError("Longitudes span more than 180 degrees and the dateline?")
    source['longitude'].values[:] = lons
    source = source.indexed(longitude=np.argsort(lons))
    # iterate over variables, unless they are considered
    # auxiliary variables (ie, variables used by slocum
    # but not in grib files).
    auxilary_variables = ['wind_speed', 'wind_from_direction']
    for single_var in (v for k, v in source.noncoordinates.iteritems()
                       if not k in auxilary_variables):
        # then iterate over time slices
        iter_time = (single_var.indexed(**{'time': [i]})
                     for i in range(single_var.coordinates['time'].size))
        for obj in iter_time:
            # Save this slice to the grib file
            gribapi.grib_gribex_mode_off()
            if sample_file is not None and os.path.exists(sample_file):
                with open(sample_file, 'r') as f:
                    grib_message = gribapi.grib_new_from_file(f)
                logger.info("Created grib message from file %s" % sample_file)
            else:
                logger.info("Creating grib message from gribapi sample: GRIB1")
                grib_message = gribapi.grib_new_from_samples("GRIB1")
            set_time(obj, grib_message)
            set_product(obj, grib_message)
            set_grid(obj, grib_message)
            set_data(obj, grib_message)
            gribapi.grib_write(grib_message, grib_file)
            gribapi.grib_release(grib_message)
    # if target was a string then we have to close the file we
    # created, otherwise leave that up to the user.
    if isinstance(target, basestring):
        grib_file.close()
Exemple #26
0
 def __exit__(self, type, value, traceback):
     """Release GRIB message handle and inform file of release."""
     gribapi.grib_release(self.gid)
     if self.grib_index:
         self.grib_index.open_messages.remove(self)
Exemple #27
0
    def get_phenomena(self):

        phen_list = []
        phenomenon =\
        {
         "id" : "",
         "attribute_count" : "",
         "attributes" :[]
        }

        phen_keys = [
                      "paramId",
                      "cfNameECMF",
                      "cfName",
                      "cfVarName",
                      "units",
                      "nameECMF",
                      "name"
                    ]

        phen_attr =\
        {
         "name" : "",
         "value": ""
        }

        try:
            fd = open(self.file_path)

            while 1:
                gid = gapi.grib_new_from_file(fd)
                if gid is None: break

                phen_attr_list = []
                attr_count = 0
                for key in phen_keys:

                    if not gapi.grib_is_defined(gid, key):
                        continue

                    value = str(gapi.grib_get(gid, key))
                    if len(key) < util.MAX_ATTR_LENGTH \
                       and len(value) < util.MAX_ATTR_LENGTH \
                       and util.is_valid_phen_attr(value):

                        phen_attr["name"] = str(key.strip())
                        phen_attr["value"] = str(unicode(value).strip())

                        if phen_attr not in phen_attr_list:
                            phen_attr_list.append(phen_attr.copy())
                            attr_count = attr_count + 1

                if len(phen_attr_list) > 0:
                    new_phenomenon = phenomenon.copy() 
                    new_phenomenon["attributes"] = phen_attr_list
                    new_phenomenon["attribute_count"] = attr_count

                    if new_phenomenon not in phen_list:
                        phen_list.append(new_phenomenon)


                gapi.grib_release(gid)

            fd.close()

            return phen_list

        except Exception:
            return None
Exemple #28
0
    def get_metadata_level3(self):

        phen_list = []
        phenomenon =\
        {
         "id" : "",
         "attribute_count" : "",
         "attributes" :[]
        }

        phen_attr =\
        {
         "name" : "",
         "value": ""
        }

        lat_f_l = []
        lon_f_l = []
        lat_l_l = []
        lon_l_l = []
        date_d_l = []
        date_t_l = []

        phen_keys = [
                      "paramId",
                      "cfNameECMF",
                      "cfName",
                      "cfVarName",
                      "units",
                      "nameECMF",
                      "name",
                      "Ni",
                      "Nj",
                      "latitudeOfFirstGridPointInDegrees",
                      "longitudeOfFirstGridPointInDegrees",
                      "latitudeOfLastGridPointInDegrees",
                      "longitudeOfLastGridPointInDegrees",
                      "dataDate",
                      "dataTime"
                    ]
        try:
            fd = open(self.file_path)

            while 1:
                gid = gapi.grib_new_from_file(fd)
                if gid is None: break

                phen_attr_list = []
                attr_count = 0
                for key in phen_keys:

                    if not gapi.grib_is_defined(gid, key):
                        continue

                    value = str(gapi.grib_get(gid, key))

                    #So the file contains many records but all report the
                    #same spatial and temporal information. Only complete distinct records 
                    #will be stored i.e the one that contain the full list of parameter
                    #and are unique. If evety record has got different spatial and temporal
                    #then th eindex must change because currently there is only on geo_shape_field.
                    if key == "latitudeOfFirstGridPointInDegrees":
                        lat_f_l.append(value)
                    elif key == "longitudeOfFirstGridPointInDegrees":
                        lon_f_l.append(value)
                    elif key == "latitudeOfLastGridPointInDegrees":
                        lat_l_l.append(value)
                    elif key =="longitudeOfLastGridPointInDegrees":
                        lon_l_l.append(value)
                    elif key == "dataDate":
                        date_d_l.append(value)
                    elif key == "dataTime":
                        date_t_l.append(value)
                    else:
                        if    len(key) < util.MAX_ATTR_LENGTH \
                          and len(value) < util.MAX_ATTR_LENGTH \
                          and util.is_valid_phen_attr(value):

                            phen_attr["name"] = str(key.strip())
                            phen_attr["value"] = str(unicode(value).strip())

                            if phen_attr not in phen_attr_list:
                                phen_attr_list.append(phen_attr.copy())
                                attr_count = attr_count + 1

                if len(phen_attr_list) > 0:
                    new_phenomenon = phenomenon.copy() 
                    new_phenomenon["attributes"] = phen_attr_list
                    new_phenomenon["attribute_count"] = attr_count

                    if new_phenomenon not in phen_list:
                        phen_list.append(new_phenomenon)

                gapi.grib_release(gid)

            fd.close()

            if len(lat_f_l) > 0 \
               and len(lon_f_l) > 0  \
               and len(lat_l_l) > 0  \
               and len(lon_l_l) > 0  \
               and len(date_d_l) > 0 \
               and len(date_t_l):

                geospatial_dict = {}
                geospatial_dict["type"] = "envelope"

                temporal_dict = {} 
                lat_f = min(lat_f_l)
                lon_f = min(lon_f_l)
                lat_l = max(lat_l_l)
                lon_l = max(lon_l_l)

                date_d = min(date_d_l)
                date_t = min(date_t_l)

                if float(lon_l) > 180:
                    lon_l = (float(lon_l) -180) - 180


                geospatial_dict["coordinates"] = [[round(float(lon_f), 3), round(float(lat_f), 3)], [round(float(lon_l), 3), round(float(lat_l), 3) ]]

                temporal_dict["start_time"] = date_d
                temporal_dict["end_time"] = date_t

                return (phen_list, geospatial_dict, temporal_dict)
            else:
                return (phen_list,)

        except Exception as ex:
            return None
Exemple #29
0
def merge_cur_months(month, fin1, fin2, fouts, writer):
    gidinst, gidcum = -1, -1
    timinst, timcum = -1, -1
    procinst, proccum = True, True
    instmode = False
    while True:
        if (instmode):
            if (procinst):
                if (gidinst != -1): gribapi.grib_release(gidinst)
                gidinst = gribapi.grib_new_from_file(fin1)
            if (not gidinst):
                break
            time = int(gribapi.grib_get(gidinst, "dataTime"))
            if (timinst == -1): timinst = time
            if (time != timinst):
                timinst = time
                procinst = False
                instmode = False
                continue
            else:
                procinst = True
            code = make_grib_tuple(gribapi.grib_get(gidinst, "param"))
            if (code in accum_codes):
                continue
            date = int(gribapi.grib_get(gidinst, "dataDate"))
            mon = (date % 10**4) / 10**2
            if (mon == month):
                fix_Pa_pressure_levels(gidinst)
                writer(gidinst, fouts)
        else:
            if (proccum):
                if (gidinst != -1): gribapi.grib_release(gidcum)
                gidcum = gribapi.grib_new_from_file(fin2)
            if (not gidcum):
                procinst = False
                instmode = True
                continue
            time = int(gribapi.grib_get(gidcum, "dataTime"))
            if (timcum == -1): timcum = time
            if (time != timcum):
                timcum = time
                proccum = False
                instmode = True
                continue
            else:
                proccum = True
            code = make_grib_tuple(gribapi.grib_get(gidcum, "param"))
            if (code not in accum_codes): continue
            if (timeshift > 0):
                date = int(gribapi.grib_get(gidcum, "dataDate"))
                mon = (date % 10**4) / 10**2
                newdate = date
                newtime = time - 100 * timeshift
                if (newtime < 0):
                    curdate = datetime.date(date / 10**4, mon, date % 10**2)
                    prevdate = curdate - datetime.timedelta(days=1)
                    mon = prevdate.month
                    newdate = prevdate.year * 10**4 + mon * 10**2 + prevdate.day
                    newtime = 2400 + newtime
                gribapi.grib_set(gidcum, "dataDate", newdate)
                gribapi.grib_set(gidcum, "dataTime", newtime)
            if (mon == month):
                fix_Pa_pressure_levels(gidcum)
                writer(gidcum, fouts)