def clip_modem_model(model_fn, clip):
    """
    Read in ModEM model and clip to a smaller box
    """
    m_obj = modem.Model()
    m_obj.read_model_file(model_fn)

    ### --> need to convert model coordinates into lat and lon
    utm_center = gis_tools.project_point_ll2utm(model_center[1],
                                                model_center[0])

    lat = np.zeros_like(m_obj.grid_north[clip:-(clip + 1)])
    lon = np.zeros_like(m_obj.grid_east[clip:-(clip + 1)])
    depth = m_obj.grid_z[:-1] / 1000.0

    for ii, north in enumerate(m_obj.grid_north[clip:-(clip + 1)]):
        m_lat, m_lon = gis_tools.project_point_utm2ll(utm_center[0],
                                                      utm_center[1] + north,
                                                      utm_center[2])
        lat[ii] = m_lat

    for ii, east in enumerate(m_obj.grid_east[clip:-(clip + 1)]):
        m_lat, m_lon = gis_tools.project_point_utm2ll(utm_center[0] + east,
                                                      utm_center[1],
                                                      utm_center[2])
        lon[ii] = m_lon

    res = np.log10(m_obj.res_model[clip:-clip, clip:-clip, :])

    return lat, lon, depth, res
示例#2
0
    def test_project_point_utm2ll(self):
        new_lat, new_lon = project_point_utm2ll(self.easting, self.northing, self.zone)

        print(new_lat, new_lon)

        self.assertTrue(np.isclose(self.lat, new_lat))
        self.assertTrue(np.isclose(self.lon, new_lon))

        # testing with epsg
        new_lat, new_lon = project_point_utm2ll(self.easting, self.northing, utm_zone=self.zone, epsg=self.to_epsg)

        print(new_lat, new_lon)

        self.assertTrue(np.isclose(self.lat, new_lat))
        self.assertTrue(np.isclose(self.lon, new_lon))
示例#3
0
文件: station.py 项目: zy911k24/mtpy
    def center_point(self):
        """
        calculate the center point from the given station locations

        Returns
        -------------
            **center_location** : np.ndarray
                                  structured array of length 1
                                  dtype includes (east, north, zone, lat, lon)
        """
        dtype = [('lat', np.float), ('lon', np.float), ('east', np.float),
                 ('north', np.float), ('elev', np.float), ('zone', 'S4')]
        center_location = np.recarray(1, dtype=dtype)
        #        AK - using the mean here but in get_relative_locations used (max + min)/2, why???

        #        center_point = np.array([self.east.mean(), self.north.mean()])
        #
        #        #translate the stations so they are relative to 0,0
        #        east_center = (self.rel_east.max()-np.abs(self.rel_east.min()))/2
        #        north_center = (self.rel_north.max()-np.abs(self.rel_north.min()))/2
        #
        #        center_point[0] -= east_center
        #        center_point[1] -= north_center
        #
        #        # calculate center point in lat, lon, easting, northing
        #        center_location['east'] = center_point[0]
        #        center_location['north'] = center_point[1]
        center_point = np.array([
            self.east.max() + self.east.min(),
            self.north.max() + self.north.min()
        ]) / 2.
        center_location['east'] = center_point[0]
        center_location['north'] = center_point[1]

        center_location['zone'] = self.utm_zone[0]

        center_ll = gis_tools.project_point_utm2ll(float(center_point[0]),
                                                   float(center_point[1]),
                                                   self.utm_zone[0],
                                                   epsg=self.model_epsg)

        center_location['lat'] = center_ll[0]
        center_location['lon'] = center_ll[1]
        # BM: Because we are now writing center_point.elev to ModEm
        #  data file, we need to provide it.
        #  The center point elevation is the highest point of the
        #  model. Before topography is applied, this is the highest
        #  station. After it's applied, it's the highest point
        #  point of the surface model (this will be set by calling
        #  Data.project_stations_on_topography).
        center_location['elev'] = self.elev.max()

        return center_location
示例#4
0
文件: station.py 项目: qdhqf/mtpy-1
    def center_point(self):
        """
        calculate the center point from the given station locations

        Returns
        -------------
            **center_location** : np.ndarray
                                  structured array of length 1
                                  dtype includes (east, north, zone, lat, lon)
        """
        center_location = np.recarray(1, dtype=self.dtype)
        #        AK - using the mean here but in get_relative_locations used (max + min)/2, why???

        #        center_point = np.array([self.east.mean(), self.north.mean()])
        #
        #        #translate the stations so they are relative to 0,0
        #        east_center = (self.rel_east.max()-np.abs(self.rel_east.min()))/2
        #        north_center = (self.rel_north.max()-np.abs(self.rel_north.min()))/2
        #
        #        center_point[0] -= east_center
        #        center_point[1] -= north_center
        #
        #        # calculate center point in lat, lon, easting, northing
        #        center_location['east'] = center_point[0]
        #        center_location['north'] = center_point[1]

        center_point = np.array([
            self.east.max() + self.east.min(),
            self.north.max() + self.north.min()
        ]) / 2.
        center_location['east'] = center_point[0]
        center_location['north'] = center_point[1]

        center_location['zone'] = self.utm_zone[0]

        center_ll = gis_tools.project_point_utm2ll(float(center_point[0]),
                                                   float(center_point[1]),
                                                   self.utm_zone[0],
                                                   epsg=self.model_epsg)

        center_location['lat'] = center_ll[0]
        center_location['lon'] = center_ll[1]

        return center_location
示例#5
0
文件: mare2dem.py 项目: zy911k24/mtpy
def get_profile_specs(o2d_data, site_easts, site_norths):
    """
    Get specifications for the MARE2D profile line from Occam2D profile.

    Parameters
    ----------
    m2d_profile : mtpy.modeling.occam2d.Data
        Occam2D data object that has been initialised with EDI data.
    site_easts : np.ndarray
        1D array of floats of length n. Easting coordinates for the
        station locations.
    site_norths : np.ndarray
        1D array of floats of length n. Northing coordinates for the
        station locations.

    Returns
    -------
    tuple(float, ..., int, str)
        x0, y0: start of profile line.
        x1, y1: end of profile line.
        mare_origin_x, mare_origin_y: Origin of the Mare2D profile,
            which is the middle of the line.
        epsg: epsg code of the profile origin
        utm_zone: utm code of the profile origin (of form e.g. '54K S')
    """
    m, c1 = o2d_data.profile_line
    # Find start of profile
    # Assume that the start of the profile always has minimum eastings
    x0 = site_easts.min()
    y0 = m * x0 + c1
    # Find end of the profile
    # Assume y1 as the maximum northing
    x1 = site_easts.max()
    y1 = m * x1 + c1
    # Mare2D origin (middle of profile line)
    mare_origin_x = (site_easts.min() + site_easts.max()) / 2
    mare_origin_y = (site_norths.min() + site_norths.max()) / 2
    # UTM zone of Mare2D profile
    epsg = o2d_data.model_epsg
    projected_origin = gis_tools.project_point_utm2ll(mare_origin_x, mare_origin_y,
                                                      None, epsg=epsg)
    utm_zone = gis_tools.get_utm_zone(projected_origin[0], projected_origin[1])[2]
    return (x0, y0, x1, y1, mare_origin_x, mare_origin_y, epsg, utm_zone)
示例#6
0
文件: array2raster.py 项目: DSO89/DSO
    def get_model_lower_left_coord(self,
                                   model_fn=None,
                                   model_center=None,
                                   pad_east=0,
                                   pad_north=0):
        """
        Find the models lower left hand corner in (lon, lat) decimal degrees
        """
        if model_fn is not None:
            self.model_fn = model_fn

        if self.model_fn is None:
            raise IOError('Need to input a ModEM model file name to read in')

        self.pad_east = pad_east
        self.pad_north = pad_north

        model_obj = modem.Model()
        model_obj.model_fn = self.model_fn
        model_obj.read_model_file()

        if model_center:
            center_zone, center_east, center_north = gis_tools.project_point_ll2utm(
                model_center[1], model_center[0])


            lower_left_east = center_east+model_obj.grid_center[1]+\
                                model_obj.nodes_east[0:pad_east].sum()-\
                                model_obj.nodes_east[pad_east]/2
            lower_left_north = center_north+model_obj.grid_center[1]+\
                                model_obj.nodes_north[0:pad_north].sum()+\
                                model_obj.nodes_north[pad_north]/2

            ll_lat, ll_lon = gis_tools.project_point_utm2ll(
                lower_left_north, lower_left_east, center_zone)

            print 'Lower Left Coordinates should be ({0:.5f}, {1:.5f})'.format(
                ll_lon, ll_lat)
            return (ll_lon, ll_lat)
        else:
            raise IOError('Need to input model center (lon, lat)')
model_center = (45.654713, -118.547148)
model_center_ne = gis_tools.project_point_ll2utm(
    model_center[0], model_center[1], epsg=26911
)

m_obj = modem.Model()
m_obj.read_model_file(mfn)

# need to make a lat and lon list
lat = np.zeros(m_obj.nodes_north.size)
lon = np.zeros(m_obj.nodes_east.size)

for ii, north in enumerate(model_center_ne[0] - m_obj.grid_north[:-1]):
    lat_00, lon_00 = gis_tools.project_point_utm2ll(
        north, model_center_ne[1], model_center_ne[2]
    )
    lat[ii] = lat_00

for ii, east in enumerate(model_center_ne[1] - m_obj.grid_east[:-1]):
    lat_00, lon_00 = gis_tools.project_point_utm2ll(
        model_center_ne[0], east, model_center_ne[2]
    )
    lon[ii] = lon_00

# nc_obj = netCDF4.Dataset(m_obj.model_fn[:-4]+'.nc', 'w', format='NETCDF4')
nc_obj = netCDF4.Dataset(
    r"c:\Users\jpeacock\OneDrive - DOI\Geothermal\Umatilla\modem_inv\inv_09\um_z05_c025_086.nc",
    "w",
    format="NETCDF4",
)
                         dtype=dtypes)
    except pd._libs.parsers.ParserError:
        df = pd.read_csv(txt_fn,
                         skiprows=1,
                         delimiter=r"\s+",
                         usecols=(0, 1, 2, 3, 4),
                         names=cols,
                         dtype=dtypes)

    for col in cols:
        df_dict[col] += df[col].to_list()

geometry = []
stations = {'ID': [], 'elev': [], 'lat': [], 'lon': []}

for index in range(len(df_dict['station'])):
    lon, lat = gis_tools.project_point_utm2ll(df_dict['easting'][index],
                                              df_dict['northing'][index],
                                              df_dict['zone'][index],
                                              datum='NAD83')
    geometry.append(Point(lon, lat))
    stations['ID'].append(df_dict['station'][index])
    stations['elev'].append(df_dict['elevation'][index])
    stations['lat'].append(lat)
    stations['lon'].append(lon)

gdf = gpd.GeoDataFrame(stations, crs=crs, geometry=geometry)
gdf.to_file(r"c:\Users\jpeacock\OneDrive - DOI\EDI_FILES\wannamaker.kml",
            driver='kml')
gdf.to_file(r"c:\Users\jpeacock\OneDrive - DOI\EDI_FILES\wannamaker.shp",
            driver='ESRI Shapefile')
示例#9
0
spacing_east = 1000.
spacing_north = 1000.

east_arr = np.arange(ll_utm['easting_min'],
                     ll_utm['easting_max'] + spacing_east, spacing_east)

north_arr = np.arange(ll_utm['northing_min'],
                      ll_utm['northing_max'] + spacing_east, spacing_east)

kml_fn = r"c:\Users\jpeacock\Documents\Geothermal\Umatilla\um_phase_02_mt_stations_{0:.0f}m.kml".format(
    spacing_east)

kml_obj = skml.Kml()
count = 200
for ii, east in enumerate(east_arr):
    print '-' * 30
    for jj, north in enumerate(north_arr):
        print east, north

        lat_ii, lon_jj = gis_tools.project_point_utm2ll(
            east, north, ll_utm['zone'])

        kml_obj.newpoint(name='um{0:03}'.format(count),
                         coords=[(lon_jj, lat_ii)])

        count += 1

kml_obj.save(kml_fn)

print 'Number of stations: {0}'.format(count + 1)
data_epsg = 26911
model_center = (35.488658, -115.494148)

dfn = r"c:\Users\jpeacock\Documents\MountainPass\modem_inv\inv_07\mp_modem_data_z03_topo_edit.dat"

if dfn is not None:
    d_obj = modem.Data()
    d_obj.read_data_file(dfn)

# =============================================================================
# Load in file
# =============================================================================
a = np.loadtxt(fn, skiprows=3, dtype=np.float, delimiter=None).T

### compute the lower left hand corner of the raster
lower_left = gis_tools.project_point_utm2ll(a[1].min(), a[0].min(), utm_zone)
lower_left = (a[1].min(), a[0].min())

east, north, zone = gis_tools.project_points_ll2utm(a[1], a[0], datum='NAD27')

### make equally spaced points on regular grid
x_new = np.linspace(east.min(), east.max(), num=(east.max() - east.min()) / d)
y_new = np.linspace(north.min(),
                    north.max(),
                    num=(north.max() - north.min()) / d)

xg, yg = np.meshgrid(x_new, y_new)

### interpolate the data onto a regular grid
basement = interpolate.griddata((east, north),
                                -1 * a[2], (xg, yg),
# =============================================================================
# Read in model file
# =============================================================================
m_obj = modem.Model()
m_obj.read_model_file(model_fn)

### --> need to convert model coordinates into lat and lon
utm_center = gis_tools.project_point_ll2utm(model_center[1], model_center[0])

lat = np.zeros_like(m_obj.grid_north[clip:-(clip + 1)])
lon = np.zeros_like(m_obj.grid_east[clip:-(clip + 1)])
depth = m_obj.grid_z[:-1] / 1000.

for ii, north in enumerate(m_obj.grid_north[clip:-(clip + 1)]):
    m_lat, m_lon = gis_tools.project_point_utm2ll(utm_center[0],
                                                  utm_center[1] + north,
                                                  utm_center[2])
    lat[ii] = m_lat

for ii, east in enumerate(m_obj.grid_east[clip:-(clip + 1)]):
    m_lat, m_lon = gis_tools.project_point_utm2ll(utm_center[0] + east,
                                                  utm_center[1], utm_center[2])
    lon[ii] = m_lon
# =============================================================================
# Create NetCDF4 dataset compliant with IRIS format
# =============================================================================
dataset = netcdf.Dataset(save_fn, 'w', format='NETCDF4')
dataset.title = "Electrical Resistivity Model"
dataset.id = "iMUSH_MT_2018"
dataset.summary = "Crustal resistivity model of Mount St. Helens and surrounding \n"+\
                  "area estimated from magnetotelluric data part of the iMUSH project. \n"+\
示例#12
0
def interpolate_elevation_to_grid(grid_east,
                                  grid_north,
                                  epsg=None,
                                  utm_zone=None,
                                  surfacefile=None,
                                  surface=None,
                                  method='linear',
                                  fast=True):
    """
    project a surface to the model grid and add resulting elevation data
    to a dictionary called surface_dict. Assumes the surface is in lat/long
    coordinates (wgs84)
    The 'fast' method extracts a subset of the elevation data that falls within the
    mesh-bounds and interpolates them onto mesh nodes. This approach significantly
    speeds up (~ x5) the interpolation procedure.

    **returns**
    nothing returned, but surface data are added to surface_dict under
    the key given by surfacename.

    **inputs**
    choose to provide either surface_file (path to file) or surface (tuple).
    If both are provided then surface tuple takes priority.

    surface elevations are positive up, and relative to sea level.
    surface file format is:

    ncols         3601
    nrows         3601
    xllcorner     -119.00013888889 (longitude of lower left)
    yllcorner     36.999861111111  (latitude of lower left)
    cellsize      0.00027777777777778
    NODATA_value  -9999
    elevation data W --> E
    N
    |
    V
    S

    Alternatively, provide a tuple with:
    (lon,lat,elevation)
    where elevation is a 2D array (shape (ny,nx)) containing elevation
    points (order S -> N, W -> E)
    and lon, lat are either 1D arrays containing list of longitudes and
    latitudes (in the case of a regular grid) or 2D arrays with same shape
    as elevation array containing longitude and latitude of each point.

    other inputs:
    surfacename = name of surface for putting into dictionary
    surface_epsg = epsg number of input surface, default is 4326 for lat/lon(wgs84)
    method = interpolation method. Default is 'nearest', if model grid is
    dense compared to surface points then choose 'linear' or 'cubic'

    """

    # read the surface data in from ascii if surface not provided
    if surface is None:
        surface = mtfh.read_surface_ascii(surfacefile)

    x, y, elev = surface

    # if lat/lon provided as a 1D list, convert to a 2d grid of points
    if len(x.shape) == 1:
        x, y = np.meshgrid(x, y)

    if len(grid_east.shape) == 1:
        grid_east, grid_north = np.meshgrid(grid_east, grid_north)

    if (fast):
        buffer = 1  # use a buffer of 1 degree around mesh-bounds
        mlatmin, mlonmin = gis_tools.project_point_utm2ll(grid_east.min(),
                                                          grid_north.min(),
                                                          epsg=epsg,
                                                          utm_zone=utm_zone)

        mlatmax, mlonmax = gis_tools.project_point_utm2ll(grid_east.max(),
                                                          grid_north.max(),
                                                          epsg=epsg,
                                                          utm_zone=utm_zone)

        subsetIndices = (x >= mlonmin-buffer) & \
                        (x <= mlonmax+buffer) & \
                        (y >= mlatmin-buffer) & \
                        (y <= mlatmax+buffer)
        x = x[subsetIndices]
        y = y[subsetIndices]
        elev = elev[subsetIndices]
    # end if

    xs, ys, utm_zone = gis_tools.project_points_ll2utm(y,
                                                       x,
                                                       epsg=epsg,
                                                       utm_zone=utm_zone)

    # elevation in model grid
    # first, get lat,lon points of surface grid
    points = np.vstack([arr.flatten() for arr in [xs, ys]]).T
    # corresponding surface elevation points
    values = elev.flatten()
    # xi, the model grid points to interpolate to
    xi = np.vstack([arr.flatten() for arr in [grid_east, grid_north]]).T
    # elevation on the centre of the grid nodes
    elev_mg = spi.griddata(points, values, xi,
                           method=method).reshape(grid_north.shape)

    return elev_mg
示例#13
0
def interpolate_elevation_to_grid(grid_east,
                                  grid_north,
                                  epsg=None,
                                  utm_zone=None,
                                  surfacefile=None,
                                  surface=None,
                                  method='linear',
                                  fast=True):
    """
    # Note: this documentation is outdated and seems to be copied from
    #  model.interpolate_elevation2. It needs to be updated. This
    #  funciton does not update a dictionary but returns an array of
    #  elevation data.

    project a surface to the model grid and add resulting elevation data
    to a dictionary called surface_dict. Assumes the surface is in lat/long
    coordinates (wgs84)
    The 'fast' method extracts a subset of the elevation data that falls within the
    mesh-bounds and interpolates them onto mesh nodes. This approach significantly
    speeds up (~ x5) the interpolation procedure.

    **returns**
    nothing returned, but surface data are added to surface_dict under
    the key given by surfacename.

    **inputs**
    choose to provide either surface_file (path to file) or surface (tuple).
    If both are provided then surface tuple takes priority.

    surface elevations are positive up, and relative to sea level.
    surface file format is:

    ncols         3601
    nrows         3601
    xllcorner     -119.00013888889 (longitude of lower left)
    yllcorner     36.999861111111  (latitude of lower left)
    cellsize      0.00027777777777778
    NODATA_value  -9999
    elevation data W --> E
    N
    |
    V
    S

    Alternatively, provide a tuple with:
    (lon,lat,elevation)
    where elevation is a 2D array (shape (ny,nx)) containing elevation
    points (order S -> N, W -> E)
    and lon, lat are either 1D arrays containing list of longitudes and
    latitudes (in the case of a regular grid) or 2D arrays with same shape
    as elevation array containing longitude and latitude of each point.

    other inputs:
    surfacename = name of surface for putting into dictionary
    surface_epsg = epsg number of input surface, default is 4326 for lat/lon(wgs84)
    method = interpolation method. Default is 'nearest', if model grid is
    dense compared to surface points then choose 'linear' or 'cubic'
    """
    # read the surface data in from ascii if surface not provided
    if surfacefile:
        lon, lat, elev = mtfh.read_surface_ascii(surfacefile)
    elif surface:
        lon, lat, elev = surface
    else:
        raise ValueError("'surfacefile' or 'surface' must be provided")

    # if lat/lon provided as a 1D list, convert to a 2d grid of points
    if len(lon.shape) == 1:
        # BM: There seems to be an issue using dense grids (X and Y
        #  become arrays of (N, N)), and get flattened to 1D array
        #  of N^2 in point projection below.
        #  Interpolation then can't be performed because
        #  there's a dimension mismatch between lon/lat and elev.
        #  This issue doesn't happen when using 'fast' method below, so
        #  when not using fast, get a sparse grid instead.
        if fast:
            lon, lat = np.meshgrid(lon, lat)
        else:
            lon, lat = np.meshgrid(lon, lat, sparse=True)
            lat = lat.T

    if len(grid_east.shape) == 1:
        grid_east, grid_north = np.meshgrid(grid_east, grid_north)

    if (fast):
        buffer = 1  # use a buffer of 1 degree around mesh-bounds
        mlatmin, mlonmin = gis_tools.project_point_utm2ll(grid_east.min(),
                                                          grid_north.min(),
                                                          epsg=epsg,
                                                          utm_zone=utm_zone)

        mlatmax, mlonmax = gis_tools.project_point_utm2ll(grid_east.max(),
                                                          grid_north.max(),
                                                          epsg=epsg,
                                                          utm_zone=utm_zone)
        subsetIndices = (lon >= mlonmin - buffer) & \
                        (lon <= mlonmax + buffer) & \
                        (lat >= mlatmin - buffer) & \
                        (lat <= mlatmax + buffer)
        lon = lon[subsetIndices]
        lat = lat[subsetIndices]
        elev = elev[subsetIndices]

    # end if
    projected_points = gis_tools.project_point_ll2utm(lat,
                                                      lon,
                                                      epsg=epsg,
                                                      utm_zone=utm_zone)
    # elevation in model grid
    # first, get lat,lon points of surface grid
    points = np.vstack([
        arr.flatten()
        for arr in [projected_points.easting, projected_points.northing]
    ]).T
    # corresponding surface elevation points
    values = elev.flatten()
    # xi, the model grid points to interpolate to
    xi = np.vstack([arr.flatten() for arr in [grid_east, grid_north]]).T
    # elevation on the centre of the grid nodes
    elev_mg = spi.griddata(points, values, xi,
                           method=method).reshape(grid_north.shape)

    return elev_mg
示例#14
0
            delimiter=r"\s+",
            usecols=(0, 1, 2, 3, 4),
            names=cols,
            dtype=dtypes,
        )

    for col in cols:
        df_dict[col] += df[col].to_list()

geometry = []
stations = {"ID": [], "elev": [], "lat": [], "lon": []}

for index in range(len(df_dict["station"])):
    lon, lat = gis_tools.project_point_utm2ll(
        df_dict["easting"][index],
        df_dict["northing"][index],
        df_dict["zone"][index],
        datum="NAD83",
    )
    geometry.append(Point(lon, lat))
    stations["ID"].append(df_dict["station"][index])
    stations["elev"].append(df_dict["elevation"][index])
    stations["lat"].append(lat)
    stations["lon"].append(lon)

gdf = gpd.GeoDataFrame(stations, crs=crs, geometry=geometry)
gdf.to_file(r"c:\Users\jpeacock\OneDrive - DOI\EDI_FILES\wannamaker.kml",
            driver="kml")
gdf.to_file(
    r"c:\Users\jpeacock\OneDrive - DOI\EDI_FILES\wannamaker.shp",
    driver="ESRI Shapefile",
)