Пример #1
0
def get_points_in_volume(lat, lon, dep, ll, ur, inc, depth_min, depth_max):
    """find points that fall with in a volume

    Keyword arguments:
    lat: latitude list to check
    lon: longitude list to check
    dep: depth list to check
    ll: lower-left coordinate
    ur: upper-right coordinate
    depth_min: minimum depth of volume
    depth_max: maximum depth of volume

    Return values:
    latitude: list of latitudes that are in the volume
    longitude: list of longitude that are in the volume
    depth: list of depths that are in the volume
    """
    latitude = []
    longitude = []
    depth = []
    last_i = -1
    for i, lon_val in enumerate(lon):
        if i != 0 and i != len(lon) - 1 and i != last_i + inc:
            continue
        last_i = i
        for j, depth_val in enumerate(dep):
            last_k = -1
            for k, lat_val in enumerate(lat):
                if k != 0 and k != len(lat) - 1 and k != last_k + inc:
                    continue
                last_k = k
                if utils.isValueIn(lat_val, ll[0], ur[0]) and utils.isLongitudeIn(lon_val, ll[1], ur[1]) and \
                        utils.isValueIn(float(depth_val), depth_min, depth_max):
                    if lon_val not in longitude:
                        longitude.append(lon_val)
                    if depth_val not in depth:
                        depth.append(depth_val)
                    if lat_val not in latitude:
                        latitude.append(lat_val)
    return latitude, longitude, depth
Пример #2
0
def get_points_in_area(lat, lon, dep, ll, ur, inc):
    """find points that fall with in an area

    Keyword arguments:
    lat: latitude list to check
    lon: longitude list to check
    dep: depth to use
    ll: lower-left coordinate
    ur: upper-right coordinate

    Return values:
    latitude: list of latitudes that are in the area
    longitude: list of longitude that are in the area
    depth: list of depths that are in the volume
    """

    use_dep = dep
    if type(dep) is list:
        use_dep = [dep[0]]
    latitude = []
    longitude = []
    depth = []
    last_i = -1
    for i, lon_val in enumerate(lon):
        if i != 0 and i != len(lon) - 1 and i != last_i + inc:
            continue
        last_i = i
        for j, depth_val in enumerate(use_dep):
            last_k = -1
            for k, lat_val in enumerate(lat):
                if k != 0 and k != len(lat) - 1 and k != last_k + inc:
                    continue
                last_k = k
                if utils.isValueIn(lat_val, ll[0],
                                   ur[0]) and utils.isLongitudeIn(
                                       lon_val, ll[1], ur[1]):
                    if lon_val not in longitude:
                        longitude.append(lon_val)
                    if depth_val not in depth:
                        depth.append(depth_val)
                    if lat_val not in latitude:
                        latitude.append(lat_val)
    return latitude, longitude, depth
Пример #3
0
def find_netCDFModelExtent(modelFile, latVariable, lonVariable, depthVariable,
                           LL, UR, depthMin, depthMax, inc):
    """
   find the extent of the model as the number of grid points in each direction

   Parameters
   ----------
   modelFile: str
      model file
   latVariable: str
      latitude variable
   lonVariable: str
      longitude variable
   depthVar: str
      depthVariable
   LL: list
      lower-left coordinate
   UR: list
      upper-right coordinate
   depthMin: float
      minimum depth
   depthMax: float
      maximum depth
   inc: int
      grid sampling interval

   Returns
   -------
   ii: int
      number of element in the x-direction
   jj: int
      number of element in the y-direction
   kk: int
      number of element in the z-direction
   """
    #depthVariable = 'depth'
    #lonVariable   = 'longitude'
    #latVariable   = 'latitude'

    #
    # model data
    #
    import numpy as np
    from scipy.io import netcdf
    emcdata = netcdf.netcdf_file(modelFile, 'r')
    variables = []
    for name in emcdata.variables.keys():
        if name not in (depthVariable, lonVariable, latVariable):
            variables.append(name)

    #
    # I assume all variables are defined with uniform order of latitude, longitude and depth
    #
    var = variables[0]
    for i in range(len(emcdata.variables[var].dimensions)):
        if emcdata.variables[var].dimensions[i] == depthVariable:
            depthIndex = i
        elif emcdata.variables[var].dimensions[i] == lonVariable:
            lonIndex = i
        else:
            latIndex = i

    lat = emcdata.variables[latVariable][:].copy()
    lon = emcdata.variables[lonVariable][:].copy()
    for i in range(len(lon)):
        if lon[i] > 180.0: lon[i] -= 360.0

    depth = emcdata.variables[depthVariable][:].copy()
    emcdata.close()

    #
    # model data grid definition
    #
    for l in range(len(variables)):
        ii = -1
        jj = -1
        kk = -1
        oldI = -1
        oldJ = -1
        oldK = -1
        lastI = -1
        for i in range(len(lon)):
            if i != 0 and i != len(lon) - 1 and i != lastI + inc:
                continue
            lastI = i
            for j in range(len(depth)):
                lastK = -1
                for k in range(len(lat)):
                    if k != 0 and k != len(lat) - 1 and k != lastK + inc:
                        continue
                    lastK = k
                    if utils.isValueIn(
                            lat[k], LL[0], UR[0]) and utils.isLongitudeIn(
                                lon[i], LL[1], UR[1]) and utils.isValueIn(
                                    float(depth[j]), depthMin, depthMax):
                        if i != oldI:
                            oldI = i
                            ii += 1
                            jj = -1
                            oldJ = -1
                            kk = -1
                            oldK = -1
                        if j != oldJ:
                            oldJ = j
                            jj += 1
                            kk = -1
                            oldK = -1
                        if k != oldK:
                            oldK = k
                            kk += 1
    return ii, jj, kk
Пример #4
0
def read_netCdfEarthModel(modelFile, latVariable, lonVariable, depthVariable,
                          LL, UR, depthMin, depthMax, inc):
    """
   read in an EMC Earth model in the netCDF format

    Parameters
    ----------
    modelFile: str
       model file
    latVariable: str
      latitude variable
   lonVariable: str
      longitude variable
   depthVar: str
      depthVariable
    LL: list
       lower-left coordinate
    UR: list
       upper-right coordinate
    depthMin: float
       minimum depth
    depthMax: float
       maximum depth
    inc: int
       grid sampling interval

    Returns
    -------
    X: float
       x-coordinate  normalized to the radius of Earh
    Y: float
       y-coordinate  normalized to the radius of Earh
    Z: float
       z-coordinate  normalized to the radius of Earh
    meta: dict
       file metadata information
   """
    #depthVariable = 'depth'
    #lonVariable   = 'longitude'
    #latVariable   = 'latitude'

    #
    # model data
    # NetCDF files, when opened read-only, return arrays that refer directly to memory-mapped data on disk:
    #
    import numpy as np
    from scipy.io import netcdf
    emcdata = netcdf.netcdf_file(modelFile, 'r')
    variables = []
    for name in emcdata.variables.keys():
        if name not in (depthVariable, lonVariable, latVariable):
            variables.append(name)

    #
    # I assume all variables are defined with uniform order of latitude, longitude and depth
    #
    var = variables[0]
    for i in range(len(emcdata.variables[var].dimensions)):
        if emcdata.variables[var].dimensions[i] == depthVariable:
            depthIndex = i
        elif emcdata.variables[var].dimensions[i] == lonVariable:
            lonIndex = i
        else:
            latIndex = i

    lat = emcdata.variables[latVariable][:].copy()
    lon = emcdata.variables[lonVariable][:].copy()
    for i in range(len(lon)):
        if lon[i] > 180.0: lon[i] -= 360.0

    depth = emcdata.variables[depthVariable][:].copy()

    #
    # select the values within the ranges (this is to get a count only)
    #
    depth2 = []
    latitude = []
    longitude = []
    depth2 = []
    lastI = -1
    for i in range(len(lon)):
        if i != 0 and i != len(lon) - 1 and i != lastI + inc:
            continue
        lastI = i
        for j in range(len(depth)):
            lastK = -1
            for k in range(len(lat)):
                if k != 0 and k != len(lat) - 1 and k != lastK + inc:
                    continue
                lastK = k
                if utils.isValueIn(
                        lat[k], LL[0], UR[0]) and utils.isLongitudeIn(
                            lon[i], LL[1], UR[1]) and utils.isValueIn(
                                float(depth[j]), depthMin, depthMax):
                    if lon[i] not in longitude:
                        longitude.append(lon[i])
                    if depth[j] not in depth2:
                        depth2.append(depth[j])
                    if lat[k] not in latitude:
                        latitude.append(lat[k])

    #
    # model data grid definition
    #
    V = {}
    nx = len(longitude)
    ny = len(depth2)
    nz = len(latitude)
    index = [-1, -1, -1]
    meta = {
        'depth': [],
        'lat': [100, -100],
        'lon': [400, -400],
        'source': modelFile
    }
    for l in range(len(variables)):
        X = np.zeros((nx, ny, nz))
        Y = np.zeros((nx, ny, nz))
        Z = np.zeros((nx, ny, nz))
        v = np.zeros((nx, ny, nz))
        var = variables[l]
        emcin = emcdata.variables[var][:].copy()
        latitude = []
        longitude = []
        depth2 = []
        ii = -1
        jj = -1
        kk = -1
        oldI = -1
        oldJ = -1
        oldK = -1
        lastI = -1
        for i in range(len(lon)):
            if i != 0 and i != len(lon) - 1 and i != lastI + inc:
                continue
            lastI = i
            for j in range(len(depth)):
                lastK = -1
                for k in range(len(lat)):
                    if k != 0 and k != len(lat) - 1 and k != lastK + inc:
                        continue
                    lastK = k
                    if utils.isValueIn(
                            lat[k], LL[0], UR[0]) and utils.isLongitudeIn(
                                lon[i], LL[1], UR[1]) and utils.isValueIn(
                                    float(depth[j]), depthMin, depthMax):
                        if i != oldI:
                            meta['lon'] = [
                                min(meta['lon'][0], lon[i]),
                                max(meta['lon'][0], lon[i])
                            ]
                            oldI = i
                            ii += 1
                            jj = -1
                            oldJ = -1
                            kk = -1
                            oldK = -1
                        if j != oldJ:
                            if depth[j] not in meta['depth']:
                                meta['depth'].append(depth[j])
                            oldJ = j
                            jj += 1
                            kk = -1
                            oldK = -1
                        if k != oldK:
                            meta['lat'] = [
                                min(meta['lat'][0], lat[k]),
                                max(meta['lat'][0], lat[k])
                            ]
                            oldK = k
                            kk += 1
                        x, y, z = llz2xyz(lat[k], lon[i],
                                          depth[j] * depthFactor)
                        X[ii, jj, kk] = x
                        Y[ii, jj, kk] = y
                        Z[ii, jj, kk] = z
                        index[depthIndex] = j
                        index[latIndex] = k
                        index[lonIndex] = i

                        v[ii, jj, kk] = emcin[index[0]][index[1]][index[2]]

        V[var] = v
    emcdata.close()
    return X, Y, Z, V, meta
Пример #5
0
def getSlabExtent(modelFile, LL, UR, inc=5):
    """
   find the  extent of a 2-D top model file in netCDF format as the number of grid points in each direction

   Parameters
   ----------
   modelFile: str
      model file
   LL: list
      lower-left coordinate
   UR: list
      upper-right coordinate
   inc: int
      grid sampling interval

   Returns
   -------
   ii: int
      number of element in the x-direction
   jj: int
      number of element in the y-direction
   kk: int
      number of element in the z-direction
   """
    depthVariable = 'z'
    lonVariable = 'x'
    latVariable = 'y'

    #
    # select the values within the ranges (this is to get a count only)
    #
    import numpy as np
    from scipy.io import netcdf
    topodata = netcdf.netcdf_file(modelFile, 'r')
    lat = topodata.variables[latVariable][:].copy()
    lon = topodata.variables[lonVariable][:].copy()
    for i in range(len(lon)):
        if lon[i] > 180.0: lon[i] -= 360.0
    depth = topodata.variables[depthVariable][:].copy()
    topodata.close()

    #
    # model data grid definition
    #
    for l in range(1):
        ii = 0
        jj = 1
        kk = 0
        oldI = -1
        oldJ = -1
        oldK = -1
        for i in range(0, len(lon), inc):
            for k in range(0, len(lat), inc):
                if utils.isValueIn(lat[k], LL[0],
                                   UR[0]) and utils.isLongitudeIn(
                                       lon[i], LL[1], UR[1]):
                    if i != oldI:
                        oldI = i
                        ii += 1
                        oldJ = -1
                        kk = -1
                        oldK = -1
                    if k != oldK:
                        oldK = k
                        kk += 1
    return ii, jj, kk
Пример #6
0
def readSlabFile(modelFile, LL, UR, inc=5):
    """
   read in a 2-D netCDF topo file

   Parameters
   ----------
   modelFile: str
      model file
   LL: list
      lower-left coordinate
   UR: list
      upper-right coordinate
   inc: int
      grid sampling interval

   Returns
   -------
   X: float
      x-coordinate  normalized to the radius of Earh
   Y: float
      y-coordinate  normalized to the radius of Earh
   Z: float
      z-coordinate  normalized to the radius of Earh
   label: str
      file label
   """
    zVariable = 'z'
    lonVariable = 'x'
    latVariable = 'y'
    depthFactor = -1

    #
    # model data
    #
    import numpy as np
    from scipy.io import netcdf
    topodata = netcdf.netcdf_file(modelFile, 'r')
    lat = topodata.variables[latVariable][:].copy()
    lon = topodata.variables[lonVariable][:].copy()
    for i in range(len(lon)):
        if lon[i] > 180.0: lon[i] -= 360.0
    elevData = topodata.variables[zVariable][:].copy()

    topodata.close()

    #
    # select the values within the ranges (this is to get a count only)
    #
    depth2 = [0]
    latitude = []
    longitude = []
    for i in range(0, len(lon), inc):
        for k in range(0, len(lat), inc):
            if utils.isValueIn(lat[k], LL[0], UR[0]) and utils.isLongitudeIn(
                    lon[i], LL[1], UR[1]):
                if lon[i] not in longitude:
                    longitude.append(lon[i])
                if lat[k] not in latitude:
                    latitude.append(lat[k])
    #
    # model data grid definition
    #
    V = {}
    nx = len(longitude)
    ny = len(depth2)
    nz = len(latitude)
    index = [-1, -1, -1]
    label = "%0.1f-%0.1fkm" % (min(depth2), max(depth2))
    for l in range(1):
        X = np.zeros((nx, ny, nz))
        Y = np.zeros((nx, ny, nz))
        Z = np.zeros((nx, ny, nz))
        v = np.zeros((nx, ny, nz))
        latitude = []
        longitude = []
        depth2 = []
        ii = -1
        jj = -1
        kk = -1
        oldI = -1
        oldJ = -1
        oldK = -1
        for i in range(0, len(lon), inc):
            for j in range(1):
                for k in range(0, len(lat), inc):
                    if utils.isValueIn(lat[k], LL[0],
                                       UR[0]) and utils.isLongitudeIn(
                                           lon[i], LL[1], UR[1]):
                        if i != oldI:
                            oldI = i
                            ii += 1
                            oldJ = -1
                            kk = -1
                            oldK = -1
                        if k != oldK:
                            oldK = k
                            kk += 1
                        x, y, z = llz2xyz(lat[k], lon[i],
                                          elevData[k][i] * depthFactor)
                        X[ii, j, kk] = x
                        Y[ii, j, kk] = y
                        Z[ii, j, kk] = z

                        v[ii, j, kk] = elevData[k][i]

        V[zVariable] = v
    return X, Y, Z, V, label
Пример #7
0
def readTopoFile(modelFile, LL, UR, inc):
    """
   read in etopo5, a 2-D netCDF topo file

   Parameters
   ----------
   modelFile: str
      model file
   LL: list
      lower-left coordinate
   UR: list
      upper-right coordinate
   inc: int
      grid sampling interval

   Returns
   -------
   X: float
      x-coordinate  normalized to the radius of Earh
   Y: float
      y-coordinate  normalized to the radius of Earh
   Z: float
      z-coordinate  normalized to the radius of Earh
   label: str
      file label
   """
    zVariable = 'elev'
    lonVariable = 'X'
    latVariable = 'Y'
    #
    # model data
    #
    import numpy as np
    from scipy.io import netcdf
    topodata = netcdf.netcdf_file(modelFile, 'r')
    lat = topodata.variables[latVariable][:].copy()
    lon = topodata.variables[lonVariable][:].copy()
    for i in range(len(lon)):
        if lon[i] > 180.0: lon[i] -= 360.0
    elevData = topodata.variables[zVariable][:].copy()

    topodata.close()

    #
    # select the values within the ranges (this is to get a count only)
    #
    depth2 = [0]
    latitude = []
    longitude = []

    #
    # the loop is intended to include that last lat and lon regardless of inc
    #
    lastI = -1
    for i in range(len(lon)):
        if i != 0 and i != len(lon) - 1 and i != lastI + inc:
            continue
        lastI = i
        lastK = -1
        for k in range(len(lat)):
            if k != 0 and k != len(lat) - 1 and k != lastK + inc:
                continue
            lastK = k
            if utils.isValueIn(lat[k], LL[0], UR[0]) and utils.isLongitudeIn(
                    lon[i], LL[1], UR[1]):
                if lon[i] not in longitude:
                    longitude.append(lon[i])
                if lat[k] not in latitude:
                    latitude.append(lat[k])
    #
    # model data grid definition
    #
    V = {}
    nx = len(longitude)
    ny = len(depth2)
    nz = len(latitude)
    index = [-1, -1, -1]
    label = topodata.description
    for l in range(1):
        X = np.zeros((nx, ny, nz))
        Y = np.zeros((nx, ny, nz))
        Z = np.zeros((nx, ny, nz))
        v = np.zeros((nx, ny, nz))
        latitude = []
        longitude = []
        depth2 = []
        ii = -1
        jj = -1
        kk = -1
        oldI = -1
        oldJ = -1
        oldK = -1
        lastI = -1
        for i in range(len(lon)):
            if i != 0 and i != len(lon) - 1 and i != lastI + inc:
                continue
            lastI = i
            for j in range(1):
                lastK = -1
                for k in range(len(lat)):
                    if k != 0 and k != len(lat) - 1 and k != lastK + inc:
                        continue
                    lastK = k
                    if utils.isValueIn(lat[k], LL[0],
                                       UR[0]) and utils.isLongitudeIn(
                                           lon[i], LL[1], UR[1]):
                        if i != oldI:
                            oldI = i
                            ii += 1
                            oldJ = -1
                            kk = -1
                            oldK = -1
                        if k != oldK:
                            oldK = k
                            kk += 1
                        x, y, z = llz2xyz(
                            lat[k], lon[i],
                            elevData[k][i] * depthFactor / 1000.0)
                        X[ii, j, kk] = x
                        Y[ii, j, kk] = y
                        Z[ii, j, kk] = z

                        v[ii, j, kk] = elevData[k][i]

        V[zVariable] = v
    return X, Y, Z, V, label
Пример #8
0
def find2DnetCDFExtent(modelFile, latVar, lonVar, LL, UR, inc=1):
    """
   find the  extent of a 2-D netCDF  as the number of grid points in each direction

   Parameters
   ----------
   modelFile: str
      model file
   LL: list
      lower-left coordinate
   UR: list
      upper-right coordinate
   inc: int
      grid sampling interval

   Returns
   -------
   ii: int
      number of element in the x-direction
   jj: int
      number of element in the y-direction
   kk: int
      number of element in the z-direction
   """
    lonVariable = lonVar
    latVariable = latVar

    #
    # select the values within the ranges (this is to get a count only)
    #
    import numpy as np
    from scipy.io import netcdf
    twoDnetCDFdata = netcdf.netcdf_file(modelFile, 'r')
    lat = twoDnetCDFdata.variables[latVariable][:].copy()
    lon = twoDnetCDFdata.variables[lonVariable][:].copy()
    for i in range(len(lon)):
        if lon[i] > 180.0: lon[i] -= 360.0
    twoDnetCDFdata.close()

    #
    # model data grid definition
    #
    for l in range(1):
        ii = 0
        jj = 1
        kk = 0
        oldI = -1
        oldJ = -1
        oldK = -1
        lastI = -1
        lastK = -1
        for i in range(len(lon)):
            if i != 0 and i != len(lon) - 1 and i != lastI + inc:
                continue
            lastI = i
            for k in range(len(lat)):
                if k != 0 and k != len(lat) - 1 and k != lastK + inc:
                    continue
                lastK = k
                if utils.isValueIn(lat[k], LL[0],
                                   UR[0]) and utils.isLongitudeIn(
                                       lon[i], LL[1], UR[1]):
                    if i != oldI:
                        oldI = i
                        ii += 1
                        oldJ = -1
                        kk = -1
                        oldK = -1
                    if k != oldK:
                        oldK = k
                        kk += 1
    return ii, jj, kk
Пример #9
0
def read2DnetCDFFile(modelFile,
                     latVariable,
                     lonVariable,
                     variable,
                     LL,
                     UR,
                     inc,
                     setDepth=None):
    """
   read in a 2-D netCDF file

   Parameters
   ----------
   modelFile: str
      model file
   latVar: str
      latitude variable
   lonVar: str
      longitude variable
   var: str
      variable to plot  
   LL: list
      lower-left coordinate
   UR: list
      upper-right coordinate
   inc: int
      grid sampling interval
   depth: float
       depth to plot var at. If None, use var also as depth

    Returns
    -------
    X: float
       x-coordinate  normalized to the radius of Earh
    Y: float
       y-coordinate  normalized to the radius of Earh
    Z: float
       z-coordinate  normalized to the radius of Earh
    meta: dict
       file metadata information
   """
    #
    # model data
    # NetCDF files, when opened read-only, return arrays that refer directly to memory-mapped data on disk:
    #
    import numpy as np
    from scipy.io import netcdf
    emcdata = netcdf.netcdf_file(modelFile, 'r')
    variables = []
    for name in emcdata.variables.keys():
        if name not in (lonVariable, latVariable):
            variables.append(name)

    #
    # I assume all variables are defined with uniform order of latitude and longitude
    #
    var = variables[0]
    for i in range(len(emcdata.variables[var].dimensions)):
        if emcdata.variables[var].dimensions[i] == lonVariable:
            lonIndex = i
        else:
            latIndex = i

    lat = emcdata.variables[latVariable][:].copy()
    lon = emcdata.variables[lonVariable][:].copy()
    for i in range(len(lon)):
        if lon[i] > 180.0: lon[i] -= 360.0

    depth = [0, 1]

    #
    # select the values within the ranges (this is to get a count only)
    #
    depth2 = []
    latitude = []
    longitude = []
    depth2 = []
    lastI = -1
    for i in range(len(lon)):
        if i != 0 and i != len(lon) - 1 and i != lastI + inc:
            continue
        lastI = i
        for j in range(len(depth)):
            lastK = -1
            for k in range(len(lat)):
                if k != 0 and k != len(lat) - 1 and k != lastK + inc:
                    continue
                lastK = k
                if utils.isValueIn(lat[k], LL[0],
                                   UR[0]) and utils.isLongitudeIn(
                                       lon[i], LL[1], UR[1]):
                    if lon[i] not in longitude:
                        longitude.append(lon[i])
                    if depth[j] not in depth2:
                        depth2.append(depth[j])
                    if lat[k] not in latitude:
                        latitude.append(lat[k])

    #
    # model data grid definition
    #
    V = {}
    nx = len(longitude)
    ny = len(depth2)
    nz = len(latitude)
    index = [-1, -1, -1]
    meta = {
        'depth': [],
        'lat': [100, -100],
        'lon': [400, -400],
        'source': modelFile
    }
    for l in range(len(variables)):
        X = np.zeros((nx, ny, nz))
        Y = np.zeros((nx, ny, nz))
        Z = np.zeros((nx, ny, nz))
        v = np.zeros((nx, ny, nz))
        var = variables[l]
        emcin = emcdata.variables[var][:].copy()
        latitude = []
        longitude = []
        depth2 = []
        ii = -1
        jj = -1
        kk = -1
        oldI = -1
        oldJ = -1
        oldK = -1
        lastI = -1
        for i in range(len(lon)):
            if i != 0 and i != len(lon) - 1 and i != lastI + inc:
                continue
            lastI = i
            for j in range(len(depth)):
                lastK = -1
                for k in range(len(lat)):
                    if k != 0 and k != len(lat) - 1 and k != lastK + inc:
                        continue
                    lastK = k
                    if utils.isValueIn(lat[k], LL[0],
                                       UR[0]) and utils.isLongitudeIn(
                                           lon[i], LL[1], UR[1]):
                        if i != oldI:
                            meta['lon'] = [
                                min(meta['lon'][0], lon[i]),
                                max(meta['lon'][0], lon[i])
                            ]
                            oldI = i
                            ii += 1
                            jj = -1
                            oldJ = -1
                            kk = -1
                            oldK = -1
                        if j != oldJ:
                            if depth[j] not in meta['depth']:
                                meta['depth'].append(depth[j])
                            oldJ = j
                            jj += 1
                            kk = -1
                            oldK = -1
                        if k != oldK:
                            meta['lat'] = [
                                min(meta['lat'][0], lat[k]),
                                max(meta['lat'][0], lat[k])
                            ]
                            oldK = k
                            kk += 1

                        index[latIndex] = k
                        index[lonIndex] = i
                        thisValue = emcin[index[0]][index[1]]
                        if thisValue <= -990 or thisValue > 9999:
                            thisValue = None
                        if thisValue is None:
                            v[ii, jj, kk] = None
                        else:
                            v[ii, jj, kk] = float(thisValue)
                        if setDepth is None:
                            if thisValue is None:
                                thisDepth = 0
                            else:
                                thisDepth = float(thisValue)
                        else:
                            thisDepth = float(thisValue)
                        x, y, z = llz2xyz(lat[k], lon[i], thisDepth)
                        X[ii, jj, kk] = x
                        Y[ii, jj, kk] = y
                        Z[ii, jj, kk] = z

        V[var] = v
    emcdata.close()
    return X, Y, Z, V, meta
Пример #10
0
def read_geocsv_model_3d(model_file,
                         ll,
                         ur,
                         depth_min,
                         depth_max,
                         roughness,
                         inc,
                         extent=False):
    """Read in a 3-D Earth model in the GeoCSV format.

      Keyword arguments:
      model_file: model file
      ll: lower-left coordinate
      ur: upper-right coordinate
      depth_min: minimum depth
      depth_max: maximum depth
      inc: grid sampling interval
      extent: provide model extent only (True or False)

      Return values:
      x: x-coordinate  normalized to the radius of the Earth
      y: y-coordinate  normalized to the radius of the Earth
      z: z-coordinate  normalized to the radius of the Earth
      meta: file metadata information
     """

    # model data and metadata
    (params, lines) = read_geocsv(model_file)

    # model data
    data = []
    for line in lines:
        data.append(line.split(params['delimiter']))

    # model variables
    depth_variable = params['depth_column']
    lat_variable = params['latitude_column']
    lon_variable = params['longitude_column']
    elev_variable = params['elevation_column']
    variables = []
    for this_param in list(params.keys()):
        if params[this_param] not in (
                depth_variable, lon_variable, lat_variable,
                elev_variable) and '_column' in this_param:
            variables.append(params[this_param])

    # index to the variables
    var_index = {}
    for i, val in enumerate(params['header']):
        if val == depth_variable:
            depth_index = i
        elif val == lon_variable:
            lon_index = i
        elif val == lat_variable:
            lat_index = i
        else:
            var_index[val] = i

    lat = np.array(list(set(get_column(data, lat_index))), dtype=float)
    lon = np.array(list(set(get_column(data, lon_index))), dtype=float)

    # -180/180 models are the norm, so we convert 0/360 models to -180/180 first to unify
    # the rest of the code for all models
    data = np.ndarray.tolist(np.asfarray(data))
    if utils.lon_is_360(lon):
        for i, values in enumerate(data):
            if float(values[lon_index]) > 180.0:
                data[i][lon_index] = float(values[lon_index]) - 360.0
        lon = np.array(list(set(get_column(data, lon_index))), dtype=float)

    # we want the grid to be in x, y z order (longitude, depth, latitude)
    data.sort(key=itemgetter(lon_index, depth_index, lat_index))

    lon.sort()
    lon, lon_map = utils.lon_180(lon, fix_gap=True)
    depth = np.array(list(set(get_column(data, depth_index))), dtype=float)

    # get coordinates sorted one last time
    lat.sort()
    lon.sort()
    depth.sort()

    # select the coordinates within the ranges (this is to get a count only)
    latitude = []
    longitude = []
    depth2 = []
    last_i = -1

    for i, lon_val in enumerate(lon):
        if i != 0 and i != len(lon) - 1 and i != last_i + inc:
            continue

        last_i = i
        for j, depth_val in enumerate(depth):
            last_k = -1
            for k, lat_val in enumerate(lat):
                if k != 0 and k != len(lat) - 1 and k != last_k + inc:
                    continue
                last_k = k

                if utils.isValueIn(float(lat_val), ll[0], ur[0]) and utils.isLongitudeIn(
                        float(lon_val), ll[1], ur[1]) and \
                        utils.isValueIn(float(depth_val), depth_min, depth_max):
                    if float(lon_map[utils.float_key(
                            lon_val)]) not in longitude:
                        longitude.append(
                            float(lon_map[utils.float_key(lon_val)]))
                    if float(depth_val) not in depth2:
                        depth2.append(float(depth_val))
                    if float(lat_val) not in latitude:
                        latitude.append(float(lat_val))

    # model data grid definition
    V = {}
    nx = len(longitude)
    ny = len(depth2)
    nz = len(latitude)
    if extent:
        return nx - 1, ny - 1, nz - 1

    meta = {
        'depth': [],
        'lat': [100, -100],
        'lon': [400, -400],
        'source': model_file
    }

    X = np.zeros((nx, ny, nz))
    X[:] = np.nan
    Y = np.zeros((nx, ny, nz))
    Y[:] = np.nan
    Z = np.zeros((nx, ny, nz))
    Z[:] = np.nan

    for i, values in enumerate(data):
        lon_val = float(lon_map[utils.float_key(values[lon_index])])
        lat_val = float(values[lat_index])
        depth_val = float(values[depth_index])

        if lon_val in longitude and lat_val in latitude and depth_val in depth2:
            meta['lon'] = [
                min(meta['lon'][0], lon_val),
                max(meta['lon'][0], lon_val)
            ]
            meta['lat'] = [
                min(meta['lat'][0], lat_val),
                max(meta['lat'][0], lat_val)
            ]
            if depth_val not in meta['depth']:
                meta['depth'].append(depth_val)
            x, y, z = llz2xyz(lat_val, lon_val, depth_val * roughness)

            ii = longitude.index(lon_val)
            jj = depth2.index(depth_val)
            kk = latitude.index(lat_val)
            X[ii, jj, kk] = x
            Y[ii, jj, kk] = y
            Z[ii, jj, kk] = z

            for l, var_val in enumerate(variables):
                if var_val not in list(V.keys()):
                    V[var_val] = np.zeros((nx, ny, nz))
                    V[var_val][:] = np.nan
                if '_'.join([var_val, 'missing_value']) in params:
                    # skip the designated missing_value
                    if float(values[var_index[var_val]]) == float(
                            params['_'.join([var_val, 'missing_value'])]):
                        continue
                V[var_val][ii, jj, kk] = float(values[var_index[var_val]])

    return X, Y, Z, V, meta