Example #1
0
def add_geo_to_arrivals(arrivals, source_latitude_in_deg,
                        source_longitude_in_deg, receiver_latitude_in_deg,
                        receiver_longitude_in_deg, radius_of_earth_in_km,
                        flattening_of_earth):
    """
    Add geographical information to arrivals.

    :param arrivals: Set of taup arrivals
    :type: :class:`Arrivals`
    :param source_latitude_in_deg: Source location latitude in degrees
    :type source_latitude_in_deg: float
    :param source_longitude_in_deg: Source location longitude in degrees
    :type source_longitude_in_deg: float
    :param receiver_latitude_in_deg: Receiver location latitude in degrees
    :type receiver_latitude_in_deg: float
    :param receiver_longitude_in_deg: Receiver location longitude in degrees
    :type receiver_longitude_in_deg: float
    :param radius_of_earth_in_km: Radius of the Earth in km
    :type radius_of_earth_in_km: float
    :param flattening_of_earth: Flattening of Earth (0 for a sphere)
    :type receiver_longitude_in_deg: float

    :return: List of ``Arrival`` objects, each of which has the time,
        corresponding phase name, ray parameter, takeoff angle, etc. as
        attributes.
    :rtype: :class:`Arrivals`
    """
    if geodetics.HAS_GEOGRAPHICLIB:
        ellipsoid = Geodesic(a=radius_of_earth_in_km * 1000.0,
                             f=flattening_of_earth)
        g = ellipsoid.Inverse(source_latitude_in_deg, source_longitude_in_deg,
                              receiver_latitude_in_deg,
                              receiver_longitude_in_deg)
        azimuth = g['azi1']
        line = ellipsoid.Line(source_latitude_in_deg, source_longitude_in_deg,
                              azimuth)

        # We may need to update many arrival objects
        # and each could have pierce points and a
        # path
        for arrival in arrivals:

            if arrival.pierce is not None:
                geo_pierce = np.empty(arrival.pierce.shape, dtype=TimeDistGeo)
                for i, pierce_point in enumerate(arrival.pierce):
                    pos = line.ArcPosition(np.degrees(pierce_point['dist']))
                    geo_pierce[i] = (pierce_point['p'], pierce_point['time'],
                                     pierce_point['dist'],
                                     pierce_point['depth'],
                                     pos['lat2'], pos['lon2'])
                arrival.pierce = geo_pierce

            if arrival.path is not None:
                geo_path = np.empty(arrival.path.shape, dtype=TimeDistGeo)
                for i, path_point in enumerate(arrival.path):
                    pos = line.ArcPosition(np.degrees(path_point['dist']))
                    geo_path[i] = (path_point['p'], path_point['time'],
                                   path_point['dist'], path_point['depth'],
                                   pos['lat2'], pos['lon2'])
                arrival.path = geo_path

    else:
        # geographiclib is not installed ...
        # and  obspy/geodetics does not help much
        msg = "You need to install the Python module 'geographiclib' in " + \
              "order to add geographical information to arrivals."
        raise ImportError(msg)

    return arrivals
Example #2
0
def add_geo_to_arrivals(arrivals, source_latitude_in_deg,
                        source_longitude_in_deg, receiver_latitude_in_deg,
                        receiver_longitude_in_deg, radius_of_planet_in_km,
                        flattening_of_planet):
    """
    Add geographical information to arrivals.

    :param arrivals: Set of taup arrivals
    :type: :class:`Arrivals`
    :param source_latitude_in_deg: Source location latitude in degrees
    :type source_latitude_in_deg: float
    :param source_longitude_in_deg: Source location longitude in degrees
    :type source_longitude_in_deg: float
    :param receiver_latitude_in_deg: Receiver location latitude in degrees
    :type receiver_latitude_in_deg: float
    :param receiver_longitude_in_deg: Receiver location longitude in degrees
    :type receiver_longitude_in_deg: float
    :param radius_of_planet_in_km: Radius of the planet in km
    :type radius_of_planet_in_km: float
    :param flattening_of_planet: Flattening of planet (0 for a sphere)
    :type receiver_longitude_in_deg: float

    :return: List of ``Arrival`` objects, each of which has the time,
        corresponding phase name, ray parameter, takeoff angle, etc. as
        attributes.
    :rtype: :class:`Arrivals`
    """
    if geodetics.HAS_GEOGRAPHICLIB:
        if not geodetics.GEOGRAPHICLIB_VERSION_AT_LEAST_1_34:
            # geographiclib is not installed ...
            # and  obspy/geodetics does not help much
            msg = ("This functionality needs the Python module "
                   "'geographiclib' in version 1.34 or higher.")
            raise ImportError(msg)
        ellipsoid = Geodesic(a=radius_of_planet_in_km * 1000.0,
                             f=flattening_of_planet)
        g = ellipsoid.Inverse(source_latitude_in_deg, source_longitude_in_deg,
                              receiver_latitude_in_deg,
                              receiver_longitude_in_deg)
        azimuth = g['azi1']
        line = ellipsoid.Line(source_latitude_in_deg, source_longitude_in_deg,
                              azimuth)

        # We may need to update many arrival objects
        # and each could have pierce points and a
        # path
        for arrival in arrivals:
            # check if we go in minor or major arc direction
            distance = arrival.purist_distance % 360.
            if distance > 180.:
                sign = -1
                az_arr = (azimuth + 180.) % 360.
            else:
                sign = 1
                az_arr = azimuth
            arrival.azimuth = az_arr

            if arrival.pierce is not None:
                geo_pierce = np.empty(arrival.pierce.shape, dtype=TimeDistGeo)

                for i, pierce_point in enumerate(arrival.pierce):
                    dir_degrees = np.degrees(sign * pierce_point['dist'])
                    pos = line.ArcPosition(dir_degrees)
                    geo_pierce[i] = (pierce_point['p'], pierce_point['time'],
                                     pierce_point['dist'],
                                     pierce_point['depth'],
                                     pos['lat2'], pos['lon2'])
                arrival.pierce = geo_pierce

            if arrival.path is not None:
                geo_path = np.empty(arrival.path.shape, dtype=TimeDistGeo)
                for i, path_point in enumerate(arrival.path):
                    dir_degrees = np.degrees(sign * path_point['dist'])
                    pos = line.ArcPosition(dir_degrees)
                    geo_path[i] = (path_point['p'], path_point['time'],
                                   path_point['dist'], path_point['depth'],
                                   pos['lat2'], pos['lon2'])
                arrival.path = geo_path

    else:
        # geographiclib is not installed ...
        # and  obspy/geodetics does not help much
        msg = "You need to install the Python module 'geographiclib' in " + \
              "order to add geographical information to arrivals."
        raise ImportError(msg)

    return arrivals
Example #3
0
def organizebounds(num_bounds,iwall,idl,idr,lona,lata,lonb,latb,bound_ind,large_wall_inds,vt_ew,vt_ns,dsegtr,dseged,polarity,rad_km):

	# divide trenches and edges into segments
	lona_temp  = []; lata_temp  = []; 
	lonb_temp  = []; latb_temp  = []; iwall_temp = [];
	idl_temp   = []; idr_temp   = []; bound_ind_temp = []
	vt_ew_temp = []; vt_ns_temp = []; 
	polarity_temp = [];
	large_wall_inds_temp = [];

	num_segs = 0; num_wall_segs = 0
	print "------------------------"
	print "%.0f original boundaries" % num_bounds
	for i in range(num_bounds):

		# great circle distance [km]
		length = haversine(lona[i],lata[i],lonb[i],latb[i],rad_km)
		print "orig. length of segment %.0f = %.8f km" % (i+1,length)
		if iwall[i] == 1:
			iseg = int(.999 * length/dsegtr) + 1
		elif (idl[i] != idr[i]) and iwall[i] == 0:
			iseg = int(.999 * length/dseged) + 1
		else:
			iseg = 1  	# strike-slip (iwall=2)

		# https://geographiclib.sourceforge.io/html/python/
		geod = Geodesic(rad_km * 1e3, 0) # sphere
		gd = geod.Inverse(lata[i], lona[i], latb[i], lonb[i]) # total great-circle distance
		line = geod.Line(gd['lat1'], gd['lon1'], gd['azi1'])
		for iset in range(0,iseg):
			pointa = line.Position((gd['s12'] / iseg) * iset)
			pointb = line.Position((gd['s12'] / iseg) * (iset+1))
			lona2 = pointa['lon2']
			if lona2 < 0.:
				lona2 = 360. + lona2
			lona_temp.append(lona2)
			lata_temp.append(pointa['lat2'])
			lonb2 = pointb['lon2']
			if lonb2 < 0.:
				lonb2 = 360. + lonb2
			lonb_temp.append(lonb2)
			latb_temp.append(pointb['lat2'])

			iwall_temp.append(iwall[i]);
			idl_temp.append(idl[i]);
			idr_temp.append(idr[i]);
			bound_ind_temp.append(bound_ind[i])
			large_wall_inds_temp.append(large_wall_inds[i])
			vt_ew_temp.append(vt_ew[i])
			vt_ns_temp.append(vt_ns[i])
			polarity_temp.append(polarity[i])

		num_segs += iseg;
		if iwall[i] == 1:
			num_wall_segs += iseg;

	# # Double up wall boundaries
	n_segs = num_segs + num_wall_segs
	lona = np.zeros((n_segs)); lata = np.zeros((n_segs))
	lonb = np.zeros((n_segs)); latb = np.zeros((n_segs))
	vt_ew = np.zeros((n_segs)); vt_ns = np.zeros((n_segs)); 
	polarity = np.zeros((n_segs)); 
	iwall = [0] * n_segs; bound_ind = [0] * n_segs
	idl = [0] * n_segs; idr = [0] * n_segs; large_wall_inds = [0] * n_segs
	nwall = 0;
	for i in range(num_segs):
		lona[i] = lona_temp[i]
		lata[i] = lata_temp[i]
		lonb[i] = lonb_temp[i]
		latb[i] = latb_temp[i]
		iwall[i] = iwall_temp[i]
		idl[i] = idl_temp[i]
		idr[i] = idr_temp[i]
		bound_ind[i] = bound_ind_temp[i]
		large_wall_inds[i] = large_wall_inds_temp[i]
		vt_ew[i] = vt_ew_temp[i]
		vt_ns[i] = vt_ns_temp[i]
		polarity[i] = polarity_temp[i]
		if iwall_temp[i] == 1:
			lona[num_segs+nwall] = lona_temp[i]
			lata[num_segs+nwall] = lata_temp[i]
			lonb[num_segs+nwall] = lonb_temp[i]
			latb[num_segs+nwall] = latb_temp[i]
			iwall[num_segs+nwall] = iwall_temp[i]
			idl[num_segs+nwall] = idl_temp[i]
			idr[num_segs+nwall] = idr_temp[i]
			bound_ind[num_segs+nwall] = bound_ind_temp[i]
			large_wall_inds[num_segs+nwall] = large_wall_inds_temp[i]
			vt_ew[num_segs+nwall] = vt_ew_temp[i]
			vt_ns[num_segs+nwall] = vt_ns_temp[i]
			polarity[num_segs+nwall] = polarity_temp[i]
			nwall += 1;

	return (n_segs,num_segs,iwall,idl,idr,lona,lata,lonb,latb,bound_ind,large_wall_inds,vt_ew,vt_ns,polarity,num_wall_segs)
def add_geo_to_arrivals(arrivals,
                        source_latitude_in_deg,
                        source_longitude_in_deg,
                        receiver_latitude_in_deg,
                        receiver_longitude_in_deg,
                        radius_of_planet_in_km,
                        flattening_of_planet,
                        resample=False,
                        sampleds=5.0):
    """
    Add geographical information to arrivals.

    :param arrivals: Set of taup arrivals
    :type: :class:`Arrivals`
    :param source_latitude_in_deg: Source location latitude in degrees
    :type source_latitude_in_deg: float
    :param source_longitude_in_deg: Source location longitude in degrees
    :type source_longitude_in_deg: float
    :param receiver_latitude_in_deg: Receiver location latitude in degrees
    :type receiver_latitude_in_deg: float
    :param receiver_longitude_in_deg: Receiver location longitude in degrees
    :type receiver_longitude_in_deg: float
    :param radius_of_planet_in_km: Radius of the planet in km
    :type radius_of_planet_in_km: float
    :param flattening_of_planet: Flattening of planet (0 for a sphere)
    :type receiver_longitude_in_deg: float
    :param resample: adds sample points to allow for easy cartesian
                     interpolation. This is especially useful for phases
                     like Pdiff.
    :type resample: boolean


    :return: List of ``Arrival`` objects, each of which has the time,
        corresponding phase name, ray parameter, takeoff angle, etc. as
        attributes.
    :rtype: :class:`Arrivals`
    """
    if geodetics.HAS_GEOGRAPHICLIB:
        if not geodetics.GEOGRAPHICLIB_VERSION_AT_LEAST_1_34:
            # geographiclib is not installed ...
            # and  obspy/geodetics does not help much
            msg = ("This functionality needs the Python module "
                   "'geographiclib' in version 1.34 or higher.")
            raise ImportError(msg)
        ellipsoid = Geodesic(a=radius_of_planet_in_km * 1000.0,
                             f=flattening_of_planet)
        g = ellipsoid.Inverse(source_latitude_in_deg, source_longitude_in_deg,
                              receiver_latitude_in_deg,
                              receiver_longitude_in_deg)
        azimuth = g['azi1']
        line = ellipsoid.Line(source_latitude_in_deg, source_longitude_in_deg,
                              azimuth)

        # We may need to update many arrival objects
        # and each could have pierce points and a
        # path
        for arrival in arrivals:
            # check if we go in minor or major arc direction
            distance = arrival.purist_distance % 360.
            if distance > 180.:
                sign = -1
                az_arr = (azimuth + 180.) % 360.
            else:
                sign = 1
                az_arr = azimuth
            arrival.azimuth = az_arr

            if arrival.pierce is not None:
                geo_pierce = np.empty(arrival.pierce.shape, dtype=TimeDistGeo)

                for i, pierce_point in enumerate(arrival.pierce):
                    signed_dist = np.degrees(sign * pierce_point['dist'])
                    pos = line.ArcPosition(signed_dist)
                    geo_pierce[i] = (pierce_point['p'], pierce_point['time'],
                                     pierce_point['dist'],
                                     pierce_point['depth'], pos['lat2'],
                                     pos['lon2'])
                arrival.pierce = geo_pierce

            # choose whether we need to resample the trace
            if arrival.path is not None:
                if resample:
                    rplanet = radius_of_planet_in_km
                    # compute approximate distance between sampling points
                    # mindist = 200  # km
                    mindist = sampleds
                    radii = rplanet - arrival.path['depth']
                    rmean = np.sqrt(radii[1:] * radii[:-1])
                    diff_dists = rmean * np.diff(arrival.path['dist'])
                    npts_extra = np.floor(diff_dists / mindist).astype(np.int)

                    # count number of extra points and initialize array
                    npts_old = len(arrival.path)
                    npts_new = int(npts_old + np.sum(npts_extra))
                    geo_path = np.empty(npts_new, dtype=TimeDistGeo)

                    # now loop through path, adding extra points
                    i_new = 0
                    for i_old, path_point in enumerate(arrival.path):
                        # first add the original point at the new index
                        dist = np.degrees(sign * path_point['dist'])
                        pos = line.ArcPosition(dist)
                        geo_path[i_new] = (path_point['p'], path_point['time'],
                                           path_point['dist'],
                                           path_point['depth'], pos['lat2'],
                                           pos['lon2'])
                        i_new += 1

                        if i_old > npts_old - 2:
                            continue

                        # now check if we need to add new points
                        npts_new = npts_extra[i_old]
                        if npts_new > 0:
                            # if yes, distribute them linearly between the old
                            # and the next point
                            next_point = arrival.path[i_old + 1]
                            dist_next = np.degrees(sign * next_point['dist'])
                            dists_new = np.linspace(dist, dist_next,
                                                    npts_new + 2)[1:-1]

                            # now get all interpolated parameters
                            xs = [dist, dist_next]
                            ys = [path_point['p'], next_point['p']]
                            p_interp = np.interp(dists_new, xs, ys)
                            ys = [path_point['time'], next_point['time']]
                            time_interp = np.interp(dists_new, xs, ys)
                            ys = [path_point['depth'], next_point['depth']]
                            depth_interp = np.interp(dists_new, xs, ys)
                            pos_interp = [
                                line.ArcPosition(dist_new)
                                for dist_new in dists_new
                            ]
                            lat_interp = [
                                point['lat2'] for point in pos_interp
                            ]
                            lon_interp = [
                                point['lon2'] for point in pos_interp
                            ]

                            # add them to geo_path
                            # dists_new --> np.radians(dists_new), modified by Hongjian Fang
                            for i_extra in range(npts_new):
                                geo_path[i_new] = (p_interp[i_extra],
                                                   time_interp[i_extra],
                                                   np.radians(
                                                       dists_new[i_extra]),
                                                   depth_interp[i_extra],
                                                   lat_interp[i_extra],
                                                   lon_interp[i_extra])
                                i_new += 1

                    arrival.path = geo_path
                else:
                    geo_path = np.empty(arrival.path.shape, dtype=TimeDistGeo)
                    for i, path_point in enumerate(arrival.path):
                        signed_dist = np.degrees(sign * path_point['dist'])
                        pos = line.ArcPosition(signed_dist)
                        geo_path[i] = (path_point['p'], path_point['time'],
                                       path_point['dist'], path_point['depth'],
                                       pos['lat2'], pos['lon2'])
                    arrival.path = geo_path
    else:
        # geographiclib is not installed ...
        # and  obspy/geodetics does not help much
        msg = "You need to install the Python module 'geographiclib' in " + \
              "order to add geographical information to arrivals."
        raise ImportError(msg)

    return arrivals