def get_geometry(stream, coordsys='lonlat', return_center=False, verbose=False): """ Method to calculate the array geometry and the center coordinates in km :param stream: Stream object, the trace.stats dict like class must contain an :class:`~obspy.core.util.attribdict.AttribDict` with 'latitude', 'longitude' (in degrees) and 'elevation' (in km), or 'x', 'y', 'elevation' (in km) items/attributes. See param ``coordsys`` :param coordsys: valid values: 'lonlat' and 'xy', choose which stream attributes to use for coordinates :param return_center: Returns the center coordinates as extra tuple :return: Returns the geometry of the stations as 2d :class:`numpy.ndarray` The first dimension are the station indexes with the same order as the traces in the stream object. The second index are the values of [lat, lon, elev] in km last index contains center [lat, lon, elev] in degrees and km if return_center is true """ nstat = len(stream) center_lat = 0. center_lon = 0. center_h = 0. geometry = np.empty((nstat, 3)) if isinstance(stream, Stream): for i, tr in enumerate(stream): if coordsys == 'lonlat': geometry[i, 0] = tr.stats.coordinates.longitude geometry[i, 1] = tr.stats.coordinates.latitude geometry[i, 2] = tr.stats.coordinates.elevation elif coordsys == 'xy': geometry[i, 0] = tr.stats.coordinates.x geometry[i, 1] = tr.stats.coordinates.y geometry[i, 2] = tr.stats.coordinates.elevation elif isinstance(stream, np.ndarray): geometry = stream.copy() else: raise TypeError('only Stream or numpy.ndarray allowed') if verbose: print(("coordys = " + coordsys)) if coordsys == 'lonlat': center_lon = geometry[:, 0].mean() center_lat = geometry[:, 1].mean() center_h = geometry[:, 2].mean() for i in np.arange(nstat): x, y = utlGeoKm(center_lon, center_lat, geometry[i, 0], geometry[i, 1]) geometry[i, 0] = x geometry[i, 1] = y geometry[i, 2] -= center_h elif coordsys == 'xy': geometry[:, 0] -= geometry[:, 0].mean() geometry[:, 1] -= geometry[:, 1].mean() geometry[:, 2] -= geometry[:, 2].mean() else: raise ValueError("Coordsys must be one of 'lonlat', 'xy'") if return_center: return np.c_[geometry.T, np.array((center_lon, center_lat, center_h))].T else: return geometry
def get_geometry(stream, coordsys='lonlat', return_center=False, verbose=False): """ Method to calculate the array geometry and the center coordinates in km :param stream: Stream object, the trace.stats dict like class must contain an :class:`~obspy.core.util.attribdict.AttribDict` with 'latitude', 'longitude' (in degrees) and 'elevation' (in km), or 'x', 'y', 'elevation' (in km) items/attributes. See param ``coordsys`` :param coordsys: valid values: 'lonlat' and 'xy', choose which stream attributes to use for coordinates :param return_center: Returns the center coordinates as extra tuple :return: Returns the geometry of the stations as 2d :class:`numpy.ndarray` The first dimension are the station indexes with the same order as the traces in the stream object. The second index are the values of [lat, lon, elev] in km last index contains center [lat, lon, elev] in degrees and km if return_center is true """ nstat = len(stream) center_lat = 0. center_lon = 0. center_h = 0. geometry = np.empty((nstat, 3)) if isinstance(stream, Stream): for i, tr in enumerate(stream): if coordsys == 'lonlat': geometry[i, 0] = tr.stats.coordinates.longitude geometry[i, 1] = tr.stats.coordinates.latitude geometry[i, 2] = tr.stats.coordinates.elevation elif coordsys == 'xy': geometry[i, 0] = tr.stats.coordinates.x geometry[i, 1] = tr.stats.coordinates.y geometry[i, 2] = tr.stats.coordinates.elevation elif isinstance(stream, np.ndarray): geometry = stream.copy() else: raise TypeError('only Stream or numpy.ndarray allowed') if verbose: print("coordsys = " + coordsys) if coordsys == 'lonlat': center_lon = geometry[:, 0].mean() center_lat = geometry[:, 1].mean() center_h = geometry[:, 2].mean() for i in np.arange(nstat): x, y = utlGeoKm(center_lon, center_lat, geometry[i, 0], geometry[i, 1]) geometry[i, 0] = x geometry[i, 1] = y geometry[i, 2] -= center_h elif coordsys == 'xy': geometry[:, 0] -= geometry[:, 0].mean() geometry[:, 1] -= geometry[:, 1].mean() geometry[:, 2] -= geometry[:, 2].mean() else: raise ValueError("Coordsys must be one of 'lonlat', 'xy'") if return_center: return np.c_[geometry.T, np.array((center_lon, center_lat, center_h))].T else: return geometry
def plotarray(stcoord, inunits='m', plotunits='km', sourcecoords=None, stalabels=None): """ stcoord = stream or coords extracted in format from extract_coords sourcecoords = lat,lon or x,y (should be in same units as stcoord) inunits 'm' 'km' or 'deg' """ coords = [] tempcoords = [] if type(stcoord) is Stream: if stalabels is None: stalabels = [] for trace in stcoord: if inunits == 'deg': tempcoords.append( np.array([ trace.stats.coordinates.longitude, trace.stats.coordinates.latitude, trace.stats.coordinates.elevation ])) stalabels.append(trace.stats.station) else: tempcoords.append( np.array([ trace.stats.coordinates.x, trace.stats.coordinates.y, trace.stats.coordinates.elevation ])) stalabels.append(trace.stats.station) else: tempcoords = stcoord tempcoords = np.array(tempcoords) if inunits == 'deg': lons = np.array([coord[0] for coord in tempcoords]) lats = np.array([coord[1] for coord in tempcoords]) for coord in tempcoords: x, y = utlGeoKm(lons.min(), lats.min(), coord[0], coord[1]) coords.append(np.array([x, y, coord[2]])) if plotunits == 'm': coords = np.array(coords) * 1000. else: coords = np.array(coords) if sourcecoords is not None: sx, sy = utlGeoKm(lons.min(), lats.min(), sourcecoords[0], sourcecoords[1]) elif inunits == 'm' and plotunits == 'km': coords = np.array(tempcoords) / 1000. if sourcecoords is not None: sx, sy = sourcecoords / 1000. elif inunits == 'km' and plotunits == 'm': coords = np.array(tempcoords) * 1000. if sourcecoords is not None: sx, sy = sourcecoords * 1000. else: coords = np.array(tempcoords) if sourcecoords is not None: sx, sy = sourcecoords fig = plt.figure() ax = fig.add_subplot(111) ax.plot([coord[0] for coord in coords], [coord[1] for coord in coords], 'o') if stalabels is not None: for coord, sta in zip(coords, stalabels): ax.text(coord[0], coord[1], sta, fontsize=8) if sourcecoords is not None: ax.plot(sx, sy, '*k', markersize=20) xcenter = np.array([coord[0] for coord in coords]).mean() ycenter = np.array([coord[1] for coord in coords]).mean() az = 180 * math.atan2((xcenter - sx), (ycenter - sy)) / math.pi baz = az % -360 + 180 if baz < 0.0: baz += 360 ax.set_title('Backazimuth %0.0f degrees' % baz) else: sx = None sy = None baz = None az = None plt.axis('equal') ax.set_xlabel('x distance (%s)' % plotunits) ax.set_ylabel('y distance (%s)' % plotunits) plt.show() # ADD AZIMUTH TO CENTER OF ARRAY return coords, sx, sy, baz, az
def plotarray(stcoord, inunits='m', plotunits='km', sourcecoords=None, stalabels=None): """ stcoord = stream or coords extracted in format from extract_coords sourcecoords = lat,lon or x,y (should be in same units as stcoord) inunits 'm' 'km' or 'deg' """ coords = [] tempcoords = [] if type(stcoord) is Stream: if stalabels is None: stalabels = [] for trace in stcoord: if inunits == 'deg': tempcoords.append(np.array([trace.stats.coordinates.longitude, trace.stats.coordinates.latitude, trace.stats.coordinates.elevation])) stalabels.append(trace.stats.station) else: tempcoords.append(np.array([trace.stats.coordinates.x, trace.stats.coordinates.y, trace.stats.coordinates.elevation])) stalabels.append(trace.stats.station) else: tempcoords = stcoord tempcoords = np.array(tempcoords) if inunits == 'deg': lons = np.array([coord[0] for coord in tempcoords]) lats = np.array([coord[1] for coord in tempcoords]) for coord in tempcoords: x, y = utlGeoKm(lons.min(), lats.min(), coord[0], coord[1]) coords.append(np.array([x, y, coord[2]])) if plotunits == 'm': coords = np.array(coords)*1000. else: coords = np.array(coords) if sourcecoords is not None: sx, sy = utlGeoKm(lons.min(), lats.min(), sourcecoords[0], sourcecoords[1]) elif inunits == 'm' and plotunits == 'km': coords = np.array(tempcoords)/1000. if sourcecoords is not None: sx, sy = sourcecoords/1000. elif inunits == 'km' and plotunits == 'm': coords = np.array(tempcoords)*1000. if sourcecoords is not None: sx, sy = sourcecoords*1000. else: coords = np.array(tempcoords) if sourcecoords is not None: sx, sy = sourcecoords fig = plt.figure() ax = fig.add_subplot(111) ax.plot([coord[0] for coord in coords], [coord[1] for coord in coords], 'o') if stalabels is not None: for coord, sta in zip(coords, stalabels): ax.text(coord[0], coord[1], sta, fontsize=8) if sourcecoords is not None: ax.plot(sx, sy, '*k', markersize=20) xcenter = np.array([coord[0] for coord in coords]).mean() ycenter = np.array([coord[1] for coord in coords]).mean() az = 180 * math.atan2((xcenter-sx), (ycenter-sy)) / math.pi baz = az % -360 + 180 if baz < 0.0: baz += 360 ax.set_title('Backazimuth %0.0f degrees' % baz) else: sx = None sy = None baz = None az = None plt.axis('equal') ax.set_xlabel('x distance (%s)' % plotunits) ax.set_ylabel('y distance (%s)' % plotunits) plt.show() # ADD AZIMUTH TO CENTER OF ARRAY return coords, sx, sy, baz, az
def utlGeoKm2(orig_lon, orig_lat, lon, lat): return utlGeoKm(orig_lon, orig_lat, lon, lat)