Exemplo n.º 1
0
def TPXOTidalInterpolator(tide, grid_file_name, data_file_name, ranges=None):
    """Create a TidalNetCDFInterpolator from OTPSnc NetCDF files, where
    the grid is stored in a separate file (with "lon_z", "lat_z" and "mz"
    fields). The actual data is read from a seperate file with hRe and hIm
    fields."""
    # read grid, ranges and mask from grid netCDF
    tnci = TidalNetCDFInterpolator(tide,
                                   grid_file_name, ('nx', 'ny'),
                                   ('lon_z', 'lat_z'),
                                   ranges=ranges)
    if "mz" in tnci.nci.nc.variables:
        tnci.set_mask("mz")
    # now swap its nci (keeping all above information) with one for the data file
    tnci.nci = netcdf_reader.NetCDFInterpolator(data_file_name, tnci.nci)

    # constituents available in the netCDF file
    constituents = tnci.nci.nc.variables['con'][:]
    # dict that maps constituent names to indices
    constituent_index = dict(
        ((constituent.tostring().decode().strip(' \x00').lower(), i)
         for i, constituent in enumerate(constituents)))
    # the indices of the requested constituents
    components = [
        constituent_index[constituent.lower()]
        for constituent in tide.constituents
    ]
    tnci.load_complex_components_block(data_file_name, 'hRe', components,
                                       data_file_name, 'hIm', components)
    return tnci
Exemplo n.º 2
0
    def __init__(self,
                 tide,
                 grid_file_name,
                 dimensions,
                 coordinate_fields,
                 ranges=None,
                 mask=None):
        """Initiate a TidalNetCDFInterpolator. The specification of the names of the dimensions
        and coordinate_fields is the same as for the NetCDFInterpolator class, see its documentation.
        ranges and mask may be specified in a similar way to the NetCDFInterpolator class.
        NOTE: setting a correct coordinate ranges is strongly recommended when reading
        from a NetCDF data base that is significantly bigger than the region of interest,
        as otherwise the tidal signal will be reconstructed for all points of the NetCDF grid
        leading to very slow computations. In parallel the ranges should be set to the coordinate
        range of the local process domain.

        The tides may be stored as amplitudes and phases or as the real and complex components.
        For both cases they may be stored in separate fields for each constituent, or in one 3D
        field, where the third dimension corresponds to the different constituents. This third dimension
        should be the first (outer) dimension of the field as stored in the NetCDF file. The methods
        corresponding to these four storage formats are:

            tnci.load_amplitudes_and_phases("amplitude_file.nc", ("M2amp", "S2amp", "K1amp"),
                  "phase_file.nc", ("M2phase", "S2phase", "K1phase"))
            tnci.load_complex_components("realcomp_file.nc", ("M2real", "S2real", "K1real"),
                  "imagcomp_file.nc", ("M2imag", "S2imag", "K1imag"))
            tnci.load_amplitudes_and_phases_block("amplitude_file.nc", "amplitude_field", (0, 1, 2),
                  "phase_file.nc", "phase_field", (0, 1, 2))
            tnci.load_complex_components("realcomp_file.nc", "real_component", (0, 1, 2),
                  "imag_component", (0, 1, 2))

        The specified consituents should corresponds to tide.constituents. In the last two cases,
        "amplitude_field", "phase_field", "real_component", and "imag_component" refer to the
        3D field, and (0, 1, 2) which indices in the first dimension of that field corresponds to which of
        the constituents. In the first two cases instead of specifying a single file for all consituents, an array
        of filenames may also be provided to specify a separate file for each consituent.

        Three helper functions are available to create a TidalNetCDFInterpolator based on three
        different conventions for storage format: TPXOTidalInterpolator, FESTidalInterpolator and
        AMCGTidalInterpolator. These inititate a TidalNetCDFInterpolator and call the correct load_...() method.

        After this, the calling sequence is:

            tnci.set_time(t) # t in seconds after the datetime set with tide.set_initial_time()
            tnci.get_val(x)  # interpolate the tidal signal in location x

        Note that each call to set_time() the tidal signal is reconstructed in all points of the (restricted)
        NetCDF grid. Therefore this method is only efficient if a significant number of interpolations are
        done for each time.

        """
        self.tide = tide
        self.grid_file_name = grid_file_name
        self.nci = netcdf_reader.NetCDFInterpolator(grid_file_name, dimensions,
                                                    coordinate_fields)

        if ranges is not None:
            self.set_ranges(ranges)
        if mask is not None:
            self.set_mask(mask)
Exemplo n.º 3
0
    def _collect_fields_block(self, file_name, field_name, field_components):
        if file_name == self.grid_file_name:
            nci = self.nci
        else:
            # copies grid, mask and ranges information from self.nci (the "grid" netCDF file)
            nci = netcdf_reader.NetCDFInterpolator(file_name, self.nci)
        nci.set_field(field_name)

        val = []
        for component in field_components:
            if nci.dim_order[0] == 0:
                val.append(nci.val[component, :, :])
            else:
                val.append(nci.val[component, :, :].T)
        return val
Exemplo n.º 4
0
    def _collect_fields_val(self, file_name, field_names):
        val = []
        if isinstance(file_name, six.string_types):
            file_names = itertools.repeat(file_name)
        else:
            file_names = file_name

        nci_filenm = self.grid_file_name
        nci = self.nci

        for filenm, fieldnm in zip(file_names, field_names):
            if not filenm == nci_filenm:
                # copies grid, mask and ranges information from self.nci (the "grid" netCDF file)
                nci = netcdf_reader.NetCDFInterpolator(filenm, self.nci)
                nci_filenm = filenm
            nci.set_field(fieldnm)
            if nci.dim_order[0] == 0:
                val.append(nci.val[:])
            else:
                val.append(nci.val[:].T)
        return val