Пример #1
0
    def calculate_phase_delays(self, slowness, phase='Ps', ref=6.4):
        """
        Calculate travel time delays for slowness and reference slowness.

        Travel time delays are calculated between the direct wave and the
        converted phase or multiples.

        :param slowness: ray parameter in s/deg
        :param phase: 'Ps', 'Sp' or multiples
        :param ref: reference ray parameter in s/deg
        :return: original times, times stretched to reference slowness
        """
        if len(phase) % 2 == 1:
            msg = 'Length of phase (%s) should be divisible by two'
            raise ValueError(msg % phase)
        slowness = slowness * kilometer2degrees(1)
        ref = ref * kilometer2degrees(1)
        phase = phase.upper()
        try:
            t_ref = self.t_ref[phase]
        except KeyError:
            self.t_ref[phase] = t_ref = self._calc_phase_delay(ref, phase)
        t = self._calc_phase_delay(slowness, phase)
        if phase[0] == 'S':
            t_ref = -t_ref
            t = -t
        try:
            index = np.nonzero(np.isnan(t))[0][0] - 1
        except IndexError:
            index = len(t)
        t = t[:index]
        t_ref = t_ref[:index]
        return (np.hstack((-t[1:10][::-1], t)),
                np.hstack((-t_ref[1:10][::-1], t_ref)))
Пример #2
0
    def calculate_phase_delays(self, slowness, phase='Ps', ref=6.4):
        """
        Calculate travel time delays for slowness and reference slowness.

        Travel time delays are calculated between the direct wave and the
        converted phase or multiples.

        :param slowness: ray parameter in s/deg
        :param phase: 'Ps', 'Sp' or multiples
        :param ref: reference ray parameter in s/deg
        :return: original times, times stretched to reference slowness
        """
        if len(phase) % 2 == 1:
            msg = 'Length of phase (%s) should be divisible by two'
            raise ValueError(msg % phase)
        slowness = slowness * kilometer2degrees(1)
        ref = ref * kilometer2degrees(1)
        phase = phase.upper()
        try:
            t_ref = self.t_ref[phase]
        except KeyError:
            self.t_ref[phase] = t_ref = self._calc_phase_delay(ref, phase)
        t = self._calc_phase_delay(slowness, phase)
        if phase[0] == 'S':
            t_ref = -t_ref
            t = -t
        try:
            index = np.nonzero(np.isnan(t))[0][0] - 1
        except IndexError:
            index = len(t)
        t = t[:index]
        t_ref = t_ref[:index]
        return (np.hstack(
            (-t[1:10][::-1], t)), np.hstack((-t_ref[1:10][::-1], t_ref)))
Пример #3
0
 def test_kilometer2degrees(self):
     """
     Simple test of the convenience function.
     """
     # Test if it works.
     self.assertEqual(kilometer2degrees(111.19492664455873, radius=6371),
                      1.0)
     # Test if setting the radius actually does something. Round to avoid
     # some precision problems on different machines.
     self.assertEqual(round(kilometer2degrees(111.19492664455873,
                      radius=6381), 5), round(0.99843284751606332, 5))
Пример #4
0
 def test_kilometer2degrees(self):
     """
     Simple test of the convenience function.
     """
     # Test if it works.
     self.assertEqual(kilometer2degrees(111.19492664455873, radius=6371),
                      1.0)
     # Test if setting the radius actually does something. Round to avoid
     # some precision problems on different machines.
     self.assertEqual(
         round(kilometer2degrees(111.19492664455873, radius=6381), 5),
         round(0.99843284751606332, 5))
Пример #5
0
    def ppoint_distance(self, depth, slowness, phase='S'):
        """
        Calculate horizontal distance of piercing point to station.

        :param depth: depth of interface in km
        :param slowness: ray parameter in s/deg
        :param phase: 'P' or 'S' for P wave or S wave. Multiples are possible.
        :return: horizontal distance in km
        """
        if len(phase) % 2 == 0:
            msg = 'Length of phase (%s) should be even'
            raise ValueError(msg % phase)
        phase = phase.upper()
        slowness = slowness * kilometer2degrees(1)
        xp, xs = 0., 0.
        qp, qs = self._calc_vertical_slowness(slowness, phase=phase)
        if 'P' in phase:
            xp = np.cumsum(self.dz * slowness / qp)
        if 'S' in phase:
            xs = np.cumsum(self.dz * slowness / qs)
        x = xp * phase.count('P') + xs * phase.count('S')
        z = self.z
        index = np.nonzero(depth < z)[0][0] - 1
        return x[index] + ((x[index + 1] - x[index]) * (depth - z[index]) /
                           (z[index + 1] - z[index]))
Пример #6
0
    def ppoint_distance(self, depth, slowness, phase='S'):
        """
        Calculate horizontal distance of piercing point to station.

        :param depth: depth of interface in km
        :param slowness: ray parameter in s/deg
        :param phase: 'P' or 'S' for P wave or S wave. Multiples are possible.
        :return: horizontal distance in km
        """
        if len(phase) % 2 == 0:
            msg = 'Length of phase (%s) should be even'
            raise ValueError(msg % phase)
        phase = phase.upper()
        slowness = slowness * kilometer2degrees(1)
        xp, xs = 0., 0.
        qp, qs = self._calc_vertical_slowness(slowness, phase=phase)
        if 'P' in phase:
            xp = np.cumsum(self.dz * slowness / qp)
        if 'S' in phase:
            xs = np.cumsum(self.dz * slowness / qs)
        x = xp * phase.count('P') + xs * phase.count('S')
        z = self.z
        index = np.nonzero(depth < z)[0][0] - 1
        return x[index] + ((x[index + 1] - x[index]) *
                           (depth - z[index]) / (z[index + 1] - z[index]))
Пример #7
0
   def __init__(self, ses3d_seismogram):

       #inherit information from instance of ses3d_seismogram()
       self.ses3d_seismogram = ses3d_seismogram
       self.eq_depth = ses3d_seismogram.sz/1000.0

       #initialize receiver function specific information
       dist_az        = gps2dist_azimuth((90.0-self.ses3d_seismogram.rx),
                                         self.ses3d_seismogram.ry, 
                                        (90.0-self.ses3d_seismogram.sx),
                                         self.ses3d_seismogram.sy,
                                         a = 6371000.0, f = 0.0)
       self.back_az   = dist_az[1]
       self.az        = dist_az[2]
       self.delta_deg = kilometer2degrees(dist_az[0]/1000.0)
       self.time      = np.zeros(100)
       self.prf       = np.zeros(100)
       self.srf       = np.zeros(100)
       self.r = np.zeros(100)
       self.t = np.zeros(100)
       self.z = np.zeros(100)
       self.slowness = 0.0
       self.pierce_dict = []
       self.window_start = 0.0
       self.window_end   = 0.0
Пример #8
0
    def __init__(self, ses3d_seismogram):

        #inherit information from instance of ses3d_seismogram()
        self.ses3d_seismogram = ses3d_seismogram
        self.eq_depth = ses3d_seismogram.sz / 1000.0

        #initialize receiver function specific information
        dist_az = gps2dist_azimuth((90.0 - self.ses3d_seismogram.rx),
                                   self.ses3d_seismogram.ry,
                                   (90.0 - self.ses3d_seismogram.sx),
                                   self.ses3d_seismogram.sy,
                                   a=6371000.0,
                                   f=0.0)
        self.back_az = dist_az[1]
        self.az = dist_az[2]
        self.delta_deg = kilometer2degrees(dist_az[0] / 1000.0)
        self.time = np.zeros(100)
        self.prf = np.zeros(100)
        self.srf = np.zeros(100)
        self.r = np.zeros(100)
        self.t = np.zeros(100)
        self.z = np.zeros(100)
        self.slowness = 0.0
        self.pierce_dict = []
        self.window_start = 0.0
        self.window_end = 0.0
Пример #9
0
def rfstats(stats=None, event=None, station=None, stream=None,
            phase='P', dist_range=None):
    """
    Calculate ray specific values like slowness for given event and station.

    :param stats: stats object with event and/or station attributes. Can be
        None if both event and station are given.
    :param event: ObsPy :class:`~obspy.core.event.Event` object
    :param station: station object with attributes latitude, longitude and
        elevation
    :param stream: If a stream is given, stats has to be None. In this case
        rfstats will be called for every stats object in the stream.
    :param phase: string with phase to look for in result of
        :func:`~obspy.taup.taup.getTravelTimes`. Usually this will be 'P' or
        'S' for P and S receiver functions, respectively.
    :type dist_range: tuple of length 2
    :param dist_range: if epicentral of event is not in this intervall, None
        is returned by this function,\n
        if phase == 'P' defaults to (30, 90),\n
        if phase == 'S' defaults to (50, 85)

    :return: ``stats`` object with event and station attributes, distance,
        back_azimuth, inclination, onset and slowness or None if epicentral
        distance is not in the given intervall
    """
    if stream is not None:
        assert stats is None
        for tr in stream:
            rfstats(tr.stats, event, station, None, phase, dist_range)
        return
    phase = phase.upper()
    if dist_range is None and phase in 'PS':
        dist_range = (30, 90) if phase == 'P' else (50, 85)
    if stats is None:
        stats = AttribDict({})
    stats.update(obj2stats(event=event, station=station))
    dist, baz, _ = gps2DistAzimuth(stats.station_latitude,
                                   stats.station_longitude,
                                   stats.event_latitude,
                                   stats.event_longitude)
    dist = kilometer2degrees(dist / 1000)
    if dist_range and not dist_range[0] <= dist <= dist_range[1]:
        return
    tts = getTravelTimes(dist, stats.event_depth)
    tts2 = getTravelTimes(dist, 0)
    tts = [tt for tt in tts if tt['phase_name'] == phase]
    tts2 = [tt for tt in tts2 if tt['phase_name'] == phase]
    if len(tts) == 0 or len(tts2) == 0:
        raise Exception('Taup does not return phase %s at event distance %s' %
                        (phase, dist))
    onset = stats.event_time + tts[0]['time']
    inc = tts2[0]['take-off angle']  # approximation
    v = 5.8 if 'P' in phase else 3.36  # iasp91
    slowness = 6371. * sin(pi / 180. * inc) / v / 180 * pi
    stats.update({'distance': dist, 'back_azimuth': baz, 'inclination': inc,
                  'onset': onset, 'slowness': slowness})
    return stats
Пример #10
0
def get_event_params(eq_lat,eq_lon):
   dist_az = gps2dist_azimuth(eq_lat,eq_lon,0,0,a=6371000.0,f=0.0)
   dist_km = dist_az[0]/1000.0
   dist_deg = kilometer2degrees(dist_km)
   az = dist_az[1]
   baz = dist_az[2]
   rotation_angle = -1.0*((baz-180) -90.0)
   #rotation_angle = -1.0*(az-90.0)

   return dist_deg,rotation_angle
Пример #11
0
def get_event_params(eq_lat, eq_lon):
    dist_az = gps2dist_azimuth(eq_lat, eq_lon, 0, 0, a=6371000.0, f=0.0)
    dist_km = dist_az[0] / 1000.0
    dist_deg = kilometer2degrees(dist_km)
    az = dist_az[1]
    baz = dist_az[2]
    rotation_angle = -1.0 * ((baz - 180) - 90.0)
    #rotation_angle = -1.0*(az-90.0)

    return dist_deg, rotation_angle
Пример #12
0
Файл: main.py Проект: preinh/RF
def event2stats(lat, lon, event, phase='P', dist_range=(30, 90)):
    phase = phase.upper()
    ori = event.origins[0]
    dist, baz, _ = gps2DistAzimuth(lat, lon,
                                   ori.latitude, ori.longitude)
    dist = kilometer2degrees(dist / 1000)
    if not dist_range[0] <= dist <= dist_range[1]:
        return
    tts = getTravelTimes(dist, ori.depth)
    tts2 = getTravelTimes(dist, 0)
    tts = [tt for tt in tts if tt['phase_name'] == phase]
    tts2 = [tt for tt in tts2 if tt['phase_name'] == phase]
    if len(tts) == 0 or len(tts2) == 0:
        raise Exception('Taup does not return phase %s at event distance %s' %
                        (phase, dist))
    onset = event.origins[0].time + tts[0]['time']
    inc = tts2[0]['take-off angle']  # approximation
    return AttribDict({'dist':dist, 'back_azimuth':baz, 'inclination': inc,
                       'onset':onset})
Пример #13
0
    def plot_all(self, directory, sf=1e5, component='x'):
        import seismograms as s
        import matplotlib.pylab as plt
        from obspy.core.util.geodetics import gps2DistAzimuth
        from obspy.core.util.geodetics import kilometer2degrees

        for i in range(0, self.n_recs):
            a = s.ses3d_seismogram()
            a.read(directory, self.recs[i])

            #determine epicentral distance
            dist_az = gps2DistAzimuth((90.0 - a.rx), a.ry, (90.0 - a.sx), a.sy)
            back_az = dist_az[1]
            delta_deg = kilometer2degrees(dist_az[0] / 1000.0)

            if (component == 'x'):
                plt.plot(a.trace_x * sf + delta_deg, a.t, 'k')
            elif (component == 'y'):
                plt.plot(a.trace_y * sf + delta_deg, a.t, 'k')
            elif (component == 'z'):
                plt.plot(a.trace_z * sf + delta_deg, a.t, 'k')

        plt.show()
Пример #14
0
   def plot_all(self,directory,sf=1e5,component='x'):
      import seismograms as s   
      import matplotlib.pylab as plt
      from obspy.core.util.geodetics import gps2DistAzimuth
      from obspy.core.util.geodetics import kilometer2degrees


      for i in range(0,self.n_recs):
         a = s.ses3d_seismogram()
         a.read(directory,self.recs[i])

         #determine epicentral distance
         dist_az   = gps2DistAzimuth((90.0-a.rx),a.ry,(90.0-a.sx),a.sy)
         back_az   = dist_az[1]
         delta_deg = kilometer2degrees(dist_az[0]/1000.0)

         if (component == 'x'):
            plt.plot(a.trace_x*sf + delta_deg, a.t,'k')
         elif (component == 'y'):
            plt.plot(a.trace_y*sf + delta_deg, a.t,'k')
         elif (component == 'z'):
            plt.plot(a.trace_z*sf + delta_deg, a.t,'k')

      plt.show()
Пример #15
0
def read_nlloc_hyp(filename, coordinate_converter=None, picks=None, **kwargs):
    """
    Reads a NonLinLoc Hypocenter-Phase file to a
    :class:`~obspy.core.event.Catalog` object.

    .. note::

        Coordinate conversion from coordinate frame of NonLinLoc model files /
        location run to WGS84 has to be specified explicitly by the user if
        necessary.

    .. note::

        An example can be found on the :mod:`~obspy.nlloc` submodule front
        page in the documentation pages.

    :param filename: File or file-like object in text mode.
    :type coordinate_converter: func
    :param coordinate_converter: Function to convert (x, y, z)
        coordinates of NonLinLoc output to geographical coordinates and depth
        in meters (longitude, latitude, depth in kilometers).
        If left `None` NonLinLoc (x, y, z) output is left unchanged (e.g. if
        it is in geographical coordinates already like for NonLinLoc in
        global mode).
        The function should accept three arguments x, y, z and return a
        tuple of three values (lon, lat, depth in kilometers).
    :type picks: list of :class:`~obspy.core.event.Pick`
    :param picks: Original picks used to generate the NonLinLoc location.
        If provided, the output event will include the original picks and the
        arrivals in the output origin will link to them correctly (with their
        `pick_id` attribute). If not provided, the output event will include
        (the rather basic) pick information that can be reconstructed from the
        NonLinLoc hypocenter-phase file.
    :rtype: :class:`~obspy.core.event.Catalog`
    """
    if not hasattr(filename, "read"):
        # Check if it exists, otherwise assume its a string.
        try:
            with open(filename, "rt") as fh:
                data = fh.read()
        except:
            try:
                data = filename.decode()
            except:
                data = str(filename)
            data = data.strip()
    else:
        data = filename.read()
        if hasattr(data, "decode"):
            data = data.decode()

    lines = data.splitlines()

    # remember picks originally used in location, if provided
    original_picks = picks
    if original_picks is None:
        original_picks = []

    # determine indices of block start/end of the NLLOC output file
    indices_hyp = [None, None]
    indices_phases = [None, None]
    for i, line in enumerate(lines):
        if line.startswith("NLLOC "):
            indices_hyp[0] = i
        elif line.startswith("END_NLLOC"):
            indices_hyp[1] = i
        elif line.startswith("PHASE "):
            indices_phases[0] = i
        elif line.startswith("END_PHASE"):
            indices_phases[1] = i
    if any([i is None for i in indices_hyp]):
        msg = ("NLLOC HYP file seems corrupt,"
               " could not detect 'NLLOC' and 'END_NLLOC' lines.")
        raise RuntimeError(msg)
    # strip any other lines around NLLOC block
    lines = lines[indices_hyp[0]:indices_hyp[1]]

    # extract PHASES lines (if any)
    if any(indices_phases):
        if not all(indices_phases):
            msg = ("NLLOC HYP file seems corrupt, 'PHASE' block is corrupt.")
            raise RuntimeError(msg)
        i1, i2 = indices_phases
        lines, phases_lines = lines[:i1] + lines[i2 + 1:], lines[i1 + 1:i2]
    else:
        phases_lines = []

    lines = dict([line.split(None, 1) for line in lines])
    line = lines["SIGNATURE"]

    line = line.rstrip().split('"')[1]
    signature, version, date, time = line.rsplit(" ", 3)
    creation_time = UTCDateTime().strptime(date + time, str("%d%b%Y%Hh%Mm%S"))

    # maximum likelihood origin location info line
    line = lines["HYPOCENTER"]

    x, y, z = map(float, line.split()[1:7:2])

    if coordinate_converter:
        x, y, z = coordinate_converter(x, y, z)

    # origin time info line
    line = lines["GEOGRAPHIC"]

    year, month, day, hour, minute = map(int, line.split()[1:6])
    seconds = float(line.split()[6])
    time = UTCDateTime(year, month, day, hour, minute, seconds)

    # distribution statistics line
    line = lines["STATISTICS"]
    covariance_XX = float(line.split()[7])
    covariance_YY = float(line.split()[13])
    covariance_ZZ = float(line.split()[17])
    stats_info_string = str(
        "Note: Depth/Latitude/Longitude errors are calculated from covariance "
        "matrix as 1D marginal (Lon/Lat errors as great circle degrees) "
        "while OriginUncertainty min/max horizontal errors are calculated "
        "from 2D error ellipsoid and are therefore seemingly higher compared "
        "to 1D errors. Error estimates can be reconstructed from the "
        "following original NonLinLoc error statistics line:\nSTATISTICS " +
        lines["STATISTICS"])

    # goto location quality info line
    line = lines["QML_OriginQuality"].split()

    (assoc_phase_count, used_phase_count, assoc_station_count,
     used_station_count, depth_phase_count) = map(int, line[1:11:2])
    stderr, az_gap, sec_az_gap = map(float, line[11:17:2])
    gt_level = line[17]
    min_dist, max_dist, med_dist = map(float, line[19:25:2])

    # goto location quality info line
    line = lines["QML_OriginUncertainty"]

    hor_unc, min_hor_unc, max_hor_unc, hor_unc_azim = \
        map(float, line.split()[1:9:2])

    # assign origin info
    event = Event()
    cat = Catalog(events=[event])
    o = Origin()
    event.origins = [o]
    o.origin_uncertainty = OriginUncertainty()
    o.quality = OriginQuality()
    ou = o.origin_uncertainty
    oq = o.quality
    o.comments.append(Comment(text=stats_info_string))

    cat.creation_info.creation_time = UTCDateTime()
    cat.creation_info.version = "ObsPy %s" % __version__
    event.creation_info = CreationInfo(creation_time=creation_time,
                                       version=version)
    event.creation_info.version = version
    o.creation_info = CreationInfo(creation_time=creation_time,
                                   version=version)

    # negative values can appear on diagonal of covariance matrix due to a
    # precision problem in NLLoc implementation when location coordinates are
    # large compared to the covariances.
    o.longitude = x
    try:
        o.longitude_errors.uncertainty = kilometer2degrees(sqrt(covariance_XX))
    except ValueError:
        if covariance_XX < 0:
            msg = ("Negative value in XX value of covariance matrix, not "
                   "setting longitude error (epicentral uncertainties will "
                   "still be set in origin uncertainty).")
            warnings.warn(msg)
        else:
            raise
    o.latitude = y
    try:
        o.latitude_errors.uncertainty = kilometer2degrees(sqrt(covariance_YY))
    except ValueError:
        if covariance_YY < 0:
            msg = ("Negative value in YY value of covariance matrix, not "
                   "setting longitude error (epicentral uncertainties will "
                   "still be set in origin uncertainty).")
            warnings.warn(msg)
        else:
            raise
    o.depth = z * 1e3  # meters!
    o.depth_errors.uncertainty = sqrt(covariance_ZZ) * 1e3  # meters!
    o.depth_errors.confidence_level = 68
    o.depth_type = str("from location")
    o.time = time

    ou.horizontal_uncertainty = hor_unc
    ou.min_horizontal_uncertainty = min_hor_unc
    ou.max_horizontal_uncertainty = max_hor_unc
    # values of -1 seem to be used for unset values, set to None
    for field in ("horizontal_uncertainty", "min_horizontal_uncertainty",
                  "max_horizontal_uncertainty"):
        if ou.get(field, -1) == -1:
            ou[field] = None
        else:
            ou[field] *= 1e3  # meters!
    ou.azimuth_max_horizontal_uncertainty = hor_unc_azim
    ou.preferred_description = str("uncertainty ellipse")
    ou.confidence_level = 68  # NonLinLoc in general uses 1-sigma (68%) level

    oq.standard_error = stderr
    oq.azimuthal_gap = az_gap
    oq.secondary_azimuthal_gap = sec_az_gap
    oq.used_phase_count = used_phase_count
    oq.used_station_count = used_station_count
    oq.associated_phase_count = assoc_phase_count
    oq.associated_station_count = assoc_station_count
    oq.depth_phase_count = depth_phase_count
    oq.ground_truth_level = gt_level
    oq.minimum_distance = kilometer2degrees(min_dist)
    oq.maximum_distance = kilometer2degrees(max_dist)
    oq.median_distance = kilometer2degrees(med_dist)

    # go through all phase info lines
    for line in phases_lines:
        line = line.split()
        arrival = Arrival()
        o.arrivals.append(arrival)
        station = str(line[0])
        phase = str(line[4])
        arrival.phase = phase
        arrival.distance = kilometer2degrees(float(line[21]))
        arrival.azimuth = float(line[23])
        arrival.takeoff_angle = float(line[24])
        arrival.time_residual = float(line[16])
        arrival.time_weight = float(line[17])
        pick = Pick()
        wid = WaveformStreamID(station_code=station)
        date, hourmin, sec = map(str, line[6:9])
        t = UTCDateTime().strptime(date + hourmin, "%Y%m%d%H%M") + float(sec)
        pick.waveform_id = wid
        pick.time = t
        pick.time_errors.uncertainty = float(line[10])
        pick.phase_hint = phase
        pick.onset = ONSETS.get(line[3].lower(), None)
        pick.polarity = POLARITIES.get(line[5].lower(), None)
        # try to determine original pick for each arrival
        for pick_ in original_picks:
            wid = pick_.waveform_id
            if station == wid.station_code and phase == pick_.phase_hint:
                pick = pick_
                break
        else:
            # warn if original picks were specified and we could not associate
            # the arrival correctly
            if original_picks:
                msg = ("Could not determine corresponding original pick for "
                       "arrival. "
                       "Falling back to pick information in NonLinLoc "
                       "hypocenter-phase file.")
                warnings.warn(msg)
        event.picks.append(pick)
        arrival.pick_id = pick.resource_id

    return cat
Пример #16
0
def read_nlloc_hyp(filename, coordinate_converter=None, picks=None, **kwargs):
    """
    Reads a NonLinLoc Hypocenter-Phase file to a
    :class:`~obspy.core.event.Catalog` object.

    .. note::

        Coordinate conversion from coordinate frame of NonLinLoc model files /
        location run to WGS84 has to be specified explicitly by the user if
        necessary.

    .. note::

        An example can be found on the :mod:`~obspy.nlloc` submodule front
        page in the documentation pages.

    :param filename: File or file-like object in text mode.
    :type coordinate_converter: func
    :param coordinate_converter: Function to convert (x, y, z)
        coordinates of NonLinLoc output to geographical coordinates and depth
        in meters (longitude, latitude, depth in kilometers).
        If left `None` NonLinLoc (x, y, z) output is left unchanged (e.g. if
        it is in geographical coordinates already like for NonLinLoc in
        global mode).
        The function should accept three arguments x, y, z and return a
        tuple of three values (lon, lat, depth in kilometers).
    :type picks: list of :class:`~obspy.core.event.Pick`
    :param picks: Original picks used to generate the NonLinLoc location.
        If provided, the output event will include the original picks and the
        arrivals in the output origin will link to them correctly (with their
        `pick_id` attribute). If not provided, the output event will include
        (the rather basic) pick information that can be reconstructed from the
        NonLinLoc hypocenter-phase file.
    :rtype: :class:`~obspy.core.event.Catalog`
    """
    if not hasattr(filename, "read"):
        # Check if it exists, otherwise assume its a string.
        try:
            with open(filename, "rt") as fh:
                data = fh.read()
        except:
            try:
                data = filename.decode()
            except:
                data = str(filename)
            data = data.strip()
    else:
        data = filename.read()
        if hasattr(data, "decode"):
            data = data.decode()

    lines = data.splitlines()

    # remember picks originally used in location, if provided
    original_picks = picks
    if original_picks is None:
        original_picks = []

    # determine indices of block start/end of the NLLOC output file
    indices_hyp = [None, None]
    indices_phases = [None, None]
    for i, line in enumerate(lines):
        if line.startswith("NLLOC "):
            indices_hyp[0] = i
        elif line.startswith("END_NLLOC"):
            indices_hyp[1] = i
        elif line.startswith("PHASE "):
            indices_phases[0] = i
        elif line.startswith("END_PHASE"):
            indices_phases[1] = i
    if any([i is None for i in indices_hyp]):
        msg = ("NLLOC HYP file seems corrupt,"
               " could not detect 'NLLOC' and 'END_NLLOC' lines.")
        raise RuntimeError(msg)
    # strip any other lines around NLLOC block
    lines = lines[indices_hyp[0]:indices_hyp[1]]

    # extract PHASES lines (if any)
    if any(indices_phases):
        if not all(indices_phases):
            msg = ("NLLOC HYP file seems corrupt, 'PHASE' block is corrupt.")
            raise RuntimeError(msg)
        i1, i2 = indices_phases
        lines, phases_lines = lines[:i1] + lines[i2 + 1:], lines[i1 + 1:i2]
    else:
        phases_lines = []

    lines = dict([line.split(None, 1) for line in lines])
    line = lines["SIGNATURE"]

    line = line.rstrip().split('"')[1]
    signature, version, date, time = line.rsplit(" ", 3)
    creation_time = UTCDateTime().strptime(date + time, str("%d%b%Y%Hh%Mm%S"))

    # maximum likelihood origin location info line
    line = lines["HYPOCENTER"]

    x, y, z = map(float, line.split()[1:7:2])

    if coordinate_converter:
        x, y, z = coordinate_converter(x, y, z)

    # origin time info line
    line = lines["GEOGRAPHIC"]

    year, month, day, hour, minute = map(int, line.split()[1:6])
    seconds = float(line.split()[6])
    time = UTCDateTime(year, month, day, hour, minute, seconds)

    # distribution statistics line
    line = lines["STATISTICS"]
    covariance_XX = float(line.split()[7])
    covariance_YY = float(line.split()[13])
    covariance_ZZ = float(line.split()[17])
    stats_info_string = str(
        "Note: Depth/Latitude/Longitude errors are calculated from covariance "
        "matrix as 1D marginal (Lon/Lat errors as great circle degrees) "
        "while OriginUncertainty min/max horizontal errors are calculated "
        "from 2D error ellipsoid and are therefore seemingly higher compared "
        "to 1D errors. Error estimates can be reconstructed from the "
        "following original NonLinLoc error statistics line:\nSTATISTICS " +
        lines["STATISTICS"])

    # goto location quality info line
    line = lines["QML_OriginQuality"].split()

    (assoc_phase_count, used_phase_count, assoc_station_count,
     used_station_count, depth_phase_count) = map(int, line[1:11:2])
    stderr, az_gap, sec_az_gap = map(float, line[11:17:2])
    gt_level = line[17]
    min_dist, max_dist, med_dist = map(float, line[19:25:2])

    # goto location quality info line
    line = lines["QML_OriginUncertainty"]

    hor_unc, min_hor_unc, max_hor_unc, hor_unc_azim = \
        map(float, line.split()[1:9:2])

    # assign origin info
    event = Event()
    cat = Catalog(events=[event])
    o = Origin()
    event.origins = [o]
    o.origin_uncertainty = OriginUncertainty()
    o.quality = OriginQuality()
    ou = o.origin_uncertainty
    oq = o.quality
    o.comments.append(Comment(text=stats_info_string))

    cat.creation_info.creation_time = UTCDateTime()
    cat.creation_info.version = "ObsPy %s" % __version__
    event.creation_info = CreationInfo(creation_time=creation_time,
                                       version=version)
    event.creation_info.version = version
    o.creation_info = CreationInfo(creation_time=creation_time,
                                   version=version)

    # negative values can appear on diagonal of covariance matrix due to a
    # precision problem in NLLoc implementation when location coordinates are
    # large compared to the covariances.
    o.longitude = x
    try:
        o.longitude_errors.uncertainty = kilometer2degrees(sqrt(covariance_XX))
    except ValueError:
        if covariance_XX < 0:
            msg = ("Negative value in XX value of covariance matrix, not "
                   "setting longitude error (epicentral uncertainties will "
                   "still be set in origin uncertainty).")
            warnings.warn(msg)
        else:
            raise
    o.latitude = y
    try:
        o.latitude_errors.uncertainty = kilometer2degrees(sqrt(covariance_YY))
    except ValueError:
        if covariance_YY < 0:
            msg = ("Negative value in YY value of covariance matrix, not "
                   "setting longitude error (epicentral uncertainties will "
                   "still be set in origin uncertainty).")
            warnings.warn(msg)
        else:
            raise
    o.depth = z * 1e3  # meters!
    o.depth_errors.uncertainty = sqrt(covariance_ZZ) * 1e3  # meters!
    o.depth_errors.confidence_level = 68
    o.depth_type = str("from location")
    o.time = time

    ou.horizontal_uncertainty = hor_unc
    ou.min_horizontal_uncertainty = min_hor_unc
    ou.max_horizontal_uncertainty = max_hor_unc
    # values of -1 seem to be used for unset values, set to None
    for field in ("horizontal_uncertainty", "min_horizontal_uncertainty",
                  "max_horizontal_uncertainty"):
        if ou.get(field, -1) == -1:
            ou[field] = None
        else:
            ou[field] *= 1e3  # meters!
    ou.azimuth_max_horizontal_uncertainty = hor_unc_azim
    ou.preferred_description = str("uncertainty ellipse")
    ou.confidence_level = 68  # NonLinLoc in general uses 1-sigma (68%) level

    oq.standard_error = stderr
    oq.azimuthal_gap = az_gap
    oq.secondary_azimuthal_gap = sec_az_gap
    oq.used_phase_count = used_phase_count
    oq.used_station_count = used_station_count
    oq.associated_phase_count = assoc_phase_count
    oq.associated_station_count = assoc_station_count
    oq.depth_phase_count = depth_phase_count
    oq.ground_truth_level = gt_level
    oq.minimum_distance = kilometer2degrees(min_dist)
    oq.maximum_distance = kilometer2degrees(max_dist)
    oq.median_distance = kilometer2degrees(med_dist)

    # go through all phase info lines
    for line in phases_lines:
        line = line.split()
        arrival = Arrival()
        o.arrivals.append(arrival)
        station = str(line[0])
        phase = str(line[4])
        arrival.phase = phase
        arrival.distance = kilometer2degrees(float(line[21]))
        arrival.azimuth = float(line[23])
        arrival.takeoff_angle = float(line[24])
        arrival.time_residual = float(line[16])
        arrival.time_weight = float(line[17])
        pick = Pick()
        wid = WaveformStreamID(station_code=station)
        date, hourmin, sec = map(str, line[6:9])
        t = UTCDateTime().strptime(date + hourmin, "%Y%m%d%H%M") + float(sec)
        pick.waveform_id = wid
        pick.time = t
        pick.time_errors.uncertainty = float(line[10])
        pick.phase_hint = phase
        pick.onset = ONSETS.get(line[3].lower(), None)
        pick.polarity = POLARITIES.get(line[5].lower(), None)
        # try to determine original pick for each arrival
        for pick_ in original_picks:
            wid = pick_.waveform_id
            if station == wid.station_code and phase == pick_.phase_hint:
                pick = pick_
                break
        else:
            # warn if original picks were specified and we could not associate
            # the arrival correctly
            if original_picks:
                msg = ("Could not determine corresponding original pick for "
                       "arrival. "
                       "Falling back to pick information in NonLinLoc "
                       "hypocenter-phase file.")
                warnings.warn(msg)
        event.picks.append(pick)
        arrival.pick_id = pick.resource_id

    return cat
Пример #17
0
def make_earthquake_list(param_dict, **kwargs):
    '''
   Generate earthquakes to be used in tomographic inversion. Earthquake locations can 
   be generated randomly within the distance range (deltamin, deltamax), or alternatively
   a ring of earthquakes at a fixed distance from the point (0,0) can be generated.
   In the futures, events may be given as an obspy event catalog.

   args--------------------------------------------------------------------------
   param_dict: parameter dictionary (read from file 'inparam_tomo')
   
   kwargs------------------------------------------------------------------------
   nevents: number of earthquakes (only use if geometry is 'random')
   deltamin = minimum earthquake distance from (0,0) (only if geometry is 'random')
   deltamax = maximum earthquake distance from (0,0) (only if geometry is 'random')
   ringdist = distance of ring from (0,0). Can be tuple for multiple rings. (only if geometry is 'ring')
   dtheta = spacing between earthquakes in ring, given in degrees. Default = 30.
   '''
    geometry = param_dict['event_geometry']
    nevents = param_dict['nevents']
    depth = param_dict['depth']
    deltamin = param_dict['deltamin']
    deltamax = param_dict['deltamax']
    ringdist = param_dict['ringdist']
    dtheta = param_dict['dtheta']

    lat0 = kwargs.get('lat0', 0.0)
    lon0 = kwargs.get('lon0', 0.0)

    eq_list = []
    n = 1

    if geometry == 'random':
        while len(eq_list) < nevents:
            lon = (2.0 * deltamax * np.random.random(1)) - deltamax
            lat = (2.0 * deltamax * np.random.random(1)) - deltamax
            dist_az = gps2dist_azimuth(lat,
                                       lon,
                                       lat0,
                                       lon0,
                                       a=6371000.0,
                                       f=0.0)
            dist_km = dist_az[0] / 1000.0
            dist_deg = kilometer2degrees(dist_km)

            if dist_deg >= deltamin and dist_deg <= deltamax:
                eq_list.append((n, lon[0], lat[0], depth))
                n += 1

    elif geometry == 'ring':
        theta = np.arange(0, 360, dtheta)
        origin = geopy.Point(0, 0)
        eq_list = []

        if type(ringdist) == int or type(ringdist) == float:
            d_km = ringdist * ((6371.0 * 2 * np.pi) / 360.0)
            for i in range(0, len(theta)):
                bearing = theta[i]
                destination = VincentyDistance(kilometers=d_km).destination(
                    origin, bearing)
                lat = destination[0]
                lon = destination[1]
                eq_list.append((n, lon, lat, depth))
                n += 1

        elif type(ringdist == tuple):
            for r in ringdist:
                d_km = r * ((6371.0 * 2 * np.pi) / 360.0)
                for i in range(0, len(theta)):
                    bearing = theta[i]
                    destination = VincentyDistance(
                        kilometers=d_km).destination(origin, bearing)
                    lat = destination[0]
                    lon = destination[1]
                    eq_list.append((n, lon, lat, depth))
                    n += 1

    np.savetxt('earthquake_list',
               eq_list,
               fmt=['%d', '%5.5f', '%5.5f', '%5.5f'])
    return eq_list
Пример #18
0
def calculate_ray_coverage(earthquake_list,stations_list,depth_range,phase='S',**kwargs):
   '''
   args:
      earthquake_list: earthquakes file (same format as used in synth tomo)
      stations_list: stations file (same format as used in synth tomo)
      depth_range: tuple (mindepth,maxdepth)

   kwargs:
      savefig: True or False
      figname: str, name of figure (defaults to fig.pdf)
      plot_title: str, title at the top of the plot (default no title)
   '''
   #the earthquake list format is: eq num, eq lon, eq lat, eq dep
   #the stations list format is: st lon, st lat
   savefig = kwargs.get('savefig',True)
   fig_name = kwargs.get('fig_name','fig.pdf')
   plot_title = kwargs.get('plot_title','None')
   fout_name = kwargs.get('fout_name','None')
   prem = TauPyModel('prem_50km')

   stations_file = np.loadtxt(stations_list)
   quakes_file = np.loadtxt(earthquake_list)
   n_quakes = len(quakes_file)
   n_stats = len(stations_file)
   st_lons = stations_file[:,0]
   st_lats = stations_file[:,1]
   eq_lons = quakes_file[:,1]
   eq_lats = quakes_file[:,2]
   eq_deps = quakes_file[:,3]

   if phase=='S' or phase=='P':
      delta_min = 30.0
      delta_max = 100.0
   elif phase == 'SKS':
      delta_min = 70.0
      delta_max = 140.0

   m = Basemap(projection='hammer',lon_0=204)
   fout = open(fout_name,'w')

   for i in range(0,n_quakes):
      #print 'working on earthquake', i
      for j in range(0,n_stats):

          geodet = gps2dist_azimuth(eq_lats[i], eq_lons[i], st_lats[j], st_lons[j])
          dist_m = geodet[0]
          dist_deg = kilometer2degrees((dist_m/1000.))

          if dist_deg < delta_min:
             continue
          elif dist_deg > delta_max:
             continue

          az = geodet[1]

          #print 'eq_lat, eq_lon, st_lat, st_lon, dist_deg', eq_lats[i],eq_lons[i],st_lats[j],st_lons[j],dist_deg
          arrs = prem.get_pierce_points(source_depth_in_km=eq_deps[i],
                                        distance_in_degree=dist_deg,
                                        phase_list=[phase])
          #print arrs
          arr = arrs[0]
          pierce_dict = arr.pierce
          #items in pierce_dict: 'p' (slowness), 'time' (time in s), 'dist', (distance in rad), 'depth' (depth in km)


          origin = geopy.Point(eq_lats[i],eq_lons[i])
          bearing = az
          geo_path = []
          cross_pt1 = 0
          cross_pt2 = 0
          dist_max = pierce_dict['dist'][::-1][0]
          for ds in pierce_dict:
             #only add points that are past turning depth
             dist_here = ds[2]
             if dist_here >= dist_max / 2:
                time_here = ds[1]
                depth_here = ds[3]
                if depth_here == depth_range[1]:
                   dist_deg = np.degrees(ds[2])
                   dist_km = dist_deg * ((2*np.pi*6371.0/360.0))
                   geo_pt = VincentyDistance(kilometers=dist_km).destination(origin,bearing)
                   lat_pt = geo_pt[0]
                   lon_pt = geo_pt[1]
                   cross_pt1 = (lon_pt,lat_pt)
                if depth_here == depth_range[0]:
                   dist_deg = np.degrees(ds[2])
                   dist_km = dist_deg * ((2*np.pi*6371.0/360.0))
                   geo_pt = VincentyDistance(kilometers=dist_km).destination(origin,bearing)
                   lat_pt = geo_pt[0]
                   lon_pt = geo_pt[1]
                   cross_pt2 = (lon_pt,lat_pt)
          if cross_pt1 != 0 and cross_pt2 != 0:
             m.drawgreatcircle(cross_pt1[0],cross_pt1[1],cross_pt2[0],cross_pt2[1],linewidth=1,alpha=0.15,color='k')
             fout.write('{} {} {} {}'.format(cross_pt1[0],cross_pt1[1],cross_pt2[0],cross_pt2[1])+'\n')

   m.drawcoastlines()
   m.fillcontinents(color='lightgrey')
   #m.drawparallels(np.arange(-90.,120.,30.))
   #m.drawmeridians(np.arange(0.,360.,60.))
   if plot_title != 'None':
      plt.title(plot_title)

   if savefig:
      plt.savefig(fig_name)
      plt.clf()
   else:
      plt.show()
Пример #19
0
def vespagram(stream, ev, inv, method, frqlow, frqhigh, baz, scale, nthroot=4,
              filter=True, static3D=False, vel_corr=4.8, sl=(0.0, 10.0, 0.5),
              align=False, align_phase=['P', 'Pdiff'], plot_trace=True):
    """
    vespagram wrapper routine for MESS 2014.

    :param stream: Waveforms for the array processing.
    :type stream: :class:`obspy.core.stream.Stream`
    :param inventory: Station metadata for waveforms
    :type inventory: :class:`obspy.station.inventory.Inventory`
    :param method: Method used for the array analysis
        (one of "DLS": Delay and Sum, "PWS": Phase Weighted Stack).
    :type method: str
    :param frqlow: Low corner of frequency range for array analysis
    :type frqlow: float
    :param frqhigh: High corner of frequency range for array analysis
    :type frqhigh: float
    :param baz: pre-defined (theoretical or calculated) backazimuth used for calculation
    :type baz_plot: float
    :param scale: scale for plotting
    :type scale: float
    :param nthroot: estimating the nthroot for calculation of the beam
    :type nthroot: int
    :param filter: Whether to bandpass data to selected frequency range
    :type filter: bool
    :param static3D: static correction of topography using `vel_corr` as
        velocity (slow!)
    :type static3D: bool
    :param vel_corr: Correction velocity for static topography correction in
        km/s.
    :type vel_corr: float
    :param sl: Min/Max and stepwidthslowness for analysis
    :type sl: (float, float,float)
    :param align: whether to align the vespagram to a certain phase
    :type align: bool
    :param align_phase: phase to be aligned with (might be a list if simulateneous arivials are expected (P,PcP,Pdif)
    :type align: str
    :param plot_trace: if True plot the vespagram as wiggle plot, if False as density map
    :type align: bool
    """

    starttime = max([tr.stats.starttime for tr in stream])
    endtime = min([tr.stats.endtime for tr in stream])
    stream.trim(starttime, endtime)

    org = ev.preferred_origin() or ev.origins[0]
    ev_lat = org.latitude
    ev_lon = org.longitude
    ev_depth = org.depth/1000.  # in km
    ev_otime = org.time

    sll, slm, sls = sl
    sll /= KM_PER_DEG
    slm /= KM_PER_DEG
    sls /= KM_PER_DEG
    center_lon = 0.
    center_lat = 0.
    center_elv = 0.
    seismo = stream
    seismo.attach_response(inv)
    seismo.merge()
    sz = Stream()
    i = 0
    for tr in seismo:
        for station in inv[0].stations:
            if tr.stats.station == station.code:
                tr.stats.coordinates = \
                    AttribDict({'latitude': station.latitude,
                                'longitude': station.longitude,
                                'elevation': station.elevation})
                center_lon += station.longitude
                center_lat += station.latitude
                center_elv += station.elevation
                i += 1
        sz.append(tr)

    center_lon /= float(i)
    center_lat /= float(i)
    center_elv /= float(i)

    starttime = max([tr.stats.starttime for tr in stream])
    stt = starttime
    endtime = min([tr.stats.endtime for tr in stream])
    e = endtime
    stream.trim(starttime, endtime)

    #nut = 0
    max_amp = 0.
    sz.trim(stt, e)
    sz.detrend('simple')

    print sz
    fl, fh = frqlow, frqhigh
    if filter:
        sz.filter('bandpass', freqmin=fl, freqmax=fh, zerophase=True)

    if align:
        deg = []
        shift = []
        res = gps2DistAzimuth(center_lat, center_lon, ev_lat, ev_lon)
        deg.append(kilometer2degrees(res[0]/1000.))
        tt = getTravelTimes(deg[0], ev_depth, model='ak135')
        for item in tt:
            phase = item['phase_name']
            if phase in align_phase:
                try:
                    travel = item['time']
                    travel = ev_otime.timestamp + travel
                    dtime = travel - stt.timestamp
                    shift.append(dtime)
                except:
                    break
        for i, tr in enumerate(sz):
            res = gps2DistAzimuth(tr.stats.coordinates['latitude'],
                                  tr.stats.coordinates['longitude'],
                                  ev_lat, ev_lon)
            deg.append(kilometer2degrees(res[0]/1000.))
            tt = getTravelTimes(deg[i+1], ev_depth, model='ak135')
            for item in tt:
                phase = item['phase_name']
                if phase in align_phase:
                    try:
                        travel = item['time']
                        travel = ev_otime.timestamp + travel
                        dtime = travel - stt.timestamp
                        shift.append(dtime)
                    except:
                        break
        shift = np.asarray(shift)
        shift -= shift[0]
        AA.shifttrace_freq(sz, -shift)

    baz += 180.
    nbeam = int((slm - sll)/sls + 0.5) + 1
    kwargs = dict(
        # slowness grid: X min, X max, Y min, Y max, Slow Step
        sll=sll, slm=slm, sls=sls, baz=baz, stime=stt, method=method,
        nthroot=nthroot, etime=e, correct_3dplane=False, static_3D=static3D,
        vel_cor=vel_corr)

    start = UTCDateTime()
    slow, beams, max_beam, beam_max = AA.vespagram_baz(sz, **kwargs)
    print "Total time in routine: %f\n" % (UTCDateTime() - start)

    df = sz[0].stats.sampling_rate
    # Plot the seismograms
    npts = len(beams[0])
    print npts
    T = np.arange(0, npts/df, 1/df)
    sll *= KM_PER_DEG
    slm *= KM_PER_DEG
    sls *= KM_PER_DEG
    slow = np.arange(sll, slm, sls)
    max_amp = np.max(beams[:, :])
    #min_amp = np.min(beams[:, :])
    scale *= sls

    fig = plt.figure(figsize=(12, 8))

    if plot_trace:
        ax1 = fig.add_axes([0.1, 0.1, 0.85, 0.85])
        for i in xrange(nbeam):
            if i == max_beam:
                ax1.plot(T, sll + scale*beams[i]/max_amp + i*sls, 'r',
                         zorder=1)
            else:
                ax1.plot(T, sll + scale*beams[i]/max_amp + i*sls, 'k',
                         zorder=-1)
        ax1.set_xlabel('Time [s]')
        ax1.set_ylabel('slowness [s/deg]')
        ax1.set_xlim(T[0], T[-1])
        data_minmax = ax1.yaxis.get_data_interval()
        minmax = [min(slow[0], data_minmax[0]), max(slow[-1], data_minmax[1])]
        ax1.set_ylim(*minmax)
    #####
    else:
        #step = (max_amp - min_amp)/100.
        #level = np.arange(min_amp, max_amp, step)
        #beams = beams.transpose()
        #cmap = cm.hot_r
        cmap = cm.rainbow

        ax1 = fig.add_axes([0.1, 0.1, 0.85, 0.85])
        #ax1.contour(slow,T,beams,level)
        #extent = (slow[0], slow[-1], \
        #               T[0], T[-1])
        extent = (T[0], T[-1], slow[0] - sls * 0.5, slow[-1] + sls * 0.5)

        ax1.set_ylabel('slowness [s/deg]')
        ax1.set_xlabel('T [s]')
        beams = np.flipud(beams)
        ax1.imshow(beams, cmap=cmap, interpolation="nearest",
                   extent=extent, aspect='auto')

    ####
    result = "BAZ: %.2f Time %s" % (baz-180., stt)
    ax1.set_title(result)

    plt.show()
    return slow, beams, max_beam, beam_max
Пример #20
0
def write_input(eq_lat,eq_lon,eq_dep,ievt,stations,phase,delays_file,Tmin,taup_model,filename,raytheory=False,tt_from_raydata=True,**kwargs):
   '''
   write an input file for globalseis finite frequency tomography software.
   each earthquake and datatype (P,S,etc...) has it's own input file

   args--------------------------------------------------------------------------
   eq_lat: earthquake latitude (deg)
   eq_lon: earthquake longitude (deg)
   eq_dep: earthquake depth (km)
   stations: stations array (lons,lats)
   delays_file: h5py datafile containing cross correlation delay times
   Tmin: minimum period at which cross correlation measurements were made
   taup_model: name of TauPyModel used to calculate 1D travel times
   filename:
   raytheory: True or False
   tt_from_raydata: If True, writes cross correlation times to 'xcor*', which 
                    will then be added to 1D travel times from raydata

   kwargs------------------------------------------------------------------------
   plot_figure: plot a figure showing source receiver geometry and delay map
   t_sig: estimated standard error in cross correlation measurement.
   add_noise: add gaussian noise to traveltime measurements of magnitude t_sig
   fake_SKS_header: test the SKS header
   '''
   #define variables used in finite frequency tomography (kwargs)----------------
   idate = kwargs.get('idate','15001') #event date YYDDD where DDD is between 1 and 365
   iotime =  kwargs.get('iotime','010101') #vent origin time (HHMMSS)
   kluster = kwargs.get('kluster','0') #0 if no clustering used
   stationcode = kwargs.get('stationcode','XXXX') #station code (no more than 16 chars)
   netw = kwargs.get('netw','PLUMENET ') #network code
   nobst = kwargs.get('nobst','1') #number of travel time measurements
   nobsa = kwargs.get('nobsa','0') #number of amplitude measurements
   kpole = kwargs.get('kpole','0') #number of polar crossings (0 for P and S)
   sampling_rate = kwargs.get('sampling_rate',10.0)
   n_bands = kwargs.get('n_bands',1) # spectral bands used (TODO setup more than one)
   kunit = kwargs.get('kunit',1) #unit of noise (1 = nm)
   rms0 = kwargs.get('rms0',0) #don't know what this is
   plot_figure = kwargs.get('plot_figure',False)
   dist_min = kwargs.get('dist_min',30.0)
   dist_max = kwargs.get('dist_max',90.0)
   t_sig = kwargs.get('t_sig',0.0)
   add_noise = kwargs.get('add_noise',False)
   fake_SKS_header = kwargs.get('fake_SKS_header',False)
   filter_type = kwargs.get('filter_type','none')

   ievt=int(ievt) #double check ievt is an integer (in case it was read from a file)

   debug = False

   #create taup model------------------------------------------------------------
   tt_model = TauPyModel(taup_model)

   #get filter parameters--------------------------------------------------------
   print 'Tmin = ', Tmin
   omega_list = []
   amp_list = []
   for T0 in Tmin:
      filter_type, freqmin,freqmax, window = get_filter_params(delays_file,phase,T0,filter_type=filter_type)
      omega,amp =  get_filter_freqs(filter_type,freqmin,freqmax,sampling_rate)
      omega_list.append(omega)
      amp_list.append(amp)

   window_len = window[1] - window[0]

   #write header-----------------------------------------------------------------
   f = open(filename,'w')
   f.write('{}'.format(filename)+'\n')
   f.write('{}'.format('None'+'\n'))
   fdelays = open('xcor_{}'.format(filename),'w')

   #ray information--------------------------------------------------------------
   if phase == 'P':
      gm_component = 'BHZ ' #ground motion component
      f.write('P'+'\n')
      f.write('P'+'\n')
      f.write('6371 1 1'+'\n')
      f.write('3482 2 1'+'\n')
      f.write('6371 5 0'+'\n')
   elif phase == 'S' and fake_SKS_header == False:
      gm_component = 'BHT ' #ground motion component
      f.write('S'+'\n')
      f.write('S'+'\n')
      f.write('6371 1 2'+'\n')
      f.write('3482 2 2'+'\n')
      f.write('6371 5 0'+'\n')
   elif phase == 'SKS' or fake_SKS_header == True:
      gm_component = 'BHR ' #ground motion component
      f.write('SKS'+'\n')
      f.write('SKS'+'\n')
      f.write('6371 1 2'+'\n')
      f.write('3482 4 1'+'\n')
      f.write('1217.1 2 1'+'\n')
      f.write('3482 4 2'+'\n')
      f.write('6371 5 0'+'\n')

   #this is hardwired for now (based on range of rays found with ray tracing software)
   if phase == 'P':
      dist_min = 30.0
      #dist_max = 98.3859100
      dist_max = 97.0
   elif phase == 'S':
      dist_min = 30.0
      #dist_max = 99.0557175
      dist_max = 97.0
   elif phase == 'SKS':
      #dist_min = 66.0320663
      #dist_max = 144.349365
      dist_min = 68.0
      dist_max = 142.0

   #write spectral band information-----------------------------------------------
   if raytheory:
      n_bands=0
      f.write('{}'.format(n_bands)+'\n')
   else:
      f.write('{}'.format(n_bands)+'\n')

      for i in range(0,n_bands):
         f.write('{}'.format(len(omega_list[i]))+'\n')
         for j in range(0,len(omega)): 
            f.write('{} {}'.format(omega_list[i][j],amp_list[i][j])+'\n')

   #event delay map--------------------------------------------------------------
   #lats_i = np.arange(-30.0,30.0,0.1)
   #lons_i = np.arange(-30.0,30.0,0.1)
   lats_i = np.arange(-45.0,45.0,0.1)
   lons_i = np.arange(-45.0,45.0,0.1)

   event_maps = []
   station_delays_list = []

   if plot_figure:
      event_map,figure_axis = make_event_delay_map(eq_lat,eq_lon,phase,delays_file,Tmin,lats_i=lats_i,lons_i=lons_i,plot=True,return_axis=False,nevent=ievt)
   else:
      if debug:
         print 'func:write_input- making event delay map for', phase
         #print 'eq_lat,eq_lon,phase,Tmin lats_i,lons_i',eq_lat,eq_lon,phase,Tmin,lats_i,lons_i
      for i in range(0,n_bands):
         event_map = make_event_delay_map(eq_lat,eq_lon,phase,delays_file,Tmin[i],lats_i=lats_i,                                          lons_i=lons_i,return_axis=False,plot=True,nevent=ievt)
         event_maps.append(event_map)

   #find delays at stations------------------------------------------------------
   if plot_figure:
      station_delays = get_station_delays(event_map,stations,lats_i,lons_i,pass_figure_axis=True,figure_axis=figure_axis)
   else: 
      for i in range(0,n_bands):
         station_delays = get_station_delays(event_maps[i],stations,lats_i,lons_i)
         station_delays_list.append(station_delays)

   #add noise (optional)---------------------------------------------------------
   if t_sig != 0:
      noise = np.random.normal(0,t_sig,len(station_delays))
      if add_noise:
         for i in range(0,len(station_delays_list)):
            station_delays_list[i] += noise

   station_lons = stations[0,:]
   station_lats = stations[1,:]
   n_stations = len(station_lats)
   station_elevation = 0.0

   for i in range(0,n_stations):
      dist_deg, rotation_angle = get_event_params(eq_lat,eq_lon)
      #find event distance
      event_distaz = gps2dist_azimuth(eq_lat,eq_lon,station_lats[i],station_lons[i],a=6371000.0,f=0.0)
      event_dist_deg = kilometer2degrees((event_distaz[0]/1000.0)) 

      #skip station if too close or too far from source
      if event_dist_deg <= dist_min or event_dist_deg >= dist_max:
         continue

      #get ray theoretical travel time 
      #if phase == 'S':
      #   phase_list = ['s','S','Sdiff']
      #elif phase == 'P':
      #   phase_list = ['p','P','Pdiff']

      ray_theory_arr = tt_model.get_travel_times(eq_dep,event_dist_deg,phase_list=[phase])

      ### TRY TO GET TRAVEL TIME IN CORE #########################################################
      ray_theory_path = tt_model.get_ray_paths(eq_dep,event_dist_deg,phase_list=[phase])
      phase_path = ray_theory_path[0]
      path_time = phase_path.path['time']
      path_dt = np.diff(path_time)
      path_depth = phase_path.path['depth']
      time_in_core = 0
      for p_i in range(0,len(path_dt)):
         if path_depth[p_i] >= 2889.0:
            time_in_core += path_dt[p_i] 
      ############################################################################################
      if debug:
	 print '_________________________________________________________________________________'
         print 'arrivals from taup_get_travel_time for event parameters [depth,delta(deg),phase]:'
	 print '[{},{},{}]'.format(eq_dep,event_dist_deg,phase),ray_theory_arr
	 print 'time in core: ', time_in_core
	 print '_________________________________________________________________________________'

      if debug:
          print 'distance, phase, raytheory travel time, observed delay:', event_dist_deg,phase,ray_theory_travel_time,delay_time
          print 'the travel time observation is ', tobs

         #fdelays.write('{}'.format(delay_time)+'\n')

      if raytheory:
         n_bands = 0
         nbt = 0 #spectral band number (must be 0 if ray theory)
         window_len = 0
         kunit = 0
         corcoeft=0
      else:
            nbt = 1 #spectral band number

      #write line 1 (header - doesn't repeat for each spectral band)----------------
      f.write('{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}'.format(idate,
              iotime,ievt,kluster,stationcode,netw,gm_component,eq_lat,eq_lon,eq_dep,
              station_lats[i],station_lons[i],station_elevation,nobst,nobsa,kpole)+'\n')



      #write line 2--------------------------------------------------------------
      f.write('{} {} '.format(kunit,rms0))
      for j in range(0,n_bands):
         f.write('0 ')   #used to be 0.0 
         f.write('\n')

      #write line 3---------------------------------------------------------------
      if raytheory:
         f.write('{}'.format(1)+'\n')
      else:
         f.write('{}'.format(n_bands)+'\n')
      
      #write line 4---------------------------------------------------------------

      #find delays for each band
      for j in range(0,n_bands):
         ray_theory_travel_time = ray_theory_arr[0].time
         delay_time = station_delays_list[j][i] 
         tobs = ray_theory_travel_time - delay_time
         corcoeft = 1.0 # cross correlation coefficient 
         nbt = j+1
         f.write('{} {} {} {} {} {} {}'.format(tobs,t_sig,corcoeft,nbt,window_len,time_in_core,'#tobs,tsig,corcoeft,nbt,window,tincore')+'\n') 

      #write line 5--------------------------------------------------------------
      f.write('{}'.format(0)+'\n') # no amplitude info?
Пример #21
0
    def _metadata_handler(self):
        sel_indices = self.index_datasource.metadata.get("selections", [])
        if len(sel_indices) != 0:
            self.index_datasource.metadata.clear()
            # ~ print sel_indices[0]
            # ~ print self.entries[sel_indices[0]]
            edate, etime, elat, elon, edep, eunit, estatus = self.entries[sel_indices[0]]["summary"].split()
            elat = float(elat)
            elon = float(elon)
            edep = float(edep)

            ex, ey = self.toxy(elon, elat)
            greats = self.great(elon, elat)

            for i, great in enumerate(greats):
                lons, lats = great
                x, y = self.toxy(lons, lats)
                self.plotData.set_data("EQX%i" % i, x)
                self.plotData.set_data("EQY%i" % i, y)
                self.backImg.plot(("EQX%i" % i, "EQY%i" % i), type="line", color="red", linewidth=5.0)
            if len(greats) == 1:
                self.plotData.set_data("EQX1", [])
                self.plotData.set_data("EQY1", [])
                self.backImg.plot(("EQX1", "EQY1"), type="line", color="red", linewidth=5.0)

            # lon_ij, lat_ij =  [(114 + 14.0/60.0 + 22.19/3600.0) , -( 8.0 + 3.0/60. + 43.92/3600.0)]
            lon_ij, lat_ij = [(-46.61), -(23.50)]  # Sao Paulo
            ijx, ijy = self.toxy(lon_ij, lat_ij)

            delta = gps2DistAzimuth(elat, elon, lat_ij, lon_ij)[0]
            delta = kilometer2degrees(delta / 1000.0)
            tt = getTravelTimes(delta, edep, model="iasp91")
            text = "FIRST ARRIVAL\n"
            first = tt[0]
            text += "%s: %.1f\n" % (first["phase_name"], first["time"])

            arriv = datetime.datetime.strptime("%s %s" % (edate, etime), "%Y-%m-%d %H:%M:%S") + datetime.timedelta(
                seconds=int(first["time"])
            )
            text += "UTC: %s\n" % arriv
            text += "WIB: %s" % (arriv + datetime.timedelta(hours=-3))

            f = Font(size=16)
            del self.backImg.overlays[:]

            label1 = DataLabel(
                component=self.backImg,
                data_point=(ijx, ijy),
                label_text=text,
                show_label_coords=False,
                text_color="red",
                font=f,
                label_position="bottom right",
                border_visible=False,
                bgcolor="white",
                marker_color="blue",
                marker_line_color="transparent",
                marker="diamond",
                arrow_visible=False,
            )
            self.backImg.overlays.append(label1)

            event = self.entries[sel_indices[0]]["title"] + "\n"
            event += "%s %s" % (edate, etime)

            label2 = DataLabel(
                component=self.backImg,
                data_point=(ex, ey),
                label_text=event,
                show_label_coords=False,
                text_color="red",
                font=f,
                label_position="bottom right",
                border_visible=False,
                bgcolor="white",
                marker_color="blue",
                marker_line_color="transparent",
                marker="diamond",
                arrow_visible=False,
            )
            self.backImg.overlays.append(label2)
Пример #22
0
def make_earthquake_list(param_dict,**kwargs):
   '''
   Generate earthquakes to be used in tomographic inversion. Earthquake locations can 
   be generated randomly within the distance range (deltamin, deltamax), or alternatively
   a ring of earthquakes at a fixed distance from the point (0,0) can be generated.
   In the futures, events may be given as an obspy event catalog.

   args--------------------------------------------------------------------------
   param_dict: parameter dictionary (read from file 'inparam_tomo')
   
   kwargs------------------------------------------------------------------------
   nevents: number of earthquakes (only use if geometry is 'random')
   deltamin = minimum earthquake distance from (0,0) (only if geometry is 'random')
   deltamax = maximum earthquake distance from (0,0) (only if geometry is 'random')
   ringdist = distance of ring from (0,0). Can be tuple for multiple rings. (only if geometry is 'ring')
   dtheta = spacing between earthquakes in ring, given in degrees. Default = 30.
   '''
   geometry = param_dict['event_geometry']
   nevents = param_dict['nevents']
   depth = param_dict['depth']
   deltamin = param_dict['deltamin']
   deltamax = param_dict['deltamax']
   ringdist = param_dict['ringdist']
   dtheta = param_dict['dtheta']

   lat0 = kwargs.get('lat0',0.0)
   lon0 = kwargs.get('lon0',0.0)

   eq_list = []
   n = 1

   if geometry=='random':
      while len(eq_list) < nevents:
         lon = (2.0*deltamax*np.random.random(1)) - deltamax
         lat = (2.0*deltamax*np.random.random(1)) - deltamax
         dist_az = gps2dist_azimuth(lat,lon,lat0,lon0,a=6371000.0,f=0.0)
         dist_km = dist_az[0]/1000.0
         dist_deg = kilometer2degrees(dist_km)

         if dist_deg >= deltamin and dist_deg <= deltamax:
            eq_list.append((n,lon[0],lat[0],depth))
            n += 1

   elif geometry=='ring':
      theta = np.arange(0,360,dtheta)
      origin = geopy.Point(0,0)
      eq_list = []

      if type(ringdist)==int or type(ringdist)==float:
         d_km = ringdist * ((6371.0*2*np.pi)/360.0)
         for i in range(0,len(theta)):
            bearing = theta[i] 
            destination = VincentyDistance(kilometers=d_km).destination(origin,bearing)
            lat = destination[0]
            lon = destination[1]
            eq_list.append((n,lon,lat,depth))
            n += 1

      elif type(ringdist==tuple):
         for r in ringdist:
            d_km = r * ((6371.0*2*np.pi)/360.0)
            for i in range(0,len(theta)):
               bearing = theta[i] 
               destination = VincentyDistance(kilometers=d_km).destination(origin,bearing)
               lat = destination[0]
               lon = destination[1]
               eq_list.append((n,lon,lat,depth))
               n += 1

   np.savetxt('earthquake_list',eq_list,fmt=['%d','%5.5f','%5.5f','%5.5f'])
   return eq_list
Пример #23
0
    def processing(self):
        from telef import *
        from obspy.core.util.geodetics import gps2DistAzimuth, kilometer2degrees
        from obspy.taup.taup import getTravelTimes
        
        
        filename_out, ok = QtGui.QInputDialog.getText(QtGui.QWidget(),"Arquivo de saida", "Entre com o nome: ")
        
        output = open(filename_out,'w')
        oheader1 = ['Estacao', 'Dia', 'H.Chegada', 'H. Origem','Latitude', ' Longitude', 'H', '    Mag', 'Tipo','Dist. Az.', 'Residuo','Regiao'.ljust(30)]
        oheader2 = ['       ','   ', ' hh:mm:ss ','hh:mm:ss ', ' (graus)', ' (graus) ', ' km', '   ','    ','    (graus)', '  (s)  ','      ' ] 
        output.write(self.lines_obsis[0][1:6])
        output.write('\n\n\n')        
            
        line=oheader1
        output.write('%7s %2s %7s %6s %6s %7s %3s %4s %2s %4s %3s %6s\n'%(line[0],line[1],line[2],line[3],line[4],line[5],line[6],
                                                                   line[7],line[8],line[9],line[10],line[11]))
        line=oheader2
        output.write('%7s %2s %7s %6s %6s %7s %3s %4s %2s %4s %3s %6s\n'%(line[0],line[1],line[2],line[3],line[4],line[5],line[6],
                                                                   line[7],line[8],line[9],line[10],line[11]))
        output.write('\n')
        
        cnt=0; lres=[]; lcnt=[]; elats=[]; elons=[]; emags=[]
        stlats=[]; stlons=[]; edeps=[]
        
        lines_usgs = open(self.filename_usgs, 'r').readlines()       
        
        for line_obsis in self.lines_obsis[1:]:
            hdr_obsis=self.lines_obsis[0]
            iOBSIS = getObSis(line_obsis,hdr_obsis)
            coords = getCoord(self.filename_coord, iOBSIS[0])
            stlats.append(coords[0])
            stlons.append(coords[1])

            for line in lines_usgs[1:]:
                l = line.split(',')
                otime = UTCDateTime(l[0])
                ootime = l[0]
                if otime < iOBSIS[6]:
                    elat = float(l[1])
                    elon = float(l[2])
                    if l[3] == "": 
                        dep = 0.0
                    else:
                        dep = float(l[3])
                    mag = float(l[4])                            
                    magType = l[5]
                    net = l[10]
                    elats.append(elat)
                    elons.append(elon)
                    emags.append(mag)
                    edeps.append(dep)
                    place = [l[13],l[14]]
                    delta = gps2DistAzimuth(elat,elon,coords[0],coords[1])[0]
                    delta = kilometer2degrees(delta/1000.)
                    tt = getTravelTimes(delta, dep, model='iasp91')
                    text = "FIRST ARRIVAL\n"
                    first = tt[0]
                    if first['phase_name'] == 'P':
                        text += "%s: %.1f\n" % (first['phase_name'],first['time'])
                        arriv = UTCDateTime(otime) + first['time']
                        res = arriv-iOBSIS[6]
                        cnt += 1
                        lcnt.append(cnt)
                        lres.append(res)
                        hc=str(iOBSIS[2]).zfill(2)+':'+str(iOBSIS[3]).zfill(2)+':'+str(iOBSIS[4]).zfill(2)
                        ho=str(otime.time)
                        delta=str(delta)
                        res=str(res)
                        final = [iOBSIS[0],str(iOBSIS[1]).zfill(2),hc,ho[:10].zfill(8),str(elat).zfill(8),str(elon).zfill(9),str(dep).ljust(6),str(mag).ljust(3),str(magType).ljust(3),str(delta)[:5],res[:8].ljust(8),str(place).ljust(50)]
                        line=final
                        output.write('%7s %2s %7s %6s %6s %7s %3s %4s %2s %4s %3s %6s\n'%(line[0],line[1],line[2],line[3],line[4],line[5],line[6],line[7],line[8],line[9],line[10],line[11]))
                        temp = [elat, elon, mag, str(iOBSIS[0]), coords[0], coords[1]]
                       
                    break
                    
        output.close()
         
        ares = np.array(lres)
        acnt = np.array(lcnt)
        graphics2.scatter(acnt,ares)
        
        if self.mapfull.checkState()  == QtCore.Qt.Checked:
            graphics2.plt_map_marble(elats,elons,emags,edeps,stlats,stlons)
        else:
            graphics2.plt_map(elats,elons,emags,edeps,stlats,stlons)
Пример #24
0
    def processing(self):
        from telef import *
        from obspy.core.util.geodetics import gps2DistAzimuth, kilometer2degrees
        from obspy.taup.taup import getTravelTimes

        filename_out, ok = QtGui.QInputDialog.getText(QtGui.QWidget(),
                                                      "Arquivo de saida",
                                                      "Entre com o nome: ")

        output = open(filename_out, 'w')
        oheader1 = [
            'Estacao', 'Dia', 'H.Chegada', 'H. Origem', 'Latitude',
            ' Longitude', 'H', '    Mag', 'Tipo', 'Dist. Az.', 'Residuo',
            'Regiao'.ljust(30)
        ]
        oheader2 = [
            '       ', '   ', ' hh:mm:ss ', 'hh:mm:ss ', ' (graus)',
            ' (graus) ', ' km', '   ', '    ', '    (graus)', '  (s)  ',
            '      '
        ]
        output.write(self.lines_obsis[0][1:6])
        output.write('\n\n\n')

        line = oheader1
        output.write('%7s %2s %7s %6s %6s %7s %3s %4s %2s %4s %3s %6s\n' %
                     (line[0], line[1], line[2], line[3], line[4], line[5],
                      line[6], line[7], line[8], line[9], line[10], line[11]))
        line = oheader2
        output.write('%7s %2s %7s %6s %6s %7s %3s %4s %2s %4s %3s %6s\n' %
                     (line[0], line[1], line[2], line[3], line[4], line[5],
                      line[6], line[7], line[8], line[9], line[10], line[11]))
        output.write('\n')

        cnt = 0
        lres = []
        lcnt = []
        elats = []
        elons = []
        emags = []
        stlats = []
        stlons = []
        edeps = []

        lines_usgs = open(self.filename_usgs, 'r').readlines()

        for line_obsis in self.lines_obsis[1:]:
            hdr_obsis = self.lines_obsis[0]
            iOBSIS = getObSis(line_obsis, hdr_obsis)
            coords = getCoord(self.filename_coord, iOBSIS[0])
            stlats.append(coords[0])
            stlons.append(coords[1])

            for line in lines_usgs[1:]:
                l = line.split(',')
                otime = UTCDateTime(l[0])
                ootime = l[0]
                if otime < iOBSIS[6]:
                    elat = float(l[1])
                    elon = float(l[2])
                    if l[3] == "":
                        dep = 0.0
                    else:
                        dep = float(l[3])
                    mag = float(l[4])
                    magType = l[5]
                    net = l[10]
                    elats.append(elat)
                    elons.append(elon)
                    emags.append(mag)
                    edeps.append(dep)
                    place = [l[13], l[14]]
                    delta = gps2DistAzimuth(elat, elon, coords[0],
                                            coords[1])[0]
                    delta = kilometer2degrees(delta / 1000.)
                    tt = getTravelTimes(delta, dep, model='iasp91')
                    text = "FIRST ARRIVAL\n"
                    first = tt[0]
                    if first['phase_name'] == 'P':
                        text += "%s: %.1f\n" % (first['phase_name'],
                                                first['time'])
                        arriv = UTCDateTime(otime) + first['time']
                        res = arriv - iOBSIS[6]
                        cnt += 1
                        lcnt.append(cnt)
                        lres.append(res)
                        hc = str(iOBSIS[2]).zfill(2) + ':' + str(
                            iOBSIS[3]).zfill(2) + ':' + str(iOBSIS[4]).zfill(2)
                        ho = str(otime.time)
                        delta = str(delta)
                        res = str(res)
                        final = [
                            iOBSIS[0],
                            str(iOBSIS[1]).zfill(2), hc, ho[:10].zfill(8),
                            str(elat).zfill(8),
                            str(elon).zfill(9),
                            str(dep).ljust(6),
                            str(mag).ljust(3),
                            str(magType).ljust(3),
                            str(delta)[:5], res[:8].ljust(8),
                            str(place).ljust(50)
                        ]
                        line = final
                        output.write(
                            '%7s %2s %7s %6s %6s %7s %3s %4s %2s %4s %3s %6s\n'
                            % (line[0], line[1], line[2], line[3], line[4],
                               line[5], line[6], line[7], line[8], line[9],
                               line[10], line[11]))
                        temp = [
                            elat, elon, mag,
                            str(iOBSIS[0]), coords[0], coords[1]
                        ]

                    break

        output.close()

        ares = np.array(lres)
        acnt = np.array(lcnt)
        graphics2.scatter(acnt, ares)

        if self.mapfull.checkState() == QtCore.Qt.Checked:
            graphics2.plt_map_marble(elats, elons, emags, edeps, stlats,
                                     stlons)
        else:
            graphics2.plt_map(elats, elons, emags, edeps, stlats, stlons)
Пример #25
0
def write_input(eq_lat,
                eq_lon,
                eq_dep,
                ievt,
                stations,
                phase,
                delays_file,
                Tmin,
                taup_model,
                filename,
                raytheory=False,
                tt_from_raydata=True,
                **kwargs):
    '''
   write an input file for globalseis finite frequency tomography software.
   each earthquake and datatype (P,S,etc...) has it's own input file

   args--------------------------------------------------------------------------
   eq_lat: earthquake latitude (deg)
   eq_lon: earthquake longitude (deg)
   eq_dep: earthquake depth (km)
   stations: stations array (lons,lats)
   delays_file: h5py datafile containing cross correlation delay times
   Tmin: minimum period at which cross correlation measurements were made
   taup_model: name of TauPyModel used to calculate 1D travel times
   filename:
   raytheory: True or False
   tt_from_raydata: If True, writes cross correlation times to 'xcor*', which 
                    will then be added to 1D travel times from raydata

   kwargs------------------------------------------------------------------------
   plot_figure: plot a figure showing source receiver geometry and delay map
   t_sig: estimated standard error in cross correlation measurement.
   add_noise: add gaussian noise to traveltime measurements of magnitude t_sig
   fake_SKS_header: test the SKS header
   '''
    #define variables used in finite frequency tomography (kwargs)----------------
    idate = kwargs.get(
        'idate', '15001')  #event date YYDDD where DDD is between 1 and 365
    iotime = kwargs.get('iotime', '010101')  #vent origin time (HHMMSS)
    kluster = kwargs.get('kluster', '0')  #0 if no clustering used
    stationcode = kwargs.get('stationcode',
                             'XXXX')  #station code (no more than 16 chars)
    netw = kwargs.get('netw', 'PLUMENET ')  #network code
    nobst = kwargs.get('nobst', '1')  #number of travel time measurements
    nobsa = kwargs.get('nobsa', '0')  #number of amplitude measurements
    kpole = kwargs.get('kpole',
                       '0')  #number of polar crossings (0 for P and S)
    sampling_rate = kwargs.get('sampling_rate', 20.0)
    n_bands = kwargs.get('n_bands',
                         1)  # spectral bands used (TODO setup more than one)
    kunit = kwargs.get('kunit', 1)  #unit of noise (1 = nm)
    rms0 = kwargs.get('rms0', 0)  #don't know what this is
    plot_figure = kwargs.get('plot_figure', False)
    dist_min = kwargs.get('dist_min', 30.0)
    dist_max = kwargs.get('dist_max', 90.0)
    t_sig = kwargs.get('t_sig', 0.0)
    add_noise = kwargs.get('add_noise', False)
    fake_SKS_header = kwargs.get('fake_SKS_header', False)

    ievt = int(
        ievt
    )  #double check ievt is an integer (in case it was read from a file)

    debug = False

    #create taup model------------------------------------------------------------
    tt_model = TauPyModel(taup_model)

    #get filter parameters--------------------------------------------------------
    print 'Tmin = ', Tmin
    filter_type, freqmin, freqmax, window = get_filter_params(
        delays_file, phase, Tmin)
    omega, amp = get_filter_freqs(filter_type, freqmin, freqmax, sampling_rate)
    window_len = window[1] - window[0]

    #write header-----------------------------------------------------------------
    f = open(filename, 'w')
    f.write('{}'.format(filename) + '\n')
    f.write('{}'.format('None' + '\n'))
    fdelays = open('xcor_{}'.format(filename), 'w')

    #ray information--------------------------------------------------------------
    if phase == 'P':
        gm_component = 'BHZ '  #ground motion component
        f.write('P' + '\n')
        f.write('P' + '\n')
        f.write('6371 1 1' + '\n')
        f.write('3482 2 1' + '\n')
        f.write('6371 5 0' + '\n')
    elif phase == 'S' and fake_SKS_header == False:
        gm_component = 'BHT '  #ground motion component
        f.write('S' + '\n')
        f.write('S' + '\n')
        f.write('6371 1 2' + '\n')
        f.write('3482 2 2' + '\n')
        f.write('6371 5 0' + '\n')
    elif phase == 'SKS' or fake_SKS_header == True:
        gm_component = 'BHR '  #ground motion component
        f.write('SKS' + '\n')
        f.write('SKS' + '\n')
        f.write('6371 1 2' + '\n')
        f.write('3482 4 1' + '\n')
        f.write('1217.1 2 1' + '\n')
        f.write('3482 4 2' + '\n')
        f.write('6371 5 0' + '\n')

    #this is hardwired for now (based on range of rays found with ray tracing software)
    #TODO make distance range more adaptable
    if phase == 'P':
        dist_min = 30.0
        #dist_max = 98.3859100
        dist_max = 97.0
    elif phase == 'S':
        dist_min = 30.0
        #dist_max = 99.0557175
        dist_max = 97.0
    elif phase == 'SKS':
        #dist_min = 66.0320663
        #dist_max = 144.349365
        dist_min = 68.0
        dist_max = 142.0

    #write spectral band information-----------------------------------------------
    if raytheory:
        n_bands = 0
        f.write('{}'.format(n_bands) + '\n')
    else:
        f.write('{}'.format(n_bands) + '\n')
        f.write('{}'.format(len(omega)) + '\n')
        for i in range(0, len(omega)):
            f.write('{} {}'.format(omega[i], amp[i]) + '\n')

    #event delay map--------------------------------------------------------------
    #lats_i = np.arange(-30.0,30.0,0.1)
    #lons_i = np.arange(-30.0,30.0,0.1)
    lats_i = np.arange(-45.0, 45.0, 0.1)
    lons_i = np.arange(-45.0, 45.0, 0.1)

    if plot_figure:
        event_map, figure_axis = make_event_delay_map(eq_lat,
                                                      eq_lon,
                                                      phase,
                                                      delays_file,
                                                      Tmin,
                                                      lats_i=lats_i,
                                                      lons_i=lons_i,
                                                      plot=True,
                                                      return_axis=False,
                                                      nevent=ievt)
    else:
        if debug:
            print 'func:write_input- making event delay map for', phase
            #print 'eq_lat,eq_lon,phase,Tmin lats_i,lons_i',eq_lat,eq_lon,phase,Tmin,lats_i,lons_i
        event_map = make_event_delay_map(eq_lat,
                                         eq_lon,
                                         phase,
                                         delays_file,
                                         Tmin,
                                         lats_i=lats_i,
                                         lons_i=lons_i,
                                         return_axis=False,
                                         plot=True,
                                         nevent=ievt)

    #find delays at stations------------------------------------------------------
    if plot_figure:
        station_delays = get_station_delays(event_map,
                                            stations,
                                            lats_i,
                                            lons_i,
                                            pass_figure_axis=True,
                                            figure_axis=figure_axis)
    else:
        station_delays = get_station_delays(event_map, stations, lats_i,
                                            lons_i)

    #add noise (optional)---------------------------------------------------------
    if t_sig != 0:
        noise = np.random.normal(0, t_sig, len(station_delays))
        if add_noise:
            station_delays += noise

    station_lons = stations[0, :]
    station_lats = stations[1, :]
    n_stations = len(station_lats)
    station_elevation = 0.0

    for i in range(0, n_stations):
        dist_deg, rotation_angle = get_event_params(eq_lat, eq_lon)
        #find event distance
        event_distaz = gps2dist_azimuth(eq_lat,
                                        eq_lon,
                                        station_lats[i],
                                        station_lons[i],
                                        a=6371000.0,
                                        f=0.0)
        event_dist_deg = kilometer2degrees((event_distaz[0] / 1000.0))

        #skip station if too close or too far from source
        if event_dist_deg <= dist_min or event_dist_deg >= dist_max:
            continue

        #get ray theoretical travel time
        #if phase == 'S':
        #   phase_list = ['s','S','Sdiff']
        #elif phase == 'P':
        #   phase_list = ['p','P','Pdiff']

        ray_theory_arr = tt_model.get_travel_times(eq_dep,
                                                   event_dist_deg,
                                                   phase_list=[phase])
        if debug:
            print '_________________________________________________________________________________'
            print 'arrivals from taup_get_travel_time for event parameters [depth,delta(deg),phase]:'
            print '[{},{},{}]'.format(eq_dep, event_dist_deg,
                                      phase), ray_theory_arr
            print '_________________________________________________________________________________'

        ray_theory_travel_time = ray_theory_arr[0].time
        delay_time = station_delays[i]
        tobs = ray_theory_travel_time - delay_time

        if debug:
            print 'distance, phase, raytheory travel time, observed delay:', event_dist_deg, phase, ray_theory_travel_time, delay_time
            print 'the travel time observation is ', tobs

        fdelays.write('{}'.format(delay_time) + '\n')

        if raytheory:
            n_bands = 0
            nbt = 0  #spectral band number (must be 0 if ray theory)
            window_len = 0
            kunit = 0
            corcoeft = 0
        else:
            nbt = 1  #spectral band number

        #write line 1--------------------------------------------------------------
        f.write('{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}'.format(
            idate, iotime, ievt, kluster, stationcode, netw, gm_component,
            eq_lat, eq_lon, eq_dep, station_lats[i], station_lons[i],
            station_elevation, nobst, nobsa, kpole) + '\n')

        #write line 2--------------------------------------------------------------
        f.write('{} {} '.format(kunit, rms0))
        for j in range(0, n_bands + 1):
            f.write('0')  #used to be 0.0
        f.write('\n')

        #write line 3---------------------------------------------------------------
        if raytheory:
            f.write('{}'.format(1) + '\n')
        else:
            f.write('{}'.format(n_bands) + '\n')

        #write line 4---------------------------------------------------------------
        corcoeft = 1.0  # cross correlation coefficient
        f.write(
            '{} {} {} {} {} {}'.format(tobs, t_sig, corcoeft, nbt, window_len,
                                       '#tobs,tsig,corcoeft,nbt,window') +
            '\n')

        #write line 5--------------------------------------------------------------
        f.write('{}'.format(0) + '\n')
Пример #26
0
ff_tomo.plot_geo_config(stations=stations, events=events)

#write input files---------------------------------------------------------------
ievt = 1  #event number
nP = 0  #number of P observations
nS = 0  #number of S observations
nSKS = 0  #number of SKS observations

for event in events:
    ievt = event[0]
    eq_lon = event[1]
    eq_lat = event[2]
    eq_dep = event[3]

    dist_az = gps2dist_azimuth(eq_lat, eq_lon, 0, 0, a=6371000.0, f=0.0)
    event_dist_deg = kilometer2degrees((dist_az[0] / 1000.0))

    for phase in param_dict['phases_list']:

        if phase == 'SKS':
            if event_dist_deg < 70.0 or event_dist_deg > 120.0:
                print 'skipping event for phase SKS at distance', event_dist_deg
                continue
            else:
                nSKS += 1
                filename = '{}_{}'.format(param_dict['run_name'] + '.SKS',
                                          nSKS)
        elif phase == 'S':
            if event_dist_deg < 30.0 or event_dist_deg > 90.0:
                print 'skipping event for phase ', phase, 'at distance', event_dist_deg
                continue
Пример #27
0
def rfstats(stats=None, event=None, station=None, stream=None,
            phase='P', dist_range=None, tt_model='iasp91',
            pp_depth=None, pp_phase=None, model='iasp91'):
    """
    Calculate ray specific values like slowness for given event and station.

    :param stats: stats object with event and/or station attributes. Can be
        None if both event and station are given.
    :param event: ObsPy :class:`~obspy.core.event.Event` object
    :param station: station object with attributes latitude, longitude and
        elevation
    :param stream: If a stream is given, stats has to be None. In this case
        rfstats will be called for every stats object in the stream.
    :param phase: string with phase. Usually this will be 'P' or
        'S' for P and S receiver functions, respectively.
    :type dist_range: tuple of length 2
    :param dist_range: if epicentral of event is not in this intervall, None
        is returned by this function,\n
        if phase == 'P' defaults to (30, 90),\n
        if phase == 'S' defaults to (50, 85)
    :param tt_model: model for travel time calculation.
        (see the :mod:`obspy.taup` module, default: iasp91)
    :param pp_depth: Depth for piercing point calculation
        (in km, default: None -> No calculation)
    :param pp_phase: Phase for pp calculation (default: 'S' for P-receiver
        function and 'P' for S-receiver function)
    :param model': Path to model file for pp calculation
        (see :class:`~rf.simple_model.SimpleModel`, default: iasp91)
    :return: ``stats`` object with event and station attributes, distance,
        back_azimuth, inclination, onset and slowness or None if epicentral
        distance is not in the given intervall
    """
    if stream is not None:
        assert stats is None
        kwargs = {'event': event, 'station': station, 'stream':None,
                  'phase': phase, 'dist_range': dist_range,
                  'tt_model':tt_model, 'pp_depth': pp_depth,
                  'pp_phase': pp_phase, 'model': model}
        for tr in stream:
            rfstats(stats=tr.stats, **kwargs)
        return
    phase = phase.upper()
    if dist_range is None and phase in 'PS':
        dist_range = (30, 90) if phase == 'P' else (50, 85)
    if stats is None:
        stats = AttribDict({})
    if event is not None and station is not None:
        stats.update(obj2stats(event=event, station=station))
    dist, baz, _ = gps2DistAzimuth(stats.station_latitude,
                                   stats.station_longitude,
                                   stats.event_latitude,
                                   stats.event_longitude)
    dist = kilometer2degrees(dist / 1000)
    if dist_range and not dist_range[0] <= dist <= dist_range[1]:
        return
    tt_model = TauPyModel(model=tt_model)
    arrivals = tt_model.get_travel_times(stats.event_depth, dist, (phase,))
    if len(arrivals) == 0:
        raise Exception('TauPy does not return phase %s at distance %s' %
                        (phase, dist))
    if len(arrivals) > 1:
        from warnings import warn
        msg = ('TauPy returns more than one arrival for phase %s at '
               'distance -> take first arrival' )
        warn(msg % (phase, dist))
    arrival = arrivals[0]
    onset = stats.event_time + arrival.time
    inc = arrival.incident_angle
    slowness = arrival.ray_param_sec_degree
    stats.update({'distance': dist, 'back_azimuth': baz, 'inclination': inc,
                  'onset': onset, 'slowness': slowness})
    if pp_depth is not None:
        model = load_model(model)
        if pp_phase is None:
            pp_phase = 'S' if phase.upper().endswith('P') else 'P'
        model.ppoint(stats, pp_depth, phase=pp_phase)
    return stats