Example #1
0
def RequestInformation():
    sys.path.insert(0, r'EMC_SRC_PATH')
    import IrisEMC_Paraview_Lib as lib
    from paraview import util
    from os.path import splitext
    import IrisEMC_Paraview_Utils as utils
    import IrisEMC_Paraview_Param as param

    depth_begin = float(Depth_begin)
    depth_end = float(Depth_end)
    File_name = File_name.strip()
    ext = None
    if File_name in list(param.filesDict.values()) or not (
            File_name.lower().endswith(param.filesExtDict['ssl'].lower())
            or File_name.lower().endswith(param.filesExtDict['geo'].lower())):
        if utils.support_nc():
            ext = param.filesExtDict['ssl']
        else:
            ext = param.filesExtDict['geo']

    fileFound, address, source = lib.find_file(File_name,
                                               loc=r'EMC_MODELS_PATH',
                                               ext=ext)
    if not fileFound:
        raise Exception('model file "' + address + '" not found! Aborting.')
    Latitude_begin, Latitude_end, Longitude_begin, Longitude_end = lib.get_area(
        Area, Latitude_begin, Latitude_end, Longitude_begin, Longitude_end)
    this_filename, extension = splitext(address)
    if extension.lower() == '.nc':
        nx, ny, nz = lib.read_netcdf_model(address,
                                           Latitude_variable,
                                           Longitude_variable,
                                           Depth_variable,
                                           (Latitude_begin, Longitude_begin),
                                           (Latitude_end, Longitude_end),
                                           depth_begin,
                                           depth_end,
                                           Vertical_Scaling,
                                           inc=Sampling,
                                           extent=True)
    else:
        try:
            nx, ny, nz = lib.read_geocsv_model_3d(
                address, (Latitude_begin, Longitude_begin),
                (Latitude_end, Longitude_end),
                depth_begin,
                depth_end,
                Vertical_Scaling,
                inc=Sampling,
                extent=True)
        except Exception:
            raise Exception('cannot recognize model file "' + address +
                            '"! Aborting.')

    # ABSOLUTELY NECESSARY FOR THE READER TO WORK:
    util.SetOutputWholeExtent(self, [0, nx, 0, ny, 0, nz])
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
Example #3
0
def RequestInformation():
    from os.path import splitext
    sys.path.insert(0, r'EMC_SRC_PATH')
    import IrisEMC_Paraview_Lib as lib
    from paraview import util
    import IrisEMC_Paraview_Utils as utils
    import IrisEMC_Paraview_Param as param

    Latitude_Begin, Latitude_End, Longitude_Begin, Longitude_End = lib.get_area(
        Area, Latitude_Begin, Latitude_End, Longitude_Begin, Longitude_End)

    if len(Alternate_FileName.strip()) > 0:
        FileName = Alternate_FileName.strip()
        Label = ' '.join(['SLAB', lib.file_name(Alternate_FileName).strip()])
    else:
        FileName = lib.usgsSlabKeys[Slab]
        Label = ' '.join(['USGS Slab 1.0 -', lib.usgsSlabValues[Slab].strip()])

    FileName = FileName.strip()
    ext = None
    if FileName in list(param.usgsSlabDict.keys()):
        if utils.support_nc():
            ext = param.usgsSlabExtDict['ssl']
        else:
            ext = param.usgsSlabExtDict['geo']

    fileFound, address, source = lib.find_file(FileName,
                                               loc=r'EMC_SLABS_PATH',
                                               ext=ext)

    if not fileFound:
        raise Exception('model file "' + address + '" not found! Aborting.')

    this_filename, extension = splitext(address)

    if extension.lower() == '.grd':
        nx, ny, nz = lib.read_slab_file(address,
                                        (Latitude_Begin, Longitude_Begin),
                                        (Latitude_End, Longitude_End),
                                        inc=Sampling,
                                        extent=True)
    elif extension.lower() == '.csv':
        nx, ny, nz = lib.read_geocsv_model_2d(
            address, (Latitude_Begin, Longitude_Begin),
            (Latitude_End, Longitude_End),
            Sampling,
            0,
            extent=True)

    else:
        raise Exception('cannot recognize model file "' + address +
                        '"! Aborting.')

    # ABSOLUTELY NECESSARY FOR THE READER TO WORK:
    util.SetOutputWholeExtent(self, [0, nx, 0, ny, 0, nz])
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
Example #5
0
def RequestInformation():
    sys.path.insert(0, r'EMC_SRC_PATH')
    from os.path import splitext
    import IrisEMC_Paraview_Lib as lib
    from paraview import util
    import IrisEMC_Paraview_Utils as utils
    import IrisEMC_Paraview_Param as param

    if len(Alternate_FileName.strip()) > 0:
        file_name = Alternate_FileName.strip()
    else:
        file_name = lib.topoKeys[TopoFile]

    file_name = file_name.strip()
    ext = None
    if file_name in list(param.topoDict.keys()):
        if utils.support_nc():
            ext = param.topoExtDict['ssl']
        else:
            ext = param.topoExtDict['geo']

    fileFound, address, source = lib.find_file(file_name,
                                               loc=r'EMC_MODELS_PATH',
                                               ext=ext)
    Latitude_Begin, Latitude_End, Longitude_Begin, Longitude_End = lib.get_area(
        Area, Latitude_Begin, Latitude_End, Longitude_Begin, Longitude_End)

    this_filename, extension = splitext(address)
    if extension.lower() in ['.nc', '.grd']:
        nx, ny, nz = lib.read_netcdf_topo_file(
            address, (Latitude_Begin, Longitude_Begin),
            (Latitude_End, Longitude_End),
            Sampling,
            Roughness,
            lon_var=Longitude_Variable,
            lat_var=Latitude_Variable,
            elev_var=Elevation_Variable,
            extent=True)
    else:
        try:
            nx, ny, nz = lib.read_geocsv_model_2d(
                address, (Latitude_Begin, Longitude_Begin),
                (Latitude_End, Longitude_End),
                Sampling,
                Roughness,
                extent=True)
        except Exception:
            raise Exception('cannot recognize model file "' + address +
                            '"! Aborting.')

    # ABSOLUTELY NECESSARY FOR THE READER TO WORK:
    util.SetOutputWholeExtent(self, [0, nx, 0, ny, 0, nz])
def xyz2llz(x, y, z):
    """convert earth-centered, earth-fixed (ECEF) cartesian x, y, z to latitude, longitude, and altitude

    code is based on:

    https://www.mathworks.com/matlabcentral/fileexchange/7941-convert-cartesian--ecef--coordinates-to-lat--lon--alt?
                 focused=5062924&tab=function

     Keyword arguments:
     x: x-coordinate  normalized to the radius of Earh
     y: y-coordinate  normalized to the radius of Earh
     z: z-coordinate  normalized to the radius of Earh

     Return values:
     lat: latitude (deg)
     lon: longitude (deg)
     depth: depth (km)
    """

    # World Geodetic System 1984, WGS 84
    erad = np.float64(
        6378137.0)  # Radius of the Earth in meters (equatorial radius, WGS84)
    rad = 1  # sphere radius
    e = np.float64(8.1819190842622e-2)

    # convert to radius
    x = x * erad / rad
    y = y * erad / rad
    z = z * erad / rad

    b = np.sqrt(erad * erad * (1 - e * e))
    ep = np.sqrt((erad * erad - b * b) / (b * b))
    p = np.sqrt(x * x + y * y)
    th = np.arctan2(erad * z, b * p)
    lon = np.arctan2(y, x)
    lat = np.arctan2((z + ep * ep * b * np.sin(th) * np.sin(th) * np.sin(th)),
                     (p - e * e * erad * np.cos(th) * np.cos(th) * np.cos(th)))
    N = erad / np.sqrt(1.0 - e * e * np.sin(lat) * np.sin(lat))
    alt = p / np.cos(lat) - N

    lon = np.mod(lon, (math.pi * 2.0))
    lon = np.rad2deg(lon)
    lon = utils.lon_180(lon)
    lat = np.rad2deg(lat)
    alt = -1 * alt / 1000.0  # depth as negative alt

    return lat, lon, alt
def read_netcdf_model(model_file,
                      lat_variable,
                      lon_variable,
                      depth_variable,
                      ll,
                      ur,
                      depth_min,
                      depth_max,
                      roughness,
                      inc,
                      extent=False):
    """read in an EMC Earth model in the netCDF 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

      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
    """

    # ParaView on some platforms does not have SciPy module
    if not utils.support_nc():
        print(
            "[ERR] Cannot read netCDF files on this platform, try GeoCSV format!"
        )
        return [], [], [], [], {}

    # NetCDF files, when opened read-only, return arrays that refer directly to memory-mapped data on disk:
    print(f"[INFO] Reading model file {model_file}")
    data = netcdf.netcdf_file(model_file, 'r')
    variables = []
    for name in list(data.variables.keys()):
        if name not in (depth_variable, lon_variable, lat_variable):
            variables.append(name)

    # expects variables be a function of latitude, longitude and depth, find the order
    var = variables[0]
    for i, value in enumerate(data.variables[var].dimensions):
        if value == depth_variable:
            depth_index = i
        elif value == lon_variable:
            lon_index = i
        else:
            lat_index = i

    lat = data.variables[lat_variable][:].copy()
    lon = data.variables[lon_variable][:].copy()
    lon, lon_map = utils.lon_180(lon, fix_gap=True)

    depth = data.variables[depth_variable][:].copy()

    # select the values within the ranges (this is to get a count only)
    latitude, longitude, depth2 = get_points_in_volume(lat, lon, depth, ll, ur,
                                                       inc, depth_min,
                                                       depth_max)

    # model data grid definition
    V = {}
    nx = len(longitude)
    ny = len(depth2)
    nz = len(latitude)
    if extent:
        return nx - 1, ny - 1, nz - 1
    index = [-1, -1, -1]
    meta = {
        'depth': [],
        'lat': [100, -100],
        'lon': [400, -400],
        'source': model_file
    }

    missing_value = None
    if hasattr(data.variables[var], 'missing_value'):
        missing_value = float(data.variables[var].missing_value)

    for l, var_val in enumerate(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))
        data_in = data.variables[var_val][:].copy()

        # increment longitudes, we want to keep the first and last longitude regardless of inc
        for i, lon_val in enumerate(lon):
            for j, depth_val in enumerate(depth):
                for k, lat_val in enumerate(lat):
                    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

                        index[depth_index] = j
                        index[lat_index] = k
                        index[lon_index] = i

                        this_value = data_in[index[0]][index[1]][index[2]]

                        if this_value is None:
                            v[ii, jj, kk] = None
                        elif this_value is not None:
                            if this_value == missing_value:
                                v[ii, jj, kk] = None
                                this_value = None
                            else:
                                v[ii, jj, kk] = this_value
                        else:
                            v[ii, jj, kk] = this_value

        V[var_val] = v
    data.close()
    return X, Y, Z, V, meta
    2019-01-30 Manoch: v.2019.030 event service call request order changed from magnitude to time-asc
    2019-01-22 Manoch: v.2019.022 added animation directory under earthquakes path and introduced time_column
                       for use with earthquake
    2019-01-14 Manoch: v.2019.014 support for getting the default volcano data from IRIS EMC file repository
    2018-11-12 Manoch: v.2018.316 added Platform check to load .csv files instead of .nc for Windows
    2018-10-17 Manoch: v.2018.290 updates for R1
    2018-09-13 Manoch: v.2018.256 added support for EMC_DEFAULT_GSV_MODEL
    2018-05-09 Manoch: v.2018.129 added EMC_DEFAULT_2DMODEL tp fileDict
    2018-04-27 Manoch: v.2018.117 updateid irisEMC_Files_URL
    2018-04-23 Manoch: v.2018.113 updateid lat and lon limits for the world
                       added very low resolution coastline data file
    2018-03-21 Manoch: v.2018.080 release
"""

# see if SSL is available for HTTPS requests
ssl_available = utils.do_https()
HTTP_PROTOCOL = 'https:'
if not ssl_available:
    HTTP_PROTOCOL = 'http:'


def sort_dict_by_value(dictionary):
    """Splits a Python dictionary to two lists containing keys and values sorted by values.

    Keyword arguments:
    thisDict: a Python dictionary

    Return values:
    keys: list of keys in the dictionary
    values: list of values in the dictionary
    """
Example #9
0
def RequestData():
    # V.2019.030
    import sys
    sys.path.insert(0, r'EMC_SRC_PATH')
    from paraview.simple import RenameSource, GetActiveViewOrCreate, ColorBy, GetDisplayProperties, GetActiveSource
    import numpy as np
    import csv
    import os
    from os.path import splitext
    from vtk.util import numpy_support as nps
    import IrisEMC_Paraview_Lib as lib
    import IrisEMC_Paraview_Utils as utils
    import IrisEMC_Paraview_Param as param

    # elevation units in meters
    Roughness = -1 * float(Roughness)

    baseline = float(Depth_Bias)

    if len(Alternate_FileName.strip()) > 0:
        file_name = Alternate_FileName.strip()
        label = ' '.join(['Topo', lib.file_name(Alternate_FileName).strip()])
    else:
        file_name = lib.topoKeys[TopoFile]
        label = lib.topoValues[TopoFile]

    file_name = file_name.strip()
    ext = None
    if file_name in list(param.topoDict.keys()):
        if utils.support_nc():
            ext = param.topoExtDict['ssl']
        else:
            ext = param.topoExtDict['geo']

    # make sure we have input files
    file_found, address, source = lib.find_file(file_name,
                                                loc=r'EMC_MODELS_PATH',
                                                ext=ext)

    if not file_found:
        raise Exception('Topo file "' + address + '" not found! Aborting.')

    this_filename, extension = splitext(address)

    sg = self.GetOutput()  # vtkPolyData

    Latitude_Begin, Latitude_End, Longitude_Begin, Longitude_End = lib.get_area(
        Area, Latitude_Begin, Latitude_End, Longitude_Begin, Longitude_End)

    label2 = " - %s (%0.1f,%0.1f,%0.1f,%0.1f)" % (
        lib.areaValues[Area], Latitude_Begin, Latitude_End, Longitude_Begin,
        Longitude_End)

    if extension.lower() in ['.nc', '.grd']:

        X, Y, Z, V, label = lib.read_netcdf_topo_file(
            address, (Latitude_Begin, Longitude_Begin),
            (Latitude_End, Longitude_End),
            Sampling,
            Roughness,
            base=baseline,
            lon_var=Longitude_Variable,
            lat_var=Latitude_Variable,
            elev_var=Elevation_Variable,
            unit_factor=float(Unit_Factor),
            extent=False)

    else:
        try:
            X, Y, Z, V, meta = lib.read_geocsv_model_2d(
                address, (Latitude_Begin, Longitude_Begin),
                (Latitude_End, Longitude_End),
                Sampling,
                Roughness,
                base=baseline,
                unit_factor=float(Unit_Factor),
                extent=False)

        except Exception:
            raise Exception('cannot recognize model file "' + address +
                            '"! Aborting.')

    nx = len(X)
    ny = len(X[0])
    nz = len(X[0][0])
    sg.SetDimensions(nx, ny, nz)

    #
    # make geometry
    #
    points = vtk.vtkPoints()
    for k in range(nz):
        for j in range(ny):
            for i in range(nx):
                points.InsertNextPoint((X[i, j, k], Y[i, j, k], Z[i, j, k]))
    sg.SetPoints(points)

    #
    # make geometry
    #
    count = 0
    for var in list(V.keys()):
        scalars = vtk.vtkFloatArray()
        scalars.SetNumberOfComponents(1)
        scalars.SetName(var)
        for k in range(nz):
            for j in range(ny):
                for i in range(nx):
                    scalars.InsertNextValue(V[var][i, j, k])
        if count == 0:
            sg.GetPointData().SetScalars(scalars)
        else:
            sg.GetPointData().AddArray(scalars)
        count += 1

    # store metadata
    fieldData = sg.GetFieldData()
    fieldData.AllocateArrays(3)  # number of fields

    data = vtk.vtkFloatArray()
    data.SetName('Latitude\nRange (deg)')
    data.InsertNextValue(Latitude_Begin)
    data.InsertNextValue(Latitude_End)
    fieldData.AddArray(data)

    data = vtk.vtkFloatArray()
    data.SetName('Longitude\nRange (deg)')
    data.InsertNextValue(Longitude_Begin)
    data.InsertNextValue(Longitude_End)
    fieldData.AddArray(data)

    data = vtk.vtkStringArray()
    data.SetName('Source')
    data.InsertNextValue(source)
    fieldData.AddArray(data)
    RenameSource(' '.join(
        [label.strip(), 'from',
         source.strip(), label2.strip()]))
Example #10
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
Example #11
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
Example #12
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
Example #13
0
def RequestData():
    # V.2019.079
    import sys
    sys.path.insert(0, r'EMC_SRC_PATH')
    from paraview.simple import RenameSource, GetActiveViewOrCreate, ColorBy, GetDisplayProperties, GetActiveSource
    import numpy as np
    import csv
    import os
    from os.path import splitext
    from vtk.util import numpy_support as nps
    import IrisEMC_Paraview_Lib as lib
    import IrisEMC_Paraview_Utils as utils
    import IrisEMC_Paraview_Param as param

    File_name = File_name.strip()
    ext = None
    if File_name in list(param.filesDict.values()) or not (
            File_name.lower().endswith(param.filesExtDict['ssl'].lower())
            or File_name.lower().endswith(param.filesExtDict['geo'].lower())):
        if utils.support_nc():
            ext = param.filesExtDict['ssl']
        else:
            ext = param.filesExtDict['geo']
    depth_begin = float(Depth_begin)
    depth_end = float(Depth_end)
    if depth_begin > depth_end:
        raise Exception('Begin Depth < End Depth! Aborting.')

    Latitude_begin, Latitude_end, Longitude_begin, Longitude_end = lib.get_area(
        Area, Latitude_begin, Latitude_end, Longitude_begin, Longitude_end)

    if len(Latitude_variable.strip()) <= 0 or len(
            Longitude_variable.strip()) <= 0 or len(
                Depth_variable.strip()) <= 0:
        raise Exception('Latitude, Longitude and Depth variable are required')

    # make sure we have input files
    fileFound, address, source = lib.find_file(File_name,
                                               loc=r'EMC_MODELS_PATH',
                                               ext=ext)
    if not fileFound:
        raise Exception('model file "' + address + '" not found! Aborting.')

    filename = lib.file_name(File_name)
    if len(Label.strip()) <= 0:
        if source == filename:
            Label = "%s " % (filename)
        else:
            Label = "%s from %s " % (filename, source)

    sg = self.GetOutput()  # vtkPolyData

    this_filename, extension = splitext(address)
    if extension.lower() in ['.nc', '.grd']:
        X, Y, Z, V, meta = lib.read_netcdf_model(
            address, Latitude_variable, Longitude_variable, Depth_variable,
            (Latitude_begin, Longitude_begin), (Latitude_end, Longitude_end),
            depth_begin, depth_end, Vertical_Scaling, Sampling)
    else:
        try:
            X, Y, Z, V, meta = lib.read_geocsv_model_3d(
                address, (Latitude_begin, Longitude_begin),
                (Latitude_end, Longitude_end), depth_begin, depth_end,
                Vertical_Scaling, Sampling)
        except Exception as e:
            raise Exception('cannot recognize model file "' + address +
                            '"! Aborting.\n' + str(e))

    nx = len(X)
    if nx <= 0:
        raise Exception('No data found!')
    ny = len(X[0])
    nz = len(X[0][0])
    sg.SetDimensions(nx, ny, nz)

    # make geometry
    points = vtk.vtkPoints()
    for k in range(nz):
        for j in range(ny):
            for i in range(nx):
                points.InsertNextPoint((X[i, j, k], Y[i, j, k], Z[i, j, k]))
    sg.SetPoints(points)

    # make geometry
    count = 0
    for var in list(V.keys()):
        scalars = vtk.vtkFloatArray()
        scalars.SetNumberOfComponents(1)
        scalars.SetName(var)
        for k in range(nz):
            for j in range(ny):
                for i in range(nx):
                    if V[var][i, j, k] == float('nan'):
                        scalars.InsertNextValue(float('nan'))
                    else:
                        scalars.InsertNextValue(V[var][i, j, k])
        if count == 0:
            sg.GetPointData().SetScalars(scalars)
        else:
            sg.GetPointData().AddArray(scalars)
        count += 1

    # store boundary metadata
    field_data = sg.GetFieldData()
    field_data.AllocateArrays(3)  # number of fields

    data = vtk.vtkFloatArray()
    data.SetName('Latitude\nRange (deg)')
    data.InsertNextValue(meta['lat'][0])
    data.InsertNextValue(meta['lat'][1])
    field_data.AddArray(data)

    data = vtk.vtkFloatArray()
    data.SetName('Longitude\nRange (deg)')
    data.InsertNextValue(meta['lon'][0])
    data.InsertNextValue(meta['lon'][1])
    field_data.AddArray(data)

    data = vtk.vtkFloatArray()
    data.SetName('Depths (km)')
    for d in sorted(meta['depth']):
        data.InsertNextValue(d)
    field_data.AddArray(data)

    data = vtk.vtkStringArray()
    data.SetName('Source')
    data.InsertNextValue(File_name)
    field_data.AddArray(data)

    label_2 = " - %s (lat:%0.1f,%0.1f, lon:%0.1f,%0.1f, depth:%0.1f - %0.1f)" % (
        lib.areaValues[Area], meta['lat'][0], meta['lat'][1], meta['lon'][0],
        meta['lon'][1], meta['depth'][0], meta['depth'][-1])
    RenameSource(' '.join([Label.strip(), label_2.strip()]))
    sg.SetFieldData(field_data)
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
def find_file(address, loc, query='', ext=None):
    """find a file either locally or via a URL

    Keyword arguments:
    address: file address, path, url, etc.
    loc: location of the file
    query: URL query string

    Return values:
    found: indicating if the operation was a success
    address: full address of the local file
    source: where the file came from
    """

    found = False

    # For default files, the calling script sends the proper extension to use depending on the OS support.
    if ext is not None:
        address = ''.join([address, ext])
    if address.lower().endswith('.nc') and not utils.support_nc():
        print(
            "[ERR] Cannot read netCDF files on this platform, try GeoCSV format!"
        )
        return False, address, address

    # It is a full path to a file?
    source = address
    if os.path.isfile(address):
        origin = read_info_file(source)
        return True, address, origin

    # It is a file under the data directory?
    elif os.path.isfile(os.path.join(loc, address)):
        source = os.path.join(loc, address)
        origin = read_info_file(source)
        return True, source, origin

    # Other possibilities, URL?
    else:
        # Check the DMC URL.
        if loc in (pathDict['EMC_BOUNDARIES_PATH'],
                   pathDict['EMC_MODELS_PATH'],
                   pathDict['EMC_VOLCANOES_PATH']):
            source = irisEMC_Files_URL + address
            if is_url_valid(source):
                found, destination, origin = get_file_from_url(
                    source, loc, filename=os.path.join(loc, address))

        # USGS Slab 1.0
        elif loc == pathDict['EMC_SLABS_PATH']:
            source = usgsSlab_URL + address
            if is_url_valid(source):
                found, destination, origin = get_file_from_url(
                    source, loc, filename=os.path.join(loc, address))

        # Earthquakes.
        elif loc == pathDict['EMC_EARTHQUAKES_PATH']:
            source = query
            if is_url_valid(source):
                found, destination, origin = get_file_from_url(
                    source, loc, filename=os.path.join(loc, address))
                if found:
                    fp = open(destination, 'r+')
                    catalog = fp.read()
                    fp.seek(0, 0)
                    fp.write(eq_header(source))
                    fp.write(catalog)
                    fp.close()

        # Did we find the file?
        if found:
            return found, destination, origin

        # Did user provide a URL.
        else:
            found, destination, origin = get_file_from_url(address, loc, query)
            return found, destination, origin
def read_netcdf_topo_file(model_file,
                          ll,
                          ur,
                          inc,
                          roughness,
                          lon_var='longitude',
                          lat_var='latitude',
                          elev_var='elevation',
                          base=0,
                          unit_factor=1,
                          extent=False):
    """read in etopo, a 2-D netCDF topo file

    Keyword arguments:
    model_file: model file
    ll: lower-left coordinate
    ur: upper-right coordinate
    inc: grid sampling interval
    roughness: set the variable as depth and use this for exaggeration
    extent: should only compute model extent? (True or False)

    RReturn values:
    X: x-coordinate  normalized to the radius of Earh
    Y: y-coordinate  normalized to the radius of Earh
    Z: z-coordinate  normalized to the radius of Earh
    label: file label
    """

    # ParaView on some platforms does not have SciPy module

    if not utils.support_nc():
        print("[ERR] Sorry, cannot read netCDF files on this platform!")
        return 0, 0, 0

    z_variable = elev_var
    lon_variable = lon_var
    lat_variable = lat_var
    depth = base
    # model data
    data = netcdf.netcdf_file(model_file, 'r')
    lat = data.variables[lat_variable][:].copy()
    lon = data.variables[lon_variable][:].copy()
    lon = utils.lon_180(lon)
    elevation_data = data.variables[z_variable][:].copy()

    data.close()
    dep = [depth]
    variables = [z_variable]

    # select the values within the ranges (this is to get a count only)
    latitude, longitude, depth2 = get_points_in_area(lat, lon, dep, ll, ur,
                                                     inc)

    # model data grid definition
    V = {}
    nx = len(longitude)
    ny = len(depth2)
    nz = len(latitude)

    if extent:
        return nx - 1, ny - 1, nz - 1

    label = ''
    if hasattr(data, 'description'):
        label = data.description
    elif hasattr(data, 'title'):
        label = data.title

    for l, var_value in enumerate(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))

        for i, lon_val in enumerate(lon):
            for j, depth_val in enumerate(dep):
                for k, lat_val in enumerate(lat):
                    if lon_val in longitude and lat_val in latitude and depth_val in depth2:
                        ii = longitude.index(lon_val)
                        jj = depth2.index(depth_val)
                        kk = latitude.index(lat_val)
                        # "+" since it is elevation but we already making roughness negative to make it positive up
                        x, y, z = llz2xyz(
                            lat_val, lon_val, depth_val +
                            (elevation_data[k][i] * roughness * unit_factor))
                        X[ii, jj, kk] = x
                        Y[ii, jj, kk] = y
                        Z[ii, jj, kk] = z

                        v[ii, jj,
                          kk] = elevation_data[k][i] * float(unit_factor)

    V[z_variable] = v
    return X, Y, Z, V, label
def read_slab_file(model_file, ll, ur, inc=1, depth_factor=-1, extent=False):
    """read in a 2-D netCDF Slab file

    Keyword arguments:
    model_file: model file
    ll: lower-left coordinate
    ur: upper-right coordinate
    inc: grid sampling interval

    RReturn values:
    X: x-coordinate  normalized to the radius of Earh
    Y: y-coordinate  normalized to the radius of Earh
    Z: z-coordinate  normalized to the radius of Earh
    label: file label
    """

    # ParaView on some systems does not have SciPy module
    if not utils.support_nc():
        print(
            "[ERR] Cannot read netCDF files on this platform, try GeoCSV format!"
        )
        return [], [], [], [], ''

    z_variable = 'z'
    lon_variable = 'x'
    lat_variable = 'y'
    depth = 0

    # model data
    data = netcdf.netcdf_file(model_file, 'r')
    lat = data.variables[lat_variable][:].copy()
    lon = data.variables[lon_variable][:].copy()
    lon = utils.lon_180(lon)
    elevation_data = data.variables[z_variable][:].copy()

    data.close()
    dep = [depth]
    variables = [z_variable]

    # select the values within the ranges (this is to get a count only)
    latitude, longitude, depth2 = get_points_in_area(lat, lon, dep, ll, ur,
                                                     inc)

    # model data grid definition
    V = {}
    nx = len(longitude)
    ny = len(depth2)
    nz = len(latitude)

    if extent:
        return nx - 1, ny - 1, nz - 1

    label = ''
    if len(depth2):
        label = "%0.1f-%0.1fkm" % (min(depth2), max(depth2))

    for l, var_value in enumerate(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))

        for i, lon_val in enumerate(lon):
            for j, depth_val in enumerate(dep):
                for k, lat_val in enumerate(lat):
                    if lon_val in longitude and lat_val in latitude and depth_val in depth2:
                        ii = longitude.index(lon_val)
                        jj = depth2.index(depth_val)
                        kk = latitude.index(lat_val)
                        x, y, z = llz2xyz(lat[k], lon[i],
                                          elevation_data[k][i] * depth_factor)
                        X[ii, jj, kk] = x
                        Y[ii, jj, kk] = y
                        Z[ii, jj, kk] = z

                        v[ii, jj, kk] = elevation_data[k][i]

    V[z_variable] = v
    return X, Y, Z, V, label
Example #18
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
def read_geocsv_model_2d(model_file,
                         ll,
                         ur,
                         inc,
                         roughness,
                         unit_factor=1,
                         base=0,
                         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
      inc: grid sampling interval
      roughness: set the variable as depth and use this for exaggeration
      extent: should only compute model extent? (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, is_2d=True)

    # model data
    raw_data = []
    for line in lines:
        raw_data.append(line.split(params['delimiter']))
    data = [list(utils.str2float(sublist)) for sublist in raw_data]

    # model variables
    variables = []
    for this_param in list(params.keys()):
        if params[this_param] not in (
                params['longitude_column'],
                params['latitude_column']) 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 == params['longitude_column']:
            lon_index = i
        elif val == params['latitude_column']:
            lat_index = i
        else:
            for this_var in variables:
                if val == params[this_var + '_column']:
                    var_index[this_var] = i
                    break

    lat = list(set(get_column(data, lat_index)))
    lon = list(set(get_column(data, lon_index)))
    lon.sort(key=float)
    lon, lon_map = utils.lon_180(lon, fix_gap=True)
    depth = [base]

    # get coordinates sorted otherwise inc will not function properly
    lat.sort(key=float)
    lon.sort(key=float)

    # select the values within the ranges (this is to get a count only)
    latitude, longitude, depth2 = get_points_in_area(lat, lon, depth, ll, ur,
                                                     inc)

    # 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
    }

    for l, var_val in enumerate(variables):
        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

        # we want the grid to be in x, y z order (longitude, depth, latitude)
        data.sort(key=itemgetter(lat_index, lon_index))
        for i, values in enumerate(data):
            lon_val = float(lon_map[utils.float_key(values[lon_index])])
            lat_val = float(values[lat_index])
            this_value = float(values[var_index[var_val]])
            if this_value is None:
                depth_val = base
            else:
                depth_val = base + float(this_value) * float(
                    roughness) * float(unit_factor)

            if lon_val in longitude and lat_val in latitude:
                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)

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

                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(this_value) == float(params['_'.join(
                        [var_val, 'missing_value'])]):
                        continue
                V[var_val][ii, jj, kk] = float(this_value)

    return X, Y, Z, V, meta
Example #20
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
Example #21
0
def RequestData():
    # V.2019.031
    import sys
    sys.path.insert(0, r'EMC_SRC_PATH')
    import paraview.simple as simple
    import numpy as np
    import csv
    import os
    import datetime
    from vtk.util import numpy_support as nps
    import IrisEMC_Paraview_Lib as Lib
    import IrisEMC_Paraview_Utils as Utils
    import urllib.parse

    pts = vtk.vtkPoints()
    Latitude_Begin, Latitude_End, Longitude_Begin, Longitude_End = Lib.get_area(
        Area, Latitude_Begin, Latitude_End, Longitude_Begin, Longitude_End)
    label2 = " - %s (lat:%0.1f,%0.1f, lon:%0.1f,%0.1f, depth:%0.1f-%0.1f)" % (
        Lib.areaValues[Area], Latitude_Begin, Latitude_End, Longitude_Begin,
        Longitude_End, Depth_Begin, Depth_End)

    # make sure we have input files
    if not Time_End.strip():
        Time_End = datetime.datetime.today().strftime('%Y-%m-%d')
    query = Lib.earthquakeQuery % (Time_Begin, Time_End, Magnitude_Begin,
                                   Magnitude_End, Depth_Begin, Depth_End,
                                   Latitude_Begin, Latitude_End,
                                   Longitude_Begin, Longitude_End)
    Alternate_FileName = Alternate_FileName.strip()
    if len(Alternate_FileName) <= 0:
        eqFile = Lib.query2filename(query, url=Lib.earthquakeKeys[Data_Source])
        query = '?'.join([Lib.earthquakeKeys[Data_Source], query])
        fileFound, address, source = Lib.find_file(eqFile,
                                                   loc=r'EMC_EARTHQUAKES_PATH',
                                                   query=query)
    else:
        fileFound, address, source = Lib.find_file(Alternate_FileName,
                                                   loc=r'EMC_EARTHQUAKES_PATH')
    if not fileFound:
        raise Exception(
            'earthquake catalog file "' + address +
            '" not found! Please provide the full path or UR for the file. Aborting.'
        )
    (params, lines) = Lib.read_geocsv(address)

    pdo = self.GetOutput()  # vtkPoints
    column_keys = Lib.columnKeys
    for key in list(Lib.columnKeys.keys()):
        if key in list(params.keys()):
            column_keys[key] = params[key]

    origin = None
    if 'source' in params:
        origin = params['source']
        this_label = urllib.parse.urlparse(origin).netloc
    else:
        try:
            this_label = urllib.parse.urlparse(Alternate_FileName).netloc
        except:
            this_label = Alternate_FileName

    header = params['header']
    lat_index = None
    lon_index = None
    depth_index = None
    mag_index = None
    time_index = None
    for index, value in enumerate(header):
        if value.strip().lower() == column_keys['longitude_column'].lower():
            lon_index = index
        elif value.strip().lower() == column_keys['latitude_column'].lower():
            lat_index = index
        elif value.strip().lower() == column_keys['depth_column'].lower():
            depth_index = index
        elif value.strip().lower() == column_keys['magnitude_column'].lower():
            mag_index = index
        elif value.strip().lower() == column_keys['time_column'].lower():
            time_index = index

    scalar_m = vtk.vtkFloatArray()
    scalar_m.SetNumberOfComponents(1)
    scalar_m.SetName("magnitude")
    scalar_d = vtk.vtkFloatArray()
    scalar_d.SetNumberOfComponents(1)
    scalar_d.SetName("depth")
    scalar_t = vtk.vtkLongArray()
    scalar_t.SetNumberOfComponents(1)
    scalar_t.SetName("year-month")
    lat = []
    lon = []
    depth = []
    mag = []
    time = []
    frame_tag = Frame_Tag.strip()
    frame = dict()
    frame_single = dict()
    frame_key = Frame_Length_sec

    for i in range(len(lines)):
        line = lines[i].strip()
        values = line.strip().split(params['delimiter'].strip())
        lat_value = float(values[lat_index])
        lat.append(lat_value)
        lon_value = float(values[lon_index])
        lon.append(lon_value)
        depth_value = float(values[depth_index])
        depth.append(depth_value)
        mag_value = float(values[mag_index])
        mag.append(mag_value)
        time_value = values[time_index]
        time.append(time_value)

        # check conditions again in case data came from a file
        if not (float(Latitude_Begin) <= lat_value <= float(Latitude_End)
                and float(Longitude_Begin) <= lon_value <= float(Longitude_End)
                and float(Depth_Begin) <= depth_value <= float(Depth_End) and
                float(Magnitude_Begin) <= mag_value <= float(Magnitude_End)):
            continue

        if Latitude_Begin <= lat[-1] <= Latitude_End and Longitude_Begin <= lon[
                -1] <= Longitude_End:
            x, y, z = Lib.llz2xyz(lat[-1], lon[-1], depth[-1])
            pts.InsertNextPoint(x, y, z)
            scalar_m.InsertNextValue(mag[-1])
            scalar_d.InsertNextValue(depth[-1])
            day_value = Utils.datetime_to_int(time[-1], level='day')
            scalar_t.InsertNextValue(day_value)
            if frame_tag:
                frame_time = int(
                    Utils.datetime_to_float(time_value) -
                    Utils.datetime_to_float(Time_Begin))
                if frame_time < frame_key:
                    frame[str(frame_key)] = '%s\n%f,%f,%f,%0.2f,%0.1f,%d' % (
                        frame[str(frame_key)], x, y, z, depth[-1], mag[-1],
                        day_value)
                    if frame_time >= frame_key - Frame_Length_sec:
                        frame_single[str(
                            frame_key)] = '%s\n%f,%f,%f,%0.2f,%0.1f,%d' % (
                                frame_single[str(frame_key)], x, y, z,
                                depth[-1], mag[-1], day_value)
                else:
                    frame_key += Frame_Length_sec
                    frame[str(frame_key)] = '%f,%f,%f,%0.2f,%0.1f,%d' % (
                        x, y, z, depth[-1], mag[-1], day_value)
                    frame_single[str(
                        frame_key)] = '%f,%f,%f,%0.2f,%0.1f,%d' % (
                            x, y, z, depth[-1], mag[-1], day_value)

    # save animation frames
    if frame_tag:
        Utils.remove_files(
            os.path.join('EMC_EQ_ANIMATION_PATH', '%s_*.txt') % frame_tag)
        key_list = [int(x) for x in list(frame.keys())]
        key_list.sort()
        key0 = key_list[0]
        eq_list = 'X,Y,Z,Depth,Mag,Year-Month'
        for i, key in enumerate(key_list):
            eq_list = '%s\n%s' % (eq_list, frame[str(key)])
            with open(
                    os.path.join('EMC_EQ_ANIMATION_PATH',
                                 '%s_%012d.txt' % (frame_tag, key - key0)),
                    'w') as fp:
                fp.write('%s' % eq_list)
            eq = 'X,Y,Z,Depth,Mag,Year-Month\n%s' % frame_single[str(key)]
            with open(
                    os.path.join(
                        'EMC_EQ_ANIMATION_PATH',
                        '%s_single_%012d.txt' % (frame_tag, key - key0)),
                    'w') as fp:
                fp.write('%s' % eq)
    pdo.SetPoints(pts)
    pdo.GetPointData().AddArray(scalar_m)
    pdo.GetPointData().AddArray(scalar_d)
    pdo.GetPointData().AddArray(scalar_t)

    if len(this_label.strip()) > 0:
        simple.RenameSource(' '.join([
            'Earthquake locations:', 'from',
            this_label.strip(),
            label2.strip()
        ]))

    # store metadata
    field_data = pdo.GetFieldData()
    field_data.AllocateArrays(3)  # number of fields

    data = vtk.vtkFloatArray()
    data.SetName('Latitude\nRange (deg)')
    data.InsertNextValue(min(lat))
    data.InsertNextValue(max(lat))
    field_data.AddArray(data)

    data = vtk.vtkFloatArray()
    data.SetName('Longitude\nRange (deg)')
    data.InsertNextValue(min(lon))
    data.InsertNextValue(max(lon))
    field_data.AddArray(data)

    data = vtk.vtkFloatArray()
    data.SetName('Depth\nRange (km)')
    data.InsertNextValue(min(depth))
    data.InsertNextValue(max(depth))
    field_data.AddArray(data)

    data = vtk.vtkFloatArray()
    data.SetName('Magnitude\nRange')
    data.InsertNextValue(min(mag))
    data.InsertNextValue(max(mag))
    field_data.AddArray(data)

    data = vtk.vtkIntArray()
    data.SetName('Max. Event\nCount')
    data.InsertNextValue(len(mag))
    field_data.AddArray(data)

    data = vtk.vtkStringArray()
    data.SetName('Start Date')
    data.InsertNextValue(Time_Begin)
    field_data.AddArray(data)

    data = vtk.vtkStringArray()
    data.SetName('End Date')
    data.InsertNextValue(Time_End)
    field_data.AddArray(data)

    data = vtk.vtkStringArray()
    data.SetName('Source')
    if origin is not None:
        data.InsertNextValue(origin)

    data.InsertNextValue(source)
    field_data.AddArray(data)

    pdo.SetFieldData(field_data)
Example #22
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
Example #23
0
def RequestData():
    # R.1.2018.346
    import sys
    sys.path.insert(0, r'EMC_SRC_PATH')
    from paraview.simple import RenameSource, GetActiveViewOrCreate, ColorBy, GetDisplayProperties, GetActiveSource
    import numpy as np
    import csv
    import os
    from os.path import splitext
    from vtk.util import numpy_support as nps
    import IrisEMC_Paraview_Lib as lib
    import urllib.parse
    import IrisEMC_Paraview_Utils as utils
    import IrisEMC_Paraview_Param as param

    USGS = True
    if len(Alternate_FileName.strip()) > 0:
        FileName = Alternate_FileName.strip()
        Label = ' '.join(['SLAB', lib.file_name(Alternate_FileName).strip()])
        USGS = False
    else:
        FileName = lib.usgsSlabKeys[Slab]

    FileName = FileName.strip()
    ext = None
    if FileName in list(param.usgsSlabDict.keys()):
        if utils.support_nc():
            ext = param.usgsSlabExtDict['ssl']
        else:
            ext = param.usgsSlabExtDict['geo']

    depthFactor = -1

    Latitude_Begin, Latitude_End, Longitude_Begin, Longitude_End = lib.get_area(
        Area, Latitude_Begin, Latitude_End, Longitude_Begin, Longitude_End)
    Label2 = " - %s (lat:%0.1f,%0.1f, lon:%0.1f,%0.1f)" % (
        lib.areaValues[Area],
        Latitude_Begin,
        Latitude_End,
        Longitude_Begin,
        Longitude_End,
    )

    # Make sure we have input files
    fileFound, address, source = lib.find_file(FileName,
                                               loc=r'EMC_SLABS_PATH',
                                               ext=ext)
    if not fileFound:
        raise Exception('model file "' + address + '" not found! Aborting.')

    this_filename, extension = splitext(address)
    sg = self.GetOutput()  # vtkPolyData

    if extension.lower() == '.grd':
        X, Y, Z, V, label = lib.read_slab_file(
            address, (Latitude_Begin, Longitude_Begin),
            (Latitude_End, Longitude_End),
            inc=Sampling,
            depth_factor=depthFactor,
            extent=False)
    elif extension.lower() == '.csv':
        X, Y, Z, V, meta = lib.read_geocsv_model_2d(
            address, (Latitude_Begin, Longitude_Begin),
            (Latitude_End, Longitude_End),
            Sampling,
            1,
            base=0,
            unit_factor=depthFactor,
            extent=False)
        label = ''

    else:
        raise Exception('cannot recognize model file "' + address +
                        '"! Aborting.')

    nx = len(X)
    ny = len(X[0])
    nz = len(X[0][0])
    sg.SetDimensions(nx, ny, nz)

    #
    # make geometry
    #
    points = vtk.vtkPoints()
    for k in range(nz):
        for j in range(ny):
            for i in range(nx):
                points.InsertNextPoint((X[i, j, k], Y[i, j, k], Z[i, j, k]))
    sg.SetPoints(points)

    #
    # make geometry
    #
    count = 0
    for var in list(V.keys()):
        scalars = vtk.vtkFloatArray()
        scalars.SetNumberOfComponents(1)
        scalars.SetName(var)
        for k in range(nz):
            for j in range(ny):
                for i in range(nx):
                    scalars.InsertNextValue(depthFactor * V[var][i, j, k])
        if count == 0:
            sg.GetPointData().SetScalars(scalars)
        else:
            sg.GetPointData().AddArray(scalars)
        count += 1

        # store USGS metadata
    if USGS:
        fieldData = sg.GetFieldData()
        fieldData.AllocateArrays(3)  # number of fields

        data = vtk.vtkFloatArray()
        data.SetName('Latitude\nRange (deg)')
        data.InsertNextValue(
            lib.usgsSlabRangeDict[lib.usgsSlabKeys[Slab]]['Y'][0])
        data.InsertNextValue(
            lib.usgsSlabRangeDict[lib.usgsSlabKeys[Slab]]['Y'][1])
        fieldData.AddArray(data)

        data = vtk.vtkFloatArray()
        data.SetName('Longitude\nRange (deg)')
        minX = lib.usgsSlabRangeDict[lib.usgsSlabKeys[Slab]]['X'][0]
        if minX > 180:
            minX -= 360
        maxX = lib.usgsSlabRangeDict[lib.usgsSlabKeys[Slab]]['X'][1]
        if maxX > 180:
            maxX -= 360
        xMin = min([minX, maxX])
        xMax = max([minX, maxX])
        data.InsertNextValue(xMin)
        data.InsertNextValue(xMax)
        fieldData.AddArray(data)

        data = vtk.vtkFloatArray()
        data.SetName('Depth to Slab\nRange (km)')
        data.InsertNextValue(
            abs(lib.usgsSlabRangeDict[lib.usgsSlabKeys[Slab]]['Z'][1]))
        data.InsertNextValue(
            abs(lib.usgsSlabRangeDict[lib.usgsSlabKeys[Slab]]['Z'][0]))
        fieldData.AddArray(data)

        data = vtk.vtkStringArray()
        data.SetName('Source')
        data.InsertNextValue(lib.usgsSlab_URL)
        Label = ' '.join([
            'USGS Slab 1.0:', lib.usgsSlabValues[Slab].strip(), 'from',
            urllib.parse.urlparse(lib.usgsSlab_URL).netloc.strip()
        ])
        data.InsertNextValue(lib.usgsSlabKeys[Slab])
        fieldData.AddArray(data)

    RenameSource(' '.join([Label.strip(), Label2.strip()]))
Example #24
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
pathDict = {
    'EMC_MAIN_PATH': topDir,
    'EMC_PLUGINS_PATH': os.path.join(topDir, 'plugins'),
    'EMC_MACROS_PATH': os.path.join(topDir, 'macros'),
    'EMC_SRC_PATH': os.path.join(topDir, 'src'),
    'EMC_DATA_PATH': os.path.join(topDir, 'data'),
    'EMC_SCRATCH_PATH': os.path.join(topDir, 'data', 'scratch'),
    'EMC_SLABS_PATH': os.path.join(topDir, 'data', 'slabs'),
    'EMC_MODELS_PATH': os.path.join(topDir, 'data', 'models'),
    'EMC_BOUNDARIES_PATH': os.path.join(topDir, 'data', 'boundaries'),
    'EMC_VOLCANOES_PATH': os.path.join(topDir, 'data', 'volcanoes'),
    'EMC_EARTHQUAKES_PATH': os.path.join(topDir, 'data', 'earthquakes')
}

for key in pathDict.keys():
    utils.makePath(pathDict[key])

#
# default files
#
filesDict = {
    'ETOPO5': 'etopo5.nc',
    'EMC_DEFAULT_MODEL': 'wUS-SH-2010_percent.nc',
    'EMC_DEFAULT_2DMODEL': 'CAM2016Litho.nc'
}

#
# default column names for GeoCSV files. User can redefine these in the GeoCSV header
#
columnKeys = {
    'latitude_column': 'latitude',