Пример #1
0
def getPhaseInfo(depth, distance, phaseList, plotFlag):
    ''' Routine to calculate phase arrivals 
        example:
        getPhaseInfo(600,60,"P",False)
    '''
    from obspy.taup import TauPyModel

    #specify earth model
    model = TauPyModel(model="iasp91")

    # the source - receiver distance in degrees
    #distance = 67.62
    #distance = 45
    #distance = 75.73
    # the source depth in km
    #depth = 500
    #depth = 37.5
    # list of phases you are interested in
    #phaseList = ["P", "S", "PKiKP"]

    arrivals = model.get_travel_times(source_depth_in_km=depth,
                                      distance_in_degree=distance,
                                      phase_list=phaseList)

    # to get the travel time for a phase...
    arr = arrivals[0]
    pTime = arr.time
    print "The pwave arrives at: " + str(pTime)

    # if  you want to plot the raypaths... this is totally cool!
    if plotFlag:
        arrivals = model.get_ray_paths(source_depth_in_km=depth,
                                       distance_in_degree=distance)

        arrivals.plot()
Пример #2
0
def test_plot_window_figure(tmpdir):
    reset_matplotlib()

    obs_tr = read(obsfile).select(channel="*R")[0]
    syn_tr = read(synfile).select(channel="*R")[0]

    config_file = os.path.join(DATA_DIR, "window", "27_60.BHZ.config.yaml")
    config = wio.load_window_config_yaml(config_file)

    cat = read_events(quakeml)
    inv = read_inventory(staxml)

    from obspy.taup import TauPyModel
    model = TauPyModel(model='iasp91')
    arrivals = model.get_ray_paths(500, 140, phase_list=['Pdiff', 'SS'])
    print(arrivals)
    ws = WindowSelector(obs_tr, syn_tr, config, event=cat, station=inv)
    windows = ws.select_windows()

    assert len(windows) > 0

    win.plot_window_figure(str(tmpdir),
                           obs_tr.id,
                           ws,
                           True,
                           figure_format="png")
Пример #3
0
def main():
                                      #           MAIN PROGRAM BODY
    OT,stlat,stlon,evlat,evlon,depth = getoptions()
    origin_time = UTCDateTime(str(OT))
    result = client.distaz(stalat=stlat, stalon=stlon, evtlat=evlat,evtlon=evlon)
    model = TauPyModel(model="AK135")
    arrivals = model.get_travel_times(source_depth_in_km=depth,distance_in_degree=result['distance'])#,
                                     #phase_list = ['P','PcP','PP','PKiKP','S','SS','ScS','SKiKS'])
    print "Distance = {0:.1f} arc degrees.".format(result['distance'])
    print "{0:.0f} Km distance.".format(result['distance']*111.25)
    print "{0:.0f} deg back Azimuth.".format(result['backazimuth'])
    table = client.traveltime(evloc=(evlat,evlon),staloc=[(stlat,stlon)],evdepth=depth)
    print "Selected phase list:\n"
    print (table.decode())

                   #   Print the phases, travel time and forecasted arrival time.
    phasename = []
    phasetime = []
    arrivaltime = []
    print "For origin time {}, ".format(origin_time)
    print "TauP big list of phases and arrival times:"
    for i in range(0,len(arrivals)):
        phasename.append(arrivals[i].name)
        phasetime.append(arrivals[i].time)
        at = origin_time+(arrivals[i].time)
        arrivaltime.append(at)
        print 'Phase: {0} \t arrives in {1:.2f} sec. at time {2:02.0f}:{3:02.0f}:{4:02.0f}.{5:02.0f}' \
              .format(arrivals[i].name,arrivals[i].time,at.hour,at.minute,at.second,at.microsecond/10000)
    arrivalpaths = model.get_ray_paths(source_depth_in_km=depth,distance_in_degree=result['distance'])#,\
                                #        phase_list = ['P','PcP','PP','PKiKP','S','SS','ScS','SKiKS'])
    arrivalpaths.plot()
Пример #4
0
    def test_single_path_ak135(self):
        """
        Test the raypath for a single phase. This time for model AK135.
        """
        filename = os.path.join(
            DATA, "taup_path_-o_stdout_-h_10_-ph_P_-deg_35_-mod_ak135")
        expected = np.genfromtxt(filename, comments='>')

        m = TauPyModel(model="ak135")
        arrivals = m.get_ray_paths(source_depth_in_km=10.0,
                                   distance_in_degree=35.0, phase_list=["P"])
        self.assertEqual(len(arrivals), 1)

        # Interpolate both paths to 100 samples and make sure they are
        # approximately equal.
        sample_points = np.linspace(0, 35, 100)

        interpolated_expected = np.interp(
            sample_points,
            expected[:, 0],
            expected[:, 1])

        interpolated_actual = np.interp(
            sample_points,
            np.round(np.degrees(arrivals[0].path['dist']), 2),
            np.round(6371 - arrivals[0].path['depth'], 2))

        self.assertTrue(np.allclose(interpolated_actual,
                                    interpolated_expected, rtol=1E-4, atol=0))
Пример #5
0
    def test_regional_models(self):
        """
        Tests small regional models as this used to not work.

        Note: It looks like too much work to get a 1-layer model working.
        The problem is first in finding the moho, and second in coarsely-
        sampling slowness. Also, why bother.
        """
        model_names = ["2_layer_model", "5_layer_model"]
        expected_results = [
            [("p", 18.143), ("Pn", 19.202), ("PcP", 19.884), ("sP", 22.054),
             ("ScP", 23.029), ("PcS", 26.410), ("s", 31.509), ("Sn", 33.395),
             ("ScS", 34.533)],
            [("Pn", 17.358), ("P", 17.666), ("p", 17.804), ("P", 17.869),
             ("PcP", 18.039), ("ScP", 19.988), ("sP", 22.640), ("sP", 22.716),
             ("sP", 22.992), ("PcS", 23.051), ("sP", 24.039), ("sP", 24.042),
             ("Sn", 30.029), ("S", 30.563), ("s", 30.801), ("S", 30.913),
             ("ScS", 31.208)]]

        for model_name, expects in zip(model_names, expected_results):
            with TemporaryWorkingDirectory():
                folder = os.path.abspath(os.curdir)
                build_taup_model(
                    filename=os.path.join(DATA, os.path.pardir,
                                          model_name + ".tvel"),
                    output_folder=folder, verbose=False)
                model = TauPyModel(os.path.join(folder, model_name + ".npz"))

            arrvials = model.get_ray_paths(source_depth_in_km=18.0,
                                           distance_in_degree=1.0)

            self.assertEqual(len(arrvials), len(expects))
            for arrival, expect in zip(arrvials, expects):
                self.assertEqual(arrival.name, expect[0])
                self.assertAlmostEqual(arrival.time, expect[1], 3)
Пример #6
0
    def test_regional_models(self):
        """
        Tests small regional models as this used to not work.

        Note: It looks like too much work to get a 1-layer model working.
        The problem is first in finding the moho, and second in coarsely-
        sampling slowness. Also, why bother.
        """
        model_names = ["2_layer_model", "5_layer_model"]
        expected_results = [
            [("p", 18.143), ("Pn", 19.202), ("PcP", 19.884), ("sP", 22.054),
             ("ScP", 23.029), ("PcS", 26.410), ("s", 31.509), ("Sn", 33.395),
             ("ScS", 34.533)],
            [("Pn", 17.358), ("P", 17.666), ("p", 17.804), ("P", 17.869),
             ("PcP", 18.039), ("ScP", 19.988), ("sP", 22.640), ("sP", 22.716),
             ("sP", 22.992), ("PcS", 23.051), ("sP", 24.039), ("sP", 24.042),
             ("Sn", 30.029), ("S", 30.563), ("s", 30.801), ("S", 30.913),
             ("ScS", 31.208)]]

        for model_name, expects in zip(model_names, expected_results):
            with TemporaryWorkingDirectory():
                folder = os.path.abspath(os.curdir)
                build_taup_model(
                    filename=os.path.join(DATA, os.path.pardir,
                                          model_name + ".tvel"),
                    output_folder=folder, verbose=False)
                model = TauPyModel(os.path.join(folder, model_name + ".npz"))

            arrvials = model.get_ray_paths(source_depth_in_km=18.0,
                                           distance_in_degree=1.0)

            self.assertEqual(len(arrvials), len(expects))
            for arrival, expect in zip(arrvials, expects):
                self.assertEqual(arrival.name, expect[0])
                self.assertAlmostEqual(arrival.time, expect[1], 3)
Пример #7
0
    def test_single_path_ak135(self):
        """
        Test the raypath for a single phase. This time for model AK135.
        """
        filename = os.path.join(
            DATA, "taup_path_-o_stdout_-h_10_-ph_P_-deg_35_-mod_ak135")
        expected = np.genfromtxt(filename, comments='>')

        m = TauPyModel(model="ak135")
        arrivals = m.get_ray_paths(source_depth_in_km=10.0,
                                   distance_in_degree=35.0, phase_list=["P"])
        self.assertEqual(len(arrivals), 1)

        # Interpolate both paths to 100 samples and make sure they are
        # approximately equal.
        sample_points = np.linspace(0, 35, 100)

        interpolated_expected = np.interp(
            sample_points,
            expected[:, 0],
            expected[:, 1])

        interpolated_actual = np.interp(
            sample_points,
            np.round(np.degrees(arrivals[0].path['dist']), 2),
            np.round(6371 - arrivals[0].path['depth'], 2))

        self.assertTrue(np.allclose(interpolated_actual,
                                    interpolated_expected, rtol=1E-4, atol=0))
Пример #8
0
    def test_arrivals_class(self):
        """
        Tests list operations on the Arrivals class.

        See #1518.
        """
        model = TauPyModel(model='iasp91')
        arrivals = model.get_ray_paths(source_depth_in_km=0,
                                       distance_in_degree=1,
                                       phase_list=['Pn', 'PmP'])
        self.assertEqual(len(arrivals), 2)
        # test copy
        self.assertTrue(isinstance(arrivals.copy(), Arrivals))
        # test sum
        self.assertTrue(isinstance(arrivals + arrivals, Arrivals))
        self.assertTrue(isinstance(arrivals + arrivals[0], Arrivals))
        # test multiplying
        self.assertTrue(isinstance(arrivals * 2, Arrivals))
        arrivals *= 3
        self.assertEqual(len(arrivals), 6)
        self.assertTrue(isinstance(arrivals, Arrivals))
        # test slicing
        self.assertTrue(isinstance(arrivals[2:5], Arrivals))
        # test appending
        arrivals.append(arrivals[0])
        self.assertEqual(len(arrivals), 7)
        self.assertTrue(isinstance(arrivals, Arrivals))
        # test assignment
        arrivals[0] = arrivals[-1]
        self.assertTrue(isinstance(arrivals, Arrivals))
        arrivals[2:5] = arrivals[1:4]
        self.assertTrue(isinstance(arrivals, Arrivals))
        # test assignment with wrong type
        with self.assertRaises(TypeError):
            arrivals[0] = 10.
        with self.assertRaises(TypeError):
            arrivals[2:5] = [0, 1, 2]
        with self.assertRaises(TypeError):
            arrivals.append(arrivals)
        # test add and mul with wrong type
        with self.assertRaises(TypeError):
            arrivals + [
                2,
            ]
        with self.assertRaises(TypeError):
            arrivals += [
                2,
            ]
        with self.assertRaises(TypeError):
            arrivals * [
                2,
            ]
        with self.assertRaises(TypeError):
            arrivals *= [
                2,
            ]
Пример #9
0
 def test_ppointvsobspytaup_S2P(self):
     slowness = 12.33
     evdep = 12.4
     evdist = 67.7
     pp1 = self.model.ppoint_distance(200, slowness, phase='P')
     model = TauPyModel(model='iasp91')
     arrivals = model.get_ray_paths(evdep, evdist, ('S250p', ))
     arrival = arrivals[0]
     index = np.searchsorted(arrival.path['depth'][::-1], 200)
     pdist = arrival.path['dist']
     pp2 = degrees2kilometers((pdist[-1] - pdist[-index - 1]) * 180 / np.pi)
     self.assertLess(abs(pp1 - pp2) / pp2, 0.2)
Пример #10
0
def PsRayp(layers, dist, dep):
    model = TauPyModel(model="iasp91")
    ph_list = makepheaselist(layers)
    arrs = model.get_ray_paths(dist, dep, ph_list)
    arr_num = len(arrs)
    print(arr_num, len(ph_list))
    rayp_list = np.zeros([arr_num, 2])
    for i in range(arr_num):
        rayp_list[i][0] = srad2skm(arrs[i].ray_param)
        rayp_list[i][1] = int(arrs[i].name.strip('Ps'))
    rayp_list.sort(axis=0)
    return(rayp_list)
Пример #11
0
 def test_ppointvsobspytaup_S2P(self):
     slowness = 12.33
     evdep = 12.4
     evdist = 67.7
     pp1 = self.model.ppoint_distance(200, slowness, phase="P")
     model = TauPyModel(model="iasp91")
     arrivals = model.get_ray_paths(evdep, evdist, ("S250p",))
     arrival = arrivals[0]
     index = np.searchsorted(arrival.path["depth"][::-1], 200)
     pdist = arrival.path["dist"]
     pp2 = degrees2kilometers((pdist[-1] - pdist[-index - 1]) * 180 / np.pi)
     self.assertLess(abs(pp1 - pp2) / pp2, 0.2)
Пример #12
0
 def test_ppointvsobspytaup_P2S(self):
     slowness = 6.28
     evdep = 12.4
     evdist = 67.7
     depth = 200
     pp1 = self.model.ppoint_distance(depth, slowness)
     model = TauPyModel(model="iasp91")
     arrivals = model.get_ray_paths(evdep, evdist, ("P250s",))
     arrival = arrivals[0]
     index = np.searchsorted(arrival.path["depth"][::-1], depth)
     pdist = arrival.path["dist"]
     pp2 = degrees2kilometers((pdist[-1] - pdist[-index - 1]) * 180 / np.pi)
     self.assertLess(abs(pp1 - pp2) / pp2, 0.1)
Пример #13
0
 def test_ppointvsobspytaup_P2S(self):
     slowness = 6.28
     evdep = 12.4
     evdist = 67.7
     depth = 200
     pp1 = self.model.ppoint_distance(depth, slowness)
     model = TauPyModel(model='iasp91')
     arrivals = model.get_ray_paths(evdep, evdist, ('P250s', ))
     arrival = arrivals[0]
     index = np.searchsorted(arrival.path['depth'][::-1], depth)
     pdist = arrival.path['dist']
     pp2 = degrees2kilometers((pdist[-1] - pdist[-index - 1]) * 180 / np.pi)
     self.assertLess(abs(pp1 - pp2) / pp2, 0.1)
Пример #14
0
 def test_high_slowness_crust(self):
     """
     Check handling of sources located in a high slowness layer.
     """
     model_name = "high_slowness_crust"
     with TemporaryWorkingDirectory():
         folder = os.path.abspath(os.curdir)
         build_taup_model(
           filename=os.path.join(DATA, os.path.pardir, model_name + ".nd"),
           output_folder=folder, verbose=False)
         model = TauPyModel(os.path.join(folder, model_name + ".npz"))
         arrivals = model.get_ray_paths(20.0, 0.84, phase_list=["sS"])
         assert len(arrivals) == 0
Пример #15
0
 def test_many_identically_named_phases(self):
     """
     Regression test to make sure obspy.taup works with models that
     produce many identically names seismic phases.
     """
     with TemporaryWorkingDirectory():
         folder = os.path.abspath(os.curdir)
         model_name = "smooth_geodynamic_model"
         build_taup_model(
             filename=os.path.join(DATA, model_name + ".tvel"),
             output_folder=folder, verbose=False)
         m = TauPyModel(os.path.join(folder, model_name + ".npz"))
     arr = m.get_ray_paths(172.8000, 46.762440693494824, ["SS"])
     self.assertGreater(len(arr), 10)
Пример #16
0
    def test_arrivals_class(self):
        """
        Tests list operations on the Arrivals class.

        See #1518.
        """
        model = TauPyModel(model='iasp91')
        arrivals = model.get_ray_paths(source_depth_in_km=0,
                                       distance_in_degree=1,
                                       phase_list=['Pn', 'PmP'])
        self.assertEqual(len(arrivals), 2)
        # test copy
        self.assertTrue(isinstance(arrivals.copy(), Arrivals))
        # test sum
        self.assertTrue(isinstance(arrivals + arrivals, Arrivals))
        self.assertTrue(isinstance(arrivals + arrivals[0], Arrivals))
        # test multiplying
        self.assertTrue(isinstance(arrivals * 2, Arrivals))
        arrivals *= 3
        self.assertEqual(len(arrivals), 6)
        self.assertTrue(isinstance(arrivals, Arrivals))
        # test slicing
        self.assertTrue(isinstance(arrivals[2:5], Arrivals))
        # test appending
        arrivals.append(arrivals[0])
        self.assertEqual(len(arrivals), 7)
        self.assertTrue(isinstance(arrivals, Arrivals))
        # test assignment
        arrivals[0] = arrivals[-1]
        self.assertTrue(isinstance(arrivals, Arrivals))
        arrivals[2:5] = arrivals[1:4]
        self.assertTrue(isinstance(arrivals, Arrivals))
        # test assignment with wrong type
        with self.assertRaises(TypeError):
            arrivals[0] = 10.
        with self.assertRaises(TypeError):
            arrivals[2:5] = [0, 1, 2]
        with self.assertRaises(TypeError):
            arrivals.append(arrivals)
        # test add and mul with wrong type
        with self.assertRaises(TypeError):
            arrivals + [2, ]
        with self.assertRaises(TypeError):
            arrivals += [2, ]
        with self.assertRaises(TypeError):
            arrivals * [2, ]
        with self.assertRaises(TypeError):
            arrivals *= [2, ]
Пример #17
0
 def test_small_regional_model(self):
     """
     Tests a small regional model as this used to not work.
     """
     with TemporaryWorkingDirectory():
         folder = os.path.abspath(os.curdir)
         model_name = "regional_model"
         build_taup_model(
             filename=os.path.join(DATA, os.path.pardir,
                                   model_name + ".tvel"),
             output_folder=folder, verbose=False)
         m = TauPyModel(os.path.join(folder, model_name + ".npz"))
     arr = m.get_ray_paths(source_depth_in_km=18.0, distance_in_degree=1.0)
     self.assertEqual(len(arr), 9)
     for a, d in zip(arr, [("p", 18.143), ("Pn", 19.202), ("PcP", 19.884),
                           ("sP", 22.054), ("ScP", 23.029), ("PcS", 26.410),
                           ("s", 31.509), ("Sn", 33.395), ("ScS", 34.533)]):
         self.assertEqual(a.name, d[0])
         self.assertAlmostEqual(a.time, d[1], 3)
Пример #18
0
    def test_regional_models(self):
        """
        Tests small regional models as this used to not work.

        Note: It looks like too much work to get a 1-layer model working.
        The problem is first in finding the moho, and second in coarsely-
        sampling slowness. Also, why bother.
        """
        model_names = ["2_layer_model", "5_layer_model",
                       "2_layer_no_discontinuity_model"]
        expected_results = [
            [("p", 18.143), ("P", 19.202), ("Pn", 19.202), ("P", 19.884),
             ("sP", 22.054), ("pP", 23.023), ("pP", 23.038), ("sP", 25.656),
             ("sP", 25.759), ("s", 31.509), ("S", 33.395), ("Sn", 33.395),
             ("S", 34.533), ("sS", 39.991), ("sS", 40.009), ("PP", 3110.537),
             ("SP", 4267.568), ("PS", 4269.707), ("SS", 5426.732)],
            [("P", 17.358), ("Pn", 17.358), ("P", 17.666), ("p", 17.804),
             ("P", 17.869), ("P", 18.039), ("pP", 21.125), ("pP", 21.164),
             ("sP", 22.640), ("sP", 22.716), ("sP", 22.992), ("sP", 23.766),
             ("sP", 23.918), ("sP", 24.039), ("sP", 24.041), ("S", 30.029),
             ("Sn", 30.029), ("S", 30.563), ("s", 30.800), ("S", 30.913),
             ("S", 31.208), ("sS", 36.547), ("sS", 36.613), ("PP", 3147.085),
             ("SP", 4294.699), ("PS", 4296.826), ("SS", 5444.434)],
            [("p", 18.143), ("sP", 22.054), ("s", 31.509), ("PP", 3562.683),
             ("SP", 4881.292), ("PS", 4883.430), ("SS", 6202.037)]
            ]

        for model_name, expects in zip(model_names, expected_results):
            with TemporaryWorkingDirectory():
                folder = os.path.abspath(os.curdir)
                build_taup_model(
                    filename=os.path.join(DATA, os.path.pardir,
                                          model_name + ".tvel"),
                    output_folder=folder, verbose=False)
                model = TauPyModel(os.path.join(folder, model_name + ".npz"))

            arrivals = model.get_ray_paths(source_depth_in_km=18.0,
                                           distance_in_degree=1.0)

            assert len(arrivals) == len(expects)
            for arrival, expect in zip(arrivals, expects):
                assert arrival.name == expect[0]
                assert round(abs(arrival.time-expect[1]), 2) == 0
Пример #19
0
 def test_small_regional_model(self):
     """
     Tests a small regional model as this used to not work.
     """
     with TemporaryWorkingDirectory():
         folder = os.path.abspath(os.curdir)
         model_name = "regional_model"
         build_taup_model(filename=os.path.join(DATA, os.path.pardir,
                                                model_name + ".tvel"),
                          output_folder=folder,
                          verbose=False)
         m = TauPyModel(os.path.join(folder, model_name + ".npz"))
     arr = m.get_ray_paths(source_depth_in_km=18.0, distance_in_degree=1.0)
     self.assertEqual(len(arr), 9)
     for a, d in zip(arr, [("p", 18.143), ("Pn", 19.202), ("PcP", 19.884),
                           ("sP", 22.054), ("ScP", 23.029), ("PcS", 26.410),
                           ("s", 31.509), ("Sn", 33.395), ("ScS", 34.533)]):
         self.assertEqual(a.name, d[0])
         self.assertAlmostEqual(a.time, d[1], 3)
Пример #20
0
def calculate_depths(i):
#start = time.time()
     
    lhs = np.ones(( len(discon),))
    model = TauPyModel(model="iasp91") 
#for i in range(f):
    for j in range(len(discon)):
        phase = 'S'+ str(discon[j]) + 'p'
        arrivals = model.get_ray_paths(source_depth_in_km=source_info[i,1],                                    distance_in_degree=source_info[i,0] ,                                    phase_list=[phase])

        piercing_points = model.get_pierce_points(source_depth_in_km=source_info[i,1],                                    distance_in_degree=source_info[i,0] ,                                    phase_list=[phase])

        piercing_points_S = model.get_pierce_points(source_depth_in_km=source_info[i,1],                                    distance_in_degree=source_info[i,0] ,                                    phase_list=['S'])

        if piercing_points:  
            t_sp = piercing_points[0].pierce[-1][1]
            t_s = piercing_points_S[0].pierce[-1][1]
            lhs[j] = t_s - t_sp  
            file_name = file_info[i]
    return (lhs, file_name)
Пример #21
0
 def _compare_against_ak135_tables_kennet(self, filename, phases):
     """
     Helper function to compare against the AK135 traveltime tables of
     Kennet. This test is also done in the Java TauP version.
     """
     values = self._read_ak135_test_files(filename)
     m = TauPyModel(model="ak135")
     for value in values:
         # Parameters are not strictly defined for a non-existent travel
         # time.
         if value["time"] == 0.0:
             continue
         arrivals = m.get_ray_paths(source_depth_in_km=value["depth"],
                                    distance_in_degree=value["dist"],
                                    phase_list=phases)
         arrivals = sorted(arrivals, key=lambda x: x.time)
         arr = arrivals[0]
         # These are the same tolerances as in the Java tests suite.
         self.assertTrue(abs(arr.time - value["time"]) < 0.07)
         self.assertTrue(
             abs(arr.ray_param_sec_degree - value["ray_param"]) < 0.11)
Пример #22
0
 def _compare_against_ak135_tables_kennet(self, filename, phases):
     """
     Helper function to compare against the AK135 traveltime tables of
     Kennet. This test is also done in the Java TauP version.
     """
     values = self._read_ak135_test_files(filename)
     m = TauPyModel(model="ak135")
     for value in values:
         # Parameters are not strictly defined for a non-existent travel
         # time.
         if value["time"] == 0.0:
             continue
         arrivals = m.get_ray_paths(
             source_depth_in_km=value["depth"],
             distance_in_degree=value["dist"],
             phase_list=phases)
         arrivals = sorted(arrivals, key=lambda x: x.time)
         arr = arrivals[0]
         # These are the same tolerances as in the Java tests suite.
         self.assertTrue(abs(arr.time - value["time"]) < 0.07)
         self.assertTrue(abs(arr.ray_param_sec_degree -
                             value["ray_param"]) < 0.11)
                         y,
                         color=color,
                         linewidth=0.3,
                         linestyle='solid',
                         alpha=0.1)
        if len(x) > 0 and len(
                y) > 0:  # this function prevents text being overwritten
            plottext(x[0], y[0], phase, 'top', 'right', color, textlist)
            plottext(x[len(x) - 1], y[len(y) - 1], phase, 'top', 'left', color,
                     textlist)

# Add the inset picture of the globe at x, y, width, height, as a fraction of the parent plot
    ax1 = fig.add_axes([0.63, 0.48, 0.4, 0.4], polar=True)
    # Plot all pre-determined phases
    for phase, distance in GLOBE_PHASES:
        arrivals = model.get_ray_paths(EQZ, distance, phase_list=[phase])
        ax1 = arrivals.plot_rays(plot_type='spherical',
                                 legend=False,
                                 label_arrivals=False,
                                 plot_all=True,
                                 phase_list=PHASES,
                                 show=False,
                                 ax=ax1)

    # Annotate regions of the globe
    ax1.text(0,
             0,
             'Solid\ninner\ncore',
             horizontalalignment='center',
             verticalalignment='center',
             bbox=dict(facecolor='white', edgecolor='none', alpha=0.7))
Пример #24
0
    def test_paths_for_crustal_phases(self):
        """
        Tests that Pn and PmP are correctly modelled and not mixed up.

        See #1392.
        """
        model = TauPyModel(model='iasp91')
        paths = model.get_ray_paths(source_depth_in_km=0,
                                    distance_in_degree=1,
                                    phase_list=['Pn', 'PmP'])
        self.assertEqual(len(paths), 2)

        self.assertEqual(paths[0].name, "PmP")
        self.assertAlmostEqual(paths[0].time, 21.273, 3)
        self.assertEqual(paths[1].name, "Pn")
        self.assertAlmostEqual(paths[1].time, 21.273, 3)

        self.assertAlmostEqual(paths[0].time, 21.273, 3)

        # Values of visually checked paths to guard against regressions.
        pmp_path = [
            [0.0, 0.0],
            [8.732364066174294e-07, 0.005402127286288305],
            [0.00020293803558129412, 1.2550644943312363],
            [0.000405124234951687, 2.5047268613761844],
            [0.0008098613580518535, 5.004051595465171],
            [0.0016207981804224497, 10.002701063643144],
            [0.00243369214394241, 15.001350531821117],
            [0.0032485517460744207, 20.0],
            [0.0034500021984838003, 20.9375],
            [0.0036515675727796315, 21.875],
            [0.004055043605178164, 23.75],
            [0.004863380445624696, 27.5],
            [0.006485622554890742, 35.0],
            [0.008803860898528547, 35.018603858353345],
            [0.011122099242166353, 35.0],
            [0.012744341351432398, 27.5],
            [0.01355267819187893, 23.75],
            [0.013956154224277463, 21.875],
            [0.014157719598573294, 20.9375],
            [0.014359170050982674, 20.0],
            [0.015174029653114684, 15.001350531821117],
            [0.015986923616634643, 10.002701063643144],
            [0.01679786043900524, 5.004051595465171],
            [0.017202597562105407, 2.5047268613761844],
            [0.0174047837614758, 1.2550644943312363],
            [0.017606848560650475, 0.005402127286288305],
            [0.017607721797057094, 0.0]]
        pn_path = [
            [0.0, 0.0],
            [8.732421799574388e-07, 0.005402127286288305],
            [0.00020293937754080365, 1.2550644943312363],
            [0.0004051269144571584, 2.5047268613761844],
            [0.0008098667167377564, 5.004051595465171],
            [0.0016208089138889542, 10.002701063643144],
            [0.002433708274208186, 15.001350531821117],
            [0.003248573295310095, 20.0],
            [0.0034500255976490177, 20.9375],
            [0.0036515928239481774, 21.875],
            [0.004055072566590625, 23.75],
            [0.004863416852584004, 27.5],
            [0.0064856739540738425, 35.0],
            [0.0064856739540738425, 35.0],
            [0.010967618565869454, 35.0],
            [0.010967618565869454, 35.0],
            [0.012589875667359293, 27.5],
            [0.013398219953352672, 23.75],
            [0.01380169969599512, 21.875],
            [0.01400326692229428, 20.9375],
            [0.014204719224633202, 20.0],
            [0.015019584245735112, 15.001350531821117],
            [0.015832483606054343, 10.002701063643144],
            [0.01664342580320554, 5.004051595465171],
            [0.017048165605486137, 2.5047268613761844],
            [0.017250353142402492, 1.2550644943312363],
            [0.017452419277763337, 0.005402127286288305],
            [0.017453292519943295, 0.0]]

        np.testing.assert_allclose([_i[0] for _i in pmp_path],
                                   paths[0].path["dist"])
        np.testing.assert_allclose([_i[1] for _i in pmp_path],
                                   paths[0].path["depth"])
        np.testing.assert_allclose([_i[0] for _i in pn_path],
                                   paths[1].path["dist"])
        np.testing.assert_allclose([_i[1] for _i in pn_path],
                                   paths[1].path["depth"])
Пример #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',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
   filter_type, freqmin,freqmax, window = get_filter_params(delays_file,phase,Tmin,filter_type=filter_type)
   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])

      ### 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 '_________________________________________________________________________________'

      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,time_in_core,'#tobs,tsig,corcoeft,nbt,window,tincore')+'\n') 

      #write line 5--------------------------------------------------------------
      f.write('{}'.format(0)+'\n')
Пример #26
0
class TauPyPlottingTestCase(unittest.TestCase):
    """
    TauPy plotting tests.
    """
    def setUp(self):
        self.image_dir = os.path.join(os.path.dirname(__file__), 'images')
        self.model = TauPyModel(model="iasp91")

    def test_spherical_many_phases(self):
        with ImageComparison(self.image_dir,
                             "spherical_many_phases.png") as ic:
            self.model.get_ray_paths(500, 140).plot(plot_type="spherical",
                                                    plot_all=True, show=False)
            plt.savefig(ic.name)

    def test_spherical_many_phases_buried_station(self):
        """
        Same as test_spherical_many_phases but this time the receiver is
        buried.
        """
        with ImageComparison(self.image_dir,
                             "spherical_many_phases_buried_station.png") as ic:
            arrivals = self.model.get_ray_paths(500, 140,
                                                receiver_depth_in_km=200)
            arrivals.plot(plot_type="spherical", plot_all=True, show=False)
            plt.savefig(ic.name)

    def test_spherical_many_phases_no_other_way(self):
        """
        Same as test_spherical_many_phases but this time no phases
        travelling the other way are plotted.
        """
        with ImageComparison(self.image_dir,
                             "spherical_many_phases_single_way.png") as ic:
            self.model.get_ray_paths(500, 140).plot(plot_type="spherical",
                                                    plot_all=False, show=False)
            plt.savefig(ic.name)

    def test_spherical_more_then_360_degrees(self):
        """
        Test a plot where rays travel more than 360.0 degrees.
        """
        with ImageComparison(self.image_dir,
                             "spherical_more_then_360.png") as ic:
            self.model.get_ray_paths(0, 10, phase_list=["PPPPPP"]).plot(
                plot_type="spherical", plot_all=True, show=False)
            plt.savefig(ic.name)

    def test_spherical_diff_phases(self):
        with ImageComparison(self.image_dir,
                             "spherical_diff_phases.png") as ic:
            self.model.get_ray_paths(
                700, 140, phase_list=["Pdiff", "Sdiff", "pSdiff", "sSdiff",
                                      "pPdiff", "sPdiff"]).plot(
                plot_type="spherical", plot_all=True, show=False)
            plt.savefig(ic.name)

    def test_cartesian_many_phases(self):
        with ImageComparison(self.image_dir,
                             "cartesian_many_phases.png") as ic:
            self.model.get_ray_paths(500, 140).plot(plot_type="cartesian",
                                                    plot_all=True, show=False)
            plt.savefig(ic.name)

    def test_cartesian_many_phases_buried_station(self):
        """
        Same as test_cartesian_many_phases but this time the receiver is
        buried.
        """
        with ImageComparison(self.image_dir,
                             "cartesian_many_phases_buried_station.png") as ic:
            arrivals = self.model.get_ray_paths(500, 140,
                                                receiver_depth_in_km=200)
            arrivals.plot(plot_type="cartesian", plot_all=True, show=False)
            plt.savefig(ic.name)

    def test_cartesian_many_phases_no_other_way(self):
        """
        Same as test_cartesian_many_phases but this time no phases
        travelling the other way are plotted.
        """
        with ImageComparison(self.image_dir,
                             "cartesian_many_phases_single_way.png") as ic:
            self.model.get_ray_paths(500, 140).plot(plot_type="cartesian",
                                                    plot_all=False, show=False)
            plt.savefig(ic.name)

    def test_cartesian_multiple_station_markers(self):
        """
        Cartesian plot with two station markers.
        """
        with ImageComparison(self.image_dir,
                             "cartesian_multiple_stations.png") as ic:
            self.model.get_ray_paths(350, 100).plot(plot_type="cartesian",
                                                    plot_all=True, show=False)
            plt.savefig(ic.name)
Пример #27
0
from obspy.taup import TauPyModel

model = TauPyModel(model='iasp91')
arrivals = model.get_ray_paths(500, 140, phase_list=['Pdiff', 'SS'])
arrivals.plot_rays(plot_type='spherical', phase_list=['Pdiff', 'SS'],
                   legend=True)
Пример #28
0
def main(fnam_nd: str,
         times: tuple,
         phase_list=("P", "S"),
         depth=40.,
         plot_rays=False):
    """
    Compute distance of an event, given S-P time
    :param fnam_nd: name of TauP compatible model file
    :param times: list of S-P time
    :param phase_list: list of phases between which the time difference is measured (usually P and S)
    :param depth: assumed depth of event
    :param plot_rays: create a plot with the ray paths
    """
    fnam_npz = "./taup_tmp/" \
               + psplit(fnam_nd)[-1][:-3] + ".npz"
    build_taup_model(fnam_nd, output_folder="./taup_tmp")
    cache = OrderedDict()
    model = TauPyModel(model=fnam_npz, cache=cache)

    if plot_rays:
        fig, ax = plt.subplots(1, 1)

    for itime, tSmP in enumerate(times):
        dist = get_dist(model, tSmP=tSmP, depth=depth, phase_list=phase_list)
        if dist is None:
            print(f"{fnam_nd}, S-P time: {tSmP:5.1f}: NO SOLUTION FOUND!")
        else:
            print(f"{fnam_nd}, S-P time: {tSmP:5.1f}, "
                  f"taup_distance: {dist:5.1f}")

        if plot_rays:
            if dist is None:
                ax.plot((-200), (-200),
                        label="%4.1f sec, NO SOLUTION" % (tSmP),
                        c="white",
                        lw=0.0)
            else:
                arrivals = model.get_ray_paths(distance_in_degree=dist,
                                               source_depth_in_km=depth,
                                               phase_list=["P", "S"])

                RADIUS_MARS = 3389.5
                already_plotted = dict(P=False, S=False)
                ls = dict(P="solid", S="dashed")
                label = dict(P="%4.1f sec, %5.1f°" % (tSmP, dist), S=None)
                for arr in arrivals:
                    if not already_plotted[arr.name]:
                        already_plotted[arr.name] = True
                        x = (RADIUS_MARS - arr.path["depth"]) * \
                            np.sin(arr.path["dist"])
                        y = (RADIUS_MARS - arr.path["depth"]) * \
                            np.cos(arr.path["dist"])
                        ax.plot(x,
                                y,
                                c="C%d" % itime,
                                ls=ls[arr.name],
                                label=label[arr.name],
                                lw=1.2)

    if plot_rays:
        for layer_depth in model.model.get_branch_depths(
        ):  # (0, 10, 50, 1000,
            # 1500):
            angles = np.linspace(0, 2 * np.pi, 1000)
            x_circle = (RADIUS_MARS - layer_depth) * np.sin(angles)
            y_circle = (RADIUS_MARS - layer_depth) * np.cos(angles)
            ax.plot(x_circle, y_circle, c="k", ls="dashed", lw=0.5, zorder=-1)
        for layer_depth in (model.model.cmb_depth, 0.0):
            angles = np.linspace(0, 2 * np.pi, 1000)
            x_circle = (RADIUS_MARS - layer_depth) * np.sin(angles)
            y_circle = (RADIUS_MARS - layer_depth) * np.cos(angles)
            ax.plot(x_circle, y_circle, c="k", ls="solid", lw=1.0)

        #  for layer_depth in [1100.0]:
        #      angles = np.linspace(0, 2 * np.pi, 1000)
        #      x_circle = (RADIUS_MARS - layer_depth) * np.sin(angles)
        #      y_circle = (RADIUS_MARS - layer_depth) * np.cos(angles)
        #      ax.plot(x_circle, y_circle, c="k", ls="dotted", lw=0.3)

        ax.set_xlim(-100, RADIUS_MARS + 100)
        ax.set_ylim(1000, RADIUS_MARS + 100)
        ax.set_xlabel("radius / km")
        ax.set_ylabel("radius / km")
        ax.set_title("Ray path for model %s" % fnam_nd)
        ax.set_aspect("equal", "box")
        ax.legend(loc="lower left")
        plt.show()
Пример #29
0
#latsta= 37.2869

#sta='MILP'
#lonsta=-121.8340
#latsta=37.4491

path = '/Users/dmelgar/FakeQuakes/M6_validation_pwave/output/waveforms/M6.000000/'

#taup
zs = 8.0
g = Geod(ellps='WGS84')
azimuth, baz, dist = g.inv(-121.753508, 37.332028, lonsta, latsta)
dist_in_degs = kilometer2degrees(dist / 1000.)
velmod = TauPyModel(
    '/Users/dmelgar/FakeQuakes/M6_validation_pwave/structure/bbp_norcal.npz')
Ppaths = velmod.get_ray_paths(zs, dist_in_degs, phase_list=['P', 'p'])
p = Ppaths[0].time
Spaths = velmod.get_ray_paths(zs, dist_in_degs, phase_list=['S', 's'])
s = Spaths[0].time

nlf = read(path + sta + '.LYN.sac')
elf = read(path + sta + '.LYE.sac')
zlf = read(path + sta + '.LYZ.sac')

nbb = read(path + sta + '.bb.HNN.sac')
ebb = read(path + sta + '.bb.HNE.sac')
zbb = read(path + sta + '.bb.HNZ.sac')

nhf = read(path + sta + '.HNN.sac')
ehf = read(path + sta + '.HNE.sac')
zhf = read(path + sta + '.HNZ.sac')
Пример #30
0
def stochastic_simulation(home,
                          project_name,
                          rupture_name,
                          sta,
                          sta_lon,
                          sta_lat,
                          component,
                          model_name,
                          rise_time_depths,
                          moho_depth_in_km,
                          total_duration=100,
                          hf_dt=0.01,
                          stress_parameter=50,
                          kappa=0.04,
                          Qexp=0.6,
                          Pwave=False,
                          Swave=True,
                          high_stress_depth=1e4):
    '''
    Run stochastic HF sims
    
    stress parameter is in bars
    '''

    from numpy import genfromtxt, pi, logspace, log10, mean, where, exp, arange, zeros, argmin, rad2deg, arctan2, real
    from pyproj import Geod
    from obspy.geodetics import kilometer2degrees
    from obspy.taup import TauPyModel
    from mudpy.forward import get_mu, write_fakequakes_hf_waveforms_one_by_one, read_fakequakes_hypo_time
    from obspy import Stream, Trace
    from sys import stdout
    import warnings

    #print out what's going on:
    out = '''Running with input parameters:
    home = %s
    project_name = %s
    rupture_name = %s
    sta = %s
    sta_lon = %s
    sta_lat = %s
    model_name = %s
    rise_time_depths = %s
    moho_depth_in_km = %s
    total_duration = %s
    hf_dt = %s
    stress_parameter = %s
    kappa = %s
    Qexp = %s
    component = %s
    Pwave = %s
    Swave = %s
    high_stress_depth = %s
    ''' % (home, project_name, rupture_name, sta, str(sta_lon), str(sta_lat),
           model_name, str(rise_time_depths), str(moho_depth_in_km),
           str(total_duration), str(hf_dt), str(stress_parameter), str(kappa),
           str(Qexp), str(component), str(Pwave), str(Swave),
           str(high_stress_depth))
    print(out)

    #    rupture=rupture_name.split('.')[0]+'.'+rupture_name.split('.')[1]
    #    log=home+project_name+'/output/waveforms/'+rupture+'/'+sta+'.HN'+component+'.1cpu.log'
    #    logfile=open(log,'w')
    #    logfile.write(out)
    #print 'stress is '+str(stress_parameter)

    #I don't condone it but this cleans up the warnings
    warnings.filterwarnings("ignore")

    #Load the source
    fault = genfromtxt(home + project_name + '/output/ruptures/' +
                       rupture_name)

    #Onset times for each subfault
    onset_times = fault[:, 12]

    #load velocity structure
    structure = genfromtxt(home + project_name + '/structure/' + model_name)

    #Frequencies vector
    f = logspace(log10(hf_dt), log10(1 / (2 * hf_dt)) + 0.01, 50)
    omega = 2 * pi * f

    #Output time vector (0 is origin time)
    t = arange(0, total_duration, hf_dt)

    #Projection object for distance calculations
    g = Geod(ellps='WGS84')

    #Create taup velocity model object, paste on top of iaspei91
    #taup_create.build_taup_model(home+project_name+'/structure/bbp_norcal.tvel',output_folder=home+project_name+'/structure/')
    velmod = TauPyModel(model=home + project_name + '/structure/iquique',
                        verbose=True)
    #Get epicentral time
    epicenter, time_epi = read_fakequakes_hypo_time(home, project_name,
                                                    rupture_name)

    #Moments
    slip = (fault[:, 8]**2 + fault[:, 9]**2)**0.5
    subfault_M0 = slip * fault[:, 10] * fault[:, 11] * fault[:, 13]
    subfault_M0 = subfault_M0 * 1e7  #to dyne-cm
    M0 = subfault_M0.sum()
    relative_subfault_M0 = subfault_M0 / M0
    Mw = (2. / 3) * (log10(M0 * 1e-7) - 9.1)

    #Corner frequency scaling
    i = where(slip > 0)[0]  #Non-zero faults
    N = len(i)  #number of subfaults
    dl = mean((fault[:, 10] + fault[:, 11]) / 2)  #predominant length scale
    dl = dl / 1000  # to km

    #Tau=p perturbation
    tau_perturb = 0.1

    #Deep faults receive a higher stress
    stress_multiplier = 3

    print('... working on ' + component +
          ' component semistochastic waveform for station ' + sta)

    #initalize output seismogram
    tr = Trace()
    tr.stats.station = sta
    tr.stats.delta = hf_dt
    tr.stats.starttime = time_epi
    #info for sac header (added at the end)
    az, backaz, dist_m = g.inv(epicenter[0], epicenter[1], sta_lon, sta_lat)
    dist_in_km = dist_m / 1000.

    hf = zeros(len(t))

    #    out='''Parameters before we get into subfault calculations:
    #    rupture_name = %s
    #    epicenter = %s
    #    time_epi = %s
    #    M0 = %E
    #    Mw = %10.4f
    #    Num_Subfaults = %i
    #    dl = %.2f
    #    Dist_in_km = %10.4f
    #    '''%(rupture_name,str(epicenter),str(time_epi),M0,Mw,int(N),dl,dist_in_km)
    #    print out
    #    logfile.write(out)

    #Loop over subfaults
    #    earliestP=1e10  #something outrageously high
    #    earliestP_kfault=1e10
    for kfault in range(len(fault)):

        #Print status to screen
        if kfault % 150 == 0:
            if kfault == 0:
                stdout.write('      [')
                stdout.flush()
            stdout.write('.')
            stdout.flush()
        if kfault == len(fault) - 1:
            stdout.write(']\n')
            stdout.flush()

        #Include only subfaults with non-zero slip
        if subfault_M0[kfault] > 0:

            #Get subfault to station distance
            lon_source = fault[kfault, 1]
            lat_source = fault[kfault, 2]
            azimuth, baz, dist = g.inv(lon_source, lat_source, sta_lon,
                                       sta_lat)
            dist_in_degs = kilometer2degrees(dist / 1000.)

            #Source depth?
            z_source = fault[kfault, 3]

            #No change
            stress = stress_parameter

            #Is subfault in an SMGA?
            #radius_in_km=15.0
            #smga_center_lon=-69.709200
            #smga_center_lat=-19.683600
            #in_smga=is_subfault_in_smga(lon_source,lat_source,smga_center_lon,smga_center_lat,radius_in_km)
            #
            ###Apply multiplier?
            #if in_smga==True:
            #    stress=stress_parameter*stress_multiplier
            #    print "%.4f,%.4f is in SMGA, stress is %d" % (lon_source,lat_source,stress)
            #else:
            #    stress=stress_parameter

            #Apply multiplier?
            #if slip[kfault]>7.5:
            #    stress=stress_parameter*stress_multiplier
            ##elif lon_source>-72.057 and lon_source<-71.2 and lat_source>-30.28:
            ##    stress=stress_parameter*stress_multiplier
            #else:
            #    stress=stress_parameter

            #Apply multiplier?
            #if z_source>high_stress_depth:
            #    stress=stress_parameter*stress_multiplier
            #else:
            #    stress=stress_parameter

            # Frankel 95 scaling of corner frequency #verified this looks the same in GP
            # Right now this applies the same factor to all faults
            fc_scale = (M0) / (N * stress * dl**3 * 1e21)  #Frankel scaling
            small_event_M0 = stress * dl**3 * 1e21

            #Get rho, alpha, beta at subfault depth
            zs = fault[kfault, 3]
            mu, alpha, beta = get_mu(structure, zs, return_speeds=True)
            rho = mu / beta**2

            #Get radiation scale factor
            Spartition = 1 / 2**0.5
            if component == 'N':
                component_angle = 0
            elif component == 'E':
                component_angle = 90

            rho = rho / 1000  #to g/cm**3
            beta = (beta / 1000) * 1e5  #to cm/s
            alpha = (alpha / 1000) * 1e5

            #Verified this produces same value as in GP
            CS = (2 * Spartition) / (4 * pi * (rho) * (beta**3))
            CP = 2 / (4 * pi * (rho) * (alpha**3))

            #Get local subfault rupture speed
            beta = beta / 100  #to m/s
            vr = get_local_rupture_speed(zs, beta, rise_time_depths)
            vr = vr / 1000  #to km/s
            dip_factor = get_dip_factor(fault[kfault, 5], fault[kfault, 8],
                                        fault[kfault, 9])

            #Subfault corner frequency
            c0 = 2.0  #GP2015 value
            fc_subfault = (c0 * vr) / (dip_factor * pi * dl)

            #get subfault source spectrum
            #S=((relative_subfault_M0[kfault]*M0/N)*f**2)/(1+fc_scale*(f/fc_subfault)**2)
            S = small_event_M0 * (omega**2 / (1 + (f / fc_subfault)**2))
            frankel_conv_operator = fc_scale * (
                (fc_subfault**2 + f**2) / (fc_subfault**2 + fc_scale * f**2))
            S = S * frankel_conv_operator

            #get high frequency decay
            P = exp(-pi * kappa * f)

            #            if kfault==0:
            #                out='''Parameters within subfault calculations:
            #                kfault_lon = %10.4f
            #                kfault_lat = %10.4f
            #                CS = %s
            #                CP = %s
            #                S[0] = %s
            #                frankel_conv_operator[0] = %s
            #                '''%(fault[kfault,1],fault[kfault,2],str(CS),str(CP),str(S[0]),str(frankel_conv_operator[0]))
            #                print out
            #                logfile.write(out)

            #Get other geometric parameters necessar for radiation pattern
            strike = fault[kfault, 4]
            dip = fault[kfault, 5]
            ss = fault[kfault, 8]
            ds = fault[kfault, 9]
            rake = rad2deg(arctan2(ds, ss))

            #Get ray paths for all direct P arrivals
            Ppaths = velmod.get_ray_paths(zs,
                                          dist_in_degs,
                                          phase_list=['P', 'p'])

            #Get ray paths for all direct S arrivals
            try:
                Spaths = velmod.get_ray_paths(zs,
                                              dist_in_degs,
                                              phase_list=['S', 's'])
            except:
                Spaths = velmod.get_ray_paths(zs + tau_perturb,
                                              dist_in_degs,
                                              phase_list=['S', 's'])

            #sometimes there's no S, weird I know. Check twice.
            if len(Spaths) == 0:
                Spaths = velmod.get_ray_paths(zs + tau_perturb,
                                              dist_in_degs,
                                              phase_list=['S', 's'])
            if len(Spaths) == 0:
                Spaths = velmod.get_ray_paths(zs + 5 * tau_perturb,
                                              dist_in_degs,
                                              phase_list=['S', 's'])
            if len(Spaths) == 0:
                Spaths = velmod.get_ray_paths(zs - 5 * tau_perturb,
                                              dist_in_degs,
                                              phase_list=['S', 's'])
            if len(Spaths) == 0:
                Spaths = velmod.get_ray_paths(zs + 5 * tau_perturb,
                                              dist_in_degs,
                                              phase_list=['S', 's'])
            if len(Spaths) == 0:
                Spaths = velmod.get_ray_paths(zs - 10 * tau_perturb,
                                              dist_in_degs,
                                              phase_list=['S', 's'])
            if len(Spaths) == 0:
                Spaths = velmod.get_ray_paths(zs + 10 * tau_perturb,
                                              dist_in_degs,
                                              phase_list=['S', 's'])
            if len(Spaths) == 0:
                Spaths = velmod.get_ray_paths(zs - 50 * tau_perturb,
                                              dist_in_degs,
                                              phase_list=['S', 's'])
            if len(Spaths) == 0:
                Spaths = velmod.get_ray_paths(zs + 50 * tau_perturb,
                                              dist_in_degs,
                                              phase_list=['S', 's'])
            if len(Spaths) == 0:
                Spaths = velmod.get_ray_paths(zs - 75 * tau_perturb,
                                              dist_in_degs,
                                              phase_list=['S', 's'])
            if len(Spaths) == 0:
                Spaths = velmod.get_ray_paths(zs + 75 * tau_perturb,
                                              dist_in_degs,
                                              phase_list=['S', 's'])
            if len(Spaths) == 0:
                print(
                    'ERROR: I give up, no direct S in spite of multiple attempts at subfault '
                    + str(kfault))

            #Get direct s path and moho reflection
            mohoS = None
            directS = Spaths[0]
            directP = Ppaths[0]
            #print len(Spaths)
            if len(Spaths) == 1:  #only direct S
                pass
            else:
                #turn_depth=zeros(len(Spaths)-1) #turning depth of other non-direct rays
                #for k in range(1,len(Spaths)):
                #    turn_depth[k-1]=Spaths[k].path['depth'].max()
                ##If there's a ray that turns within 2km of Moho, callt hat guy the Moho reflection
                #deltaz=abs(turn_depth-moho_depth_in_km)
                #i=argmin(deltaz)
                #if deltaz[i]<2: #Yes, this is a moho reflection
                #    mohoS=Spaths[i+1]
                #else:
                #    mohoS=None
                mohoS = Spaths[-1]

            #######         Build Direct P ray           ######
            if Pwave == True:
                take_off_angle_P = directP.takeoff_angle

                #Get attenuation due to geometrical spreading (from the path length)
                path_length_P = get_path_length(directP, zs, dist_in_degs)
                path_length_P = path_length_P * 100  #to cm

                #Get effect of intrinsic attenuation for that ray (path integrated)
                Q_P = get_attenuation(f, structure, directP, Qexp, Qtype='P')

                #get quarter wavelength amplificationf actors
                # pass rho in kg/m^3 (this units nightmare is what I get for following Graves' code)
                I_P = get_amplification_factors(f, structure, zs, alpha,
                                                rho * 1000)

                #Build the entire path term
                G_P = (I_P * Q_P) / path_length_P

                #Get conically averaged radiation pattern terms
                RP = conically_avg_P_radiation_pattern(strike, dip, rake,
                                                       azimuth,
                                                       take_off_angle_P)
                RP = abs(RP)

                #Get partition of Pwave into Z and N,E components
                incidence_angle = directP.incident_angle
                Npartition, Epartition, Zpartition = get_P_wave_partition(
                    incidence_angle, azimuth)
                if component == 'Z':
                    Ppartition = Zpartition
                elif component == 'N':
                    Ppartition = Npartition
                else:
                    Ppartition = Epartition

                #And finally multiply everything together to get the subfault amplitude spectrum
                AP = CP * S * G_P * P * RP * Ppartition

                #Generate windowed time series
                duration = 1. / fc_subfault + 0.09 * (dist / 1000)
                w = windowed_gaussian(duration,
                                      hf_dt,
                                      window_type='saragoni_hart')

                #Go to frequency domain, apply amplitude spectrum and ifft for final time series
                hf_seis_P = apply_spectrum(w, AP, f, hf_dt)

                #What time after OT should this time series start at?
                time_insert = directP.path['time'][-1] + onset_times[kfault]
                #                if directP.time+onset_times[kfault] < earliestP:
                #                    earliestP=directP.time+onset_times[kfault]
                #                    earliestP_kfault=kfault
                i = argmin(abs(t - time_insert))
                j = i + len(hf_seis_P)

                #Check seismogram doesn't go past last sample
                if i < len(
                        hf
                ) - 1:  #if i (the beginning of the seimogram) is less than the length
                    if j > len(
                            hf
                    ):  #seismogram goes past total_duration length, trim it
                        len_paste = len(hf) - i
                        j = len(hf)
                        #Add seismogram
                        hf[i:j] = hf[i:j] + real(hf_seis_P[0:len_paste])
                    else:  #Lengths are fine
                        hf[i:j] = hf[i:j] + real(hf_seis_P)
                else:  #Seismogram starts after end of available space
                    pass

            #######         Build Direct S ray           ######
            if Swave == True:
                take_off_angle_S = directS.takeoff_angle

                #Get attenuation due to geometrical spreading (from the path length)
                path_length_S = get_path_length(directS, zs, dist_in_degs)
                path_length_S = path_length_S * 100  #to cm

                #Get effect of intrinsic aptimeenuation for that ray (path integrated)
                Q_S = get_attenuation(f, structure, directS, Qexp)

                #get quarter wavelength amplificationf actors
                # pass rho in kg/m^3 (this units nightmare is what I get for following Graves' code)
                I_S = get_amplification_factors(f, structure, zs, beta,
                                                rho * 1000)
                #Build the entire path term
                G_S = (I_S * Q_S) / path_length_S

                #Get conically averaged radiation pattern terms
                if component == 'Z':
                    RP_vert = conically_avg_vert_radiation_pattern(
                        strike, dip, rake, azimuth, take_off_angle_S)
                    #And finally multiply everything together to get the subfault amplitude spectrum
                    AS = CS * S * G_S * P * RP_vert
                else:
                    RP = conically_avg_radiation_pattern(
                        strike, dip, rake, azimuth, take_off_angle_S,
                        component_angle)
                    RP = abs(RP)
                    #And finally multiply everything together to get the subfault amplitude spectrum
                    AS = CS * S * G_S * P * RP

                #Generate windowed time series
                duration = 1. / fc_subfault + 0.063 * (dist / 1000)
                w = windowed_gaussian(duration,
                                      hf_dt,
                                      window_type='saragoni_hart')
                #w=windowed_gaussian(3*duration,hf_dt,window_type='cua',ptime=Ppaths[0].path['time'][-1],stime=Spaths[0].path['time'][-1])

                #Go to frequency domain, apply amplitude spectrum and ifft for final time series
                hf_seis_S = apply_spectrum(w, AS, f, hf_dt)

                #What time after OT should this time series start at?
                time_insert = directS.path['time'][-1] + onset_times[kfault]
                #print 'ts = '+str(time_insert)+' , Td = '+str(duration)
                #time_insert=Ppaths[0].path['time'][-1]
                i = argmin(abs(t - time_insert))
                j = i + len(hf_seis_S)

                #Check seismogram doesn't go past last sample
                if i < len(
                        hf
                ) - 1:  #if i (the beginning of the seimogram) is less than the length
                    if j > len(
                            hf
                    ):  #seismogram goes past total_duration length, trim it
                        len_paste = len(hf) - i
                        j = len(hf)
                        #Add seismogram
                        hf[i:j] = hf[i:j] + real(hf_seis_S[0:len_paste])
                    else:  #Lengths are fine
                        hf[i:j] = hf[i:j] + real(hf_seis_S)
                else:  #Beginning of seismogram is past end of available space
                    pass

            #######         Build Moho reflected S ray           ######


#            if mohoS==None:
#                pass
#            else:
#                if kfault%100==0:
#                    print '... ... building Moho reflected S wave'
#                take_off_angle_mS=mohoS.takeoff_angle
#
#                #Get attenuation due to geometrical spreading (from the path length)
#                path_length_mS=get_path_length(mohoS,zs,dist_in_degs)
#                path_length_mS=path_length_mS*100 #to cm
#
#                #Get effect of intrinsic aptimeenuation for that ray (path integrated)
#                Q_mS=get_attenuation(f,structure,mohoS,Qexp)
#
#                #Build the entire path term
#                G_mS=(I*Q_mS)/path_length_mS
#
#                #Get conically averaged radiation pattern terms
#                if component=='Z':
#                    RP_vert=conically_avg_vert_radiation_pattern(strike,dip,rake,azimuth,take_off_angle_mS)
#                    #And finally multiply everything together to get the subfault amplitude spectrum
#                    A=C*S*G_mS*P*RP_vert
#                else:
#                    RP=conically_avg_radiation_pattern(strike,dip,rake,azimuth,take_off_angle_mS,component_angle)
#                    RP=abs(RP)
#                    #And finally multiply everything together to get the subfault amplitude spectrum
#                    A=C*S*G_mS*P*RP
#
#                #Generate windowed time series
#                duration=1./fc_subfault+0.063*(dist/1000)
#                w=windowed_gaussian(duration,hf_dt,window_type='saragoni_hart')
#                #w=windowed_gaussian(3*duration,hf_dt,window_type='cua',ptime=Ppaths[0].path['time'][-1],stime=Spaths[0].path['time'][-1])
#
#                #Go to frequency domain, apply amplitude spectrum and ifft for final time series
#                hf_seis=apply_spectrum(w,A,f,hf_dt)
#
#                #What time after OT should this time series start at?
#                time_insert=mohoS.path['time'][-1]+onset_times[kfault]
#                #print 'ts = '+str(time_insert)+' , Td = '+str(duration)
#                #time_insert=Ppaths[0].path['time'][-1]
#                i=argmin(abs(t-time_insert))
#                j=i+len(hf_seis)
#
#                #Add seismogram
#                hf[i:j]=hf[i:j]+hf_seis
#
#                #Done, reset
#                mohoS=None
#        if kfault==0:
#            out=''' More:
#            fc_scale = %10.4f
#            subfaultM0 = %E
#            mu = %E
#            CS = %E
#            CP = %E
#            vr = %10.4f
#            dip_factor = %10.4f
#            fc_subfault = %10.4f
#            directS = %s
#            directP = %s
#            '''%(fc_scale,subfault_M0[kfault],mu,CS,CP,vr,dip_factor,fc_subfault,str(directS.time),str(directP.time))
#            print out
#            logfile.write(out)
#    logfile.close()
#Done
    tr.data = hf / 100  #convert to m/s**2
    #Add station location, event location, and first P-wave arrival time to SAC header
    tr.stats.update({
        'sac': {
            'stlo': sta_lon,
            'stla': sta_lat,
            'evlo': epicenter[0],
            'evla': epicenter[1],
            'evdp': epicenter[2],
            'dist': dist_in_km,
            'az': az,
            'baz': backaz,
            'mag': Mw
        }
    })  #,'idep':"ACC (m/s^2)" not sure why idep won't work
    #Return trace for writing to file
    #    print "Earliest P wave Comes at " + str(earliestP) + "after OT, from location " + str(fault[earliestP_kfault,1]) + ", " + str(fault[earliestP_kfault,2]) + ", " +str(fault[earliestP_kfault,3])
    return tr
Пример #31
0
def stochastic_simulation(home,project_name,rupture_name,sta,sta_lon,sta_lat,component,model_name,
        rise_time_depths,moho_depth_in_km,total_duration=100,hf_dt=0.01,stress_parameter=50,
        kappa=0.04,Qexp=0.6,Pwave=False,high_stress_depth=1e4): 
    '''
    Run stochastic HF sims
    
    stress parameter is in bars
    '''
    
    from numpy import genfromtxt,pi,logspace,log10,mean,where,exp,arange,zeros,argmin,rad2deg,arctan2,real
    from pyproj import Geod
    from obspy.geodetics import kilometer2degrees
    from obspy.taup import TauPyModel
    from mudpy.forward import get_mu, write_fakequakes_hf_waveforms_one_by_one,read_fakequakes_hypo_time
    from obspy import Stream,Trace
    from sys import stdout
    import warnings


    #print out what's going on:
    out='''Running with input parameters:
    home = %s
    project_name = %s
    rupture_name = %s
    sta = %s
    sta_lon = %s
    sta_lat = %s
    model_name = %s
    rise_time_depths = %s
    moho_depth_in_km = %s
    total_duration = %s
    hf_dt = %s
    stress_parameter = %s
    kappa = %s
    Qexp = %s
    component = %s
    Pwave = %s
    high_stress_depth = %s
    '''%(home,project_name,rupture_name,sta,str(sta_lon),str(sta_lat),model_name,str(rise_time_depths),
    str(moho_depth_in_km),str(total_duration),str(hf_dt),str(stress_parameter),
    str(kappa),str(Qexp),str(component),str(Pwave),str(high_stress_depth))
    print out

#    rupture=rupture_name.split('.')[0]+'.'+rupture_name.split('.')[1]
#    log=home+project_name+'/output/waveforms/'+rupture+'/'+sta+'.HN'+component+'.1cpu.log'
#    logfile=open(log,'w')
#    logfile.write(out)
    #print 'stress is '+str(stress_parameter)

    #I don't condone it but this cleans up the warnings
    warnings.filterwarnings("ignore")
    
    #Load the source
    fault=genfromtxt(home+project_name+'/output/ruptures/'+rupture_name)    
    
    #Onset times for each subfault
    onset_times=fault[:,12]
    
    #load velocity structure
    structure=genfromtxt(home+project_name+'/structure/'+model_name)
    
    #Frequencies vector
    f=logspace(log10(hf_dt),log10(1/(2*hf_dt))+0.01,50)
    omega=2*pi*f
    
    #Output time vector (0 is origin time)
    t=arange(0,total_duration,hf_dt)
    
    #Projection object for distance calculations
    g=Geod(ellps='WGS84')
    
    #Create taup velocity model object, paste on top of iaspei91
    #taup_create.build_taup_model(home+project_name+'/structure/bbp_norcal.tvel',output_folder=home+project_name+'/structure/')
    velmod=TauPyModel(model=home+project_name+'/structure/maule',verbose=True)
    #Get epicentral time
    epicenter,time_epi=read_fakequakes_hypo_time(home,project_name,rupture_name)
    
    #Moments
    slip=(fault[:,8]**2+fault[:,9]**2)**0.5
    subfault_M0=slip*fault[:,10]*fault[:,11]*fault[:,13]
    subfault_M0=subfault_M0*1e7 #to dyne-cm
    M0=subfault_M0.sum()
    relative_subfault_M0=subfault_M0/M0
    Mw=(2./3)*(log10(M0*1e-7)-9.1)
    
    #Corner frequency scaling
    i=where(slip>0)[0] #Non-zero faults
    N=len(i) #number of subfaults
    dl=mean((fault[:,10]+fault[:,11])/2) #predominant length scale
    dl=dl/1000 # to km
    
    #Tau=p perturbation
    tau_perturb=0.1
    
    #Deep faults receive a higher stress
    stress_multiplier=3
         
    print '... working on '+component+' component semistochastic waveform for station '+sta

    #initalize output seismogram
    tr=Trace()
    tr.stats.station=sta
    tr.stats.delta=hf_dt
    tr.stats.starttime=time_epi
    #info for sac header (added at the end)
    az,backaz,dist_m=g.inv(epicenter[0],epicenter[1],sta_lon,sta_lat)
    dist_in_km=dist_m/1000.    
    
    hf=zeros(len(t))
    
#    out='''Parameters before we get into subfault calculations:
#    rupture_name = %s
#    epicenter = %s
#    time_epi = %s
#    M0 = %E
#    Mw = %10.4f
#    Num_Subfaults = %i
#    dl = %.2f
#    Dist_in_km = %10.4f
#    '''%(rupture_name,str(epicenter),str(time_epi),M0,Mw,int(N),dl,dist_in_km)
#    print out
#    logfile.write(out)
    
    #Loop over subfaults
#    earliestP=1e10  #something outrageously high
#    earliestP_kfault=1e10
    for kfault in range(len(fault)):
        
        #Print status to screen            
        if kfault % 150 == 0:
            if kfault==0:
                stdout.write('      [')
                stdout.flush()
            stdout.write('.')
            stdout.flush()
        if kfault==len(fault)-1:
            stdout.write(']\n')
            stdout.flush()                
        
        #Include only subfaults with non-zero slip
        if subfault_M0[kfault]>0:
            
            #Get subfault to station distance
            lon_source=fault[kfault,1]
            lat_source=fault[kfault,2]
            azimuth,baz,dist=g.inv(lon_source,lat_source,sta_lon,sta_lat)
            dist_in_degs=kilometer2degrees(dist/1000.)
            
            #Source depth?
            z_source=fault[kfault,3]
            
            #No change
            stress=stress_parameter
            
            #Is subfault in an SMGA?
            #radius_in_km=15.0
            #smga_center_lon=-69.709200
            #smga_center_lat=-19.683600
            #in_smga=is_subfault_in_smga(lon_source,lat_source,smga_center_lon,smga_center_lat,radius_in_km)
            #
            ###Apply multiplier?
            #if in_smga==True:
            #    stress=stress_parameter*stress_multiplier
            #    print "%.4f,%.4f is in SMGA, stress is %d" % (lon_source,lat_source,stress)
            #else:
            #    stress=stress_parameter
            
            #Apply multiplier?
            #if slip[kfault]>7.5:
            #    stress=stress_parameter*stress_multiplier
            ##elif lon_source>-72.057 and lon_source<-71.2 and lat_source>-30.28:
            ##    stress=stress_parameter*stress_multiplier
            #else:
            #    stress=stress_parameter
                
            #Apply multiplier?
            #if z_source>high_stress_depth:
            #    stress=stress_parameter*stress_multiplier
            #else:
            #    stress=stress_parameter
            
            # Frankel 95 scaling of corner frequency #verified this looks the same in GP
            # Right now this applies the same factor to all faults
            fc_scale=(M0)/(N*stress*dl**3*1e21) #Frankel scaling
            small_event_M0 = stress*dl**3*1e21
            
        

            
            #Get rho, alpha, beta at subfault depth
            zs=fault[kfault,3]
            mu,alpha,beta=get_mu(structure,zs,return_speeds=True)
            rho=mu/beta**2
            
            #Get radiation scale factor
            Spartition=1/2**0.5
            if component=='N' :
                component_angle=0
            elif component=='E':
                component_angle=90
            
            rho=rho/1000 #to g/cm**3
            beta=(beta/1000)*1e5 #to cm/s
            alpha=(alpha/1000)*1e5
            
            #Verified this produces same value as in GP
            CS=(2*Spartition)/(4*pi*(rho)*(beta**3))
            CP=2/(4*pi*(rho)*(alpha**3))
            
            #Get local subfault rupture speed
            beta=beta/100 #to m/s
            vr=get_local_rupture_speed(zs,beta,rise_time_depths)
            vr=vr/1000 #to km/s
            dip_factor=get_dip_factor(fault[kfault,5],fault[kfault,8],fault[kfault,9])
            
            #Subfault corner frequency
            c0=2.0 #GP2015 value
            fc_subfault=(c0*vr)/(dip_factor*pi*dl)
            
            #get subfault source spectrum
            #S=((relative_subfault_M0[kfault]*M0/N)*f**2)/(1+fc_scale*(f/fc_subfault)**2)
            S=small_event_M0*(omega**2/(1+(f/fc_subfault)**2))
            frankel_conv_operator= fc_scale*((fc_subfault**2+f**2)/(fc_subfault**2+fc_scale*f**2))
            S=S*frankel_conv_operator
            
            #get high frequency decay
            P=exp(-pi*kappa*f)
            
            #get quarter wavelength amplificationf actors
            # pass rho in kg/m^3 (this units nightmare is what I get for following Graves' code)
            I=get_amplification_factors(f,structure,zs,beta,rho*1000)
            
#            if kfault==0:
#                out='''Parameters within subfault calculations:
#                kfault_lon = %10.4f
#                kfault_lat = %10.4f
#                CS = %s
#                CP = %s
#                S[0] = %s
#                frankel_conv_operator[0] = %s
#                '''%(fault[kfault,1],fault[kfault,2],str(CS),str(CP),str(S[0]),str(frankel_conv_operator[0]))
#                print out
#                logfile.write(out)
            
            #Get other geometric parameters necessar for radiation pattern
            strike=fault[kfault,4]
            dip=fault[kfault,5]
            ss=fault[kfault,8]
            ds=fault[kfault,9]
            rake=rad2deg(arctan2(ds,ss))
            
            #Get ray paths for all direct P arrivals
            Ppaths=velmod.get_ray_paths(zs,dist_in_degs,phase_list=['P','p'])
            
            #Get ray paths for all direct S arrivals
            try:
                Spaths=velmod.get_ray_paths(zs,dist_in_degs,phase_list=['S','s'])
            except:
                Spaths=velmod.get_ray_paths(zs+tau_perturb,dist_in_degs,phase_list=['S','s'])
                
            #sometimes there's no S, weird I know. Check twice.
            if len(Spaths)==0:
                Spaths=velmod.get_ray_paths(zs+tau_perturb,dist_in_degs,phase_list=['S','s'])
            if len(Spaths)==0:
                Spaths=velmod.get_ray_paths(zs+5*tau_perturb,dist_in_degs,phase_list=['S','s'])   
            if len(Spaths)==0:
                Spaths=velmod.get_ray_paths(zs-5*tau_perturb,dist_in_degs,phase_list=['S','s'])
            if len(Spaths)==0:
                Spaths=velmod.get_ray_paths(zs+5*tau_perturb,dist_in_degs,phase_list=['S','s'])  
            if len(Spaths)==0:
                Spaths=velmod.get_ray_paths(zs-10*tau_perturb,dist_in_degs,phase_list=['S','s'])
            if len(Spaths)==0:
                Spaths=velmod.get_ray_paths(zs+10*tau_perturb,dist_in_degs,phase_list=['S','s']) 
            if len(Spaths)==0:
                Spaths=velmod.get_ray_paths(zs-50*tau_perturb,dist_in_degs,phase_list=['S','s'])
            if len(Spaths)==0:
                Spaths=velmod.get_ray_paths(zs+50*tau_perturb,dist_in_degs,phase_list=['S','s']) 
            if len(Spaths)==0:
                Spaths=velmod.get_ray_paths(zs-75*tau_perturb,dist_in_degs,phase_list=['S','s'])
            if len(Spaths)==0:
                Spaths=velmod.get_ray_paths(zs+75*tau_perturb,dist_in_degs,phase_list=['S','s']) 
            if len(Spaths)==0:
                print 'ERROR: I give up, no direct S in spite of multiple attempts at subfault '+str(kfault)

            #Get direct s path and moho reflection
            mohoS=None
            directS=Spaths[0]
            directP=Ppaths[0]
            #print len(Spaths)
            if len(Spaths)==1: #only direct S
                pass
            else:
                #turn_depth=zeros(len(Spaths)-1) #turning depth of other non-direct rays
                #for k in range(1,len(Spaths)):
                #    turn_depth[k-1]=Spaths[k].path['depth'].max()
                ##If there's a ray that turns within 2km of Moho, callt hat guy the Moho reflection
                #deltaz=abs(turn_depth-moho_depth_in_km)
                #i=argmin(deltaz)
                #if deltaz[i]<2: #Yes, this is a moho reflection
                #    mohoS=Spaths[i+1]
                #else:
                #    mohoS=None
                mohoS=Spaths[-1]
                 
 
            #######         Build Direct P ray           ######
            if Pwave==True:
                take_off_angle_P=directP.takeoff_angle
                
                #Get attenuation due to geometrical spreading (from the path length)
                path_length_P=get_path_length(directP,zs,dist_in_degs)
                path_length_P=path_length_P*100 #to cm
                
                #Get effect of intrinsic attenuation for that ray (path integrated)
                Q_P=get_attenuation(f,structure,directS,Qexp,Qtype='P')
                
                #Build the entire path term
                G_P=(I*Q_P)/path_length_P

                #Get conically averaged radiation pattern terms
                RP=conically_avg_P_radiation_pattern(strike,dip,rake,azimuth,take_off_angle_P)
                RP=abs(RP)
                   
                #Get partition of Pwave into Z and N,E components 
                incidence_angle=directP.incident_angle
                Npartition,Epartition,Zpartition=get_P_wave_partition(incidence_angle,azimuth)
                if component=='Z':
                   Ppartition=Zpartition 
                elif component=='N':
                    Ppartition=Npartition
                else:
                    Ppartition=Epartition
                    
                #And finally multiply everything together to get the subfault amplitude spectrum
                AP=CP*S*G_P*P*RP*Ppartition           

                #Generate windowed time series
                duration=1./fc_subfault+0.09*(dist/1000)
                w=windowed_gaussian(duration,hf_dt,window_type='saragoni_hart')
                
                #Go to frequency domain, apply amplitude spectrum and ifft for final time series
                hf_seis_P=apply_spectrum(w,AP,f,hf_dt)
                
                #What time after OT should this time series start at?
                time_insert=directP.path['time'][-1]+onset_times[kfault]
#                if directP.time+onset_times[kfault] < earliestP:
#                    earliestP=directP.time+onset_times[kfault]
#                    earliestP_kfault=kfault
                i=argmin(abs(t-time_insert))
                j=i+len(hf_seis_P)
                
                #Check seismogram doesn't go past last sample
                if i<len(hf)-1: #if i (the beginning of the seimogram) is less than the length
                    if j>len(hf): #seismogram goes past total_duration length, trim it
                        len_paste=len(hf)-i
                        j=len(hf)
                        #Add seismogram
                        hf[i:j]=hf[i:j]+real(hf_seis_P[0:len_paste])
                    else: #Lengths are fine
                        hf[i:j]=hf[i:j]+real(hf_seis_P)      
                else: #Seismogram starts after end of available space
                    pass   
                
                                           
                                                                  
                                                                                                                
                          
            #######         Build Direct S ray           ######
            take_off_angle_S=directS.takeoff_angle
            
            #Get attenuation due to geometrical spreading (from the path length)
            path_length_S=get_path_length(directS,zs,dist_in_degs)
            path_length_S=path_length_S*100 #to cm
            
            #Get effect of intrinsic aptimeenuation for that ray (path integrated)
            Q_S=get_attenuation(f,structure,directS,Qexp)
            
            #Build the entire path term
            G_S=(I*Q_S)/path_length_S

            #Get conically averaged radiation pattern terms
            if component=='Z':
                RP_vert=conically_avg_vert_radiation_pattern(strike,dip,rake,azimuth,take_off_angle_S)
                #And finally multiply everything together to get the subfault amplitude spectrum
                AS=CS*S*G_S*P*RP_vert   
            else:
                RP=conically_avg_radiation_pattern(strike,dip,rake,azimuth,take_off_angle_S,component_angle)
                RP=abs(RP)
                #And finally multiply everything together to get the subfault amplitude spectrum
                AS=CS*S*G_S*P*RP                

            #Generate windowed time series
            duration=1./fc_subfault+0.063*(dist/1000)
            w=windowed_gaussian(duration,hf_dt,window_type='saragoni_hart')
            #w=windowed_gaussian(3*duration,hf_dt,window_type='cua',ptime=Ppaths[0].path['time'][-1],stime=Spaths[0].path['time'][-1])
            
            #Go to frequency domain, apply amplitude spectrum and ifft for final time series
            hf_seis_S=apply_spectrum(w,AS,f,hf_dt)
            
            #What time after OT should this time series start at?
            time_insert=directS.path['time'][-1]+onset_times[kfault]
            #print 'ts = '+str(time_insert)+' , Td = '+str(duration)
            #time_insert=Ppaths[0].path['time'][-1]
            i=argmin(abs(t-time_insert))
            j=i+len(hf_seis_S)
            
            
            #Check seismogram doesn't go past last sample
            if i<len(hf)-1: #if i (the beginning of the seimogram) is less than the length
                if j>len(hf): #seismogram goes past total_duration length, trim it
                    len_paste=len(hf)-i
                    j=len(hf)
                    #Add seismogram
                    hf[i:j]=hf[i:j]+real(hf_seis_S[0:len_paste])
                else: #Lengths are fine
                    hf[i:j]=hf[i:j]+real(hf_seis_S)
            else: #Beginning of seismogram is past end of available space
                pass
            
            
            #######         Build Moho reflected S ray           ######
#            if mohoS==None:
#                pass
#            else:
#                if kfault%100==0:
#                    print '... ... building Moho reflected S wave'
#                take_off_angle_mS=mohoS.takeoff_angle
#                
#                #Get attenuation due to geometrical spreading (from the path length)
#                path_length_mS=get_path_length(mohoS,zs,dist_in_degs)
#                path_length_mS=path_length_mS*100 #to cm
#                
#                #Get effect of intrinsic aptimeenuation for that ray (path integrated)
#                Q_mS=get_attenuation(f,structure,mohoS,Qexp)
#                
#                #Build the entire path term
#                G_mS=(I*Q_mS)/path_length_mS
#
#                #Get conically averaged radiation pattern terms
#                if component=='Z':
#                    RP_vert=conically_avg_vert_radiation_pattern(strike,dip,rake,azimuth,take_off_angle_mS)
#                    #And finally multiply everything together to get the subfault amplitude spectrum
#                    A=C*S*G_mS*P*RP_vert   
#                else:
#                    RP=conically_avg_radiation_pattern(strike,dip,rake,azimuth,take_off_angle_mS,component_angle)
#                    RP=abs(RP)
#                    #And finally multiply everything together to get the subfault amplitude spectrum
#                    A=C*S*G_mS*P*RP                
#
#                #Generate windowed time series
#                duration=1./fc_subfault+0.063*(dist/1000)
#                w=windowed_gaussian(duration,hf_dt,window_type='saragoni_hart')
#                #w=windowed_gaussian(3*duration,hf_dt,window_type='cua',ptime=Ppaths[0].path['time'][-1],stime=Spaths[0].path['time'][-1])
#                
#                #Go to frequency domain, apply amplitude spectrum and ifft for final time series
#                hf_seis=apply_spectrum(w,A,f,hf_dt)
#                
#                #What time after OT should this time series start at?
#                time_insert=mohoS.path['time'][-1]+onset_times[kfault]
#                #print 'ts = '+str(time_insert)+' , Td = '+str(duration)
#                #time_insert=Ppaths[0].path['time'][-1]
#                i=argmin(abs(t-time_insert))
#                j=i+len(hf_seis)
#                
#                #Add seismogram
#                hf[i:j]=hf[i:j]+hf_seis
#                
#                #Done, reset
#                mohoS=None        
#        if kfault==0:
#            out=''' More:
#            fc_scale = %10.4f
#            subfaultM0 = %E
#            mu = %E
#            CS = %E
#            CP = %E
#            vr = %10.4f
#            dip_factor = %10.4f
#            fc_subfault = %10.4f
#            directS = %s
#            directP = %s
#            '''%(fc_scale,subfault_M0[kfault],mu,CS,CP,vr,dip_factor,fc_subfault,str(directS.time),str(directP.time))
#            print out
#            logfile.write(out)
#    logfile.close()
    #Done
    tr.data=hf/100 #convert to m/s**2
    #Add station location, event location, and first P-wave arrival time to SAC header
    tr.stats.update({'sac':{'stlo':sta_lon,'stla':sta_lat,'evlo':epicenter[0],'evla':epicenter[1],'evdp':epicenter[2],'dist':dist_in_km,'az':az,'baz':backaz,'mag':Mw}}) #,'idep':"ACC (m/s^2)" not sure why idep won't work
    #Return trace for writing to file    
#    print "Earliest P wave Comes at " + str(earliestP) + "after OT, from location " + str(fault[earliestP_kfault,1]) + ", " + str(fault[earliestP_kfault,2]) + ", " +str(fault[earliestP_kfault,3])
    return tr
# radius of Earth in km
radius = 6371.

# regular time array in s, 1 s resolution
time = np.arange(0., 2000.)

# calculate through and save ray paths in interpolated time domain
save_paths = []
for p, phase in enumerate(phases_to_plot):
    dists_collected = []
    depths_collected = []
    for r, dist in enumerate(
            np.arange(rays_dist_min[p], rays_dist_max[p],
                      1)):  # resolution could be improved here
        # get raypaths
        rays = model.get_ray_paths(depth_earthquake, dist, phase_list=[phase])
        # Loop through rays found, some phases have multiple paths
        for ray in rays:
            # Interpolate to regulard time array
            dists = np.interp(time,
                              ray.path['time'],
                              ray.path['dist'],
                              left=np.nan,
                              right=np.nan)
            depths = np.interp(time,
                               ray.path['time'],
                               ray.path['depth'],
                               left=np.nan,
                               right=np.nan)
            # save paths
            dists_collected.append(dists)
Пример #33
0
    ('p', -10),
    ('pP', -37.5),
    ('s', -3),
    ('sP', -49),
    ('ScS', -44),
    ('SKS', -82),
    ('SKKS', -120),
]

model = TauPyModel(model='iasp91')

fig, ax = plt.subplots(subplot_kw=dict(polar=True))

# Plot all pre-determined phases
for phase, distance in PHASES:
    arrivals = model.get_ray_paths(700, distance, phase_list=[phase])
    ax = arrivals.plot_rays(plot_type='spherical',
                            legend=False, label_arrivals=True,
                            plot_all=True,
                            show=False, ax=ax)

# Annotate regions
ax.text(0, 0, 'Solid\ninner\ncore',
        horizontalalignment='center', verticalalignment='center',
        bbox=dict(facecolor='white', edgecolor='none', alpha=0.7))
ocr = (model.model.radius_of_planet -
       (model.model.s_mod.v_mod.iocb_depth +
        model.model.s_mod.v_mod.cmb_depth) / 2)
ax.text(np.deg2rad(180), ocr, 'Fluid outer core',
        horizontalalignment='center',
        bbox=dict(facecolor='white', edgecolor='none', alpha=0.7))
Пример #34
0
            FILTERLABEL,
            horizontalalignment='center',
            fontsize=10,
            multialignment='left',
            bbox=dict(boxstyle="round",
                      facecolor='#f2f2f2',
                      ec="0.5",
                      pad=0.5,
                      alpha=1))

if PLOT_PHASE_GLOBE:  # Add the inset picture of the globe at x, y, width, height, as a fraction of the parent plot
    if plotted_arrivals:
        ax1 = fig1.add_axes([0.68, 0.48, 0.4, 0.4], polar=True)
        for phase_time, phase_name, arrival_legend, color_plot, arrival_vertline in plotted_arrivals:
            arrivals = model.get_ray_paths(EVT_Z,
                                           STA_DEGREES,
                                           phase_list=[phase_name])
            if (len(arrivals)) > 1:
                m = (len(arrivals)) - 1
                arrivals = arrivals[:-m or
                                    None]  #If more than one of the same phase, use the earliers phase time
            ax1 = arrivals.plot_rays(plot_type='spherical',
                                     legend=True,
                                     label_arrivals=False,
                                     plot_all=True,
                                     show=False,
                                     ax=ax1)

        # Annotate regions of the globe
        ax1.text(0,
                 0,
Пример #35
0
   def migrate_3d(self,window_start=-10.0,window_end=100.0,perturbation_model='none'):

      '''
      Migrates receiver functions using a model with 3d heterogeneity.
      The only difference between migrate_3d and migrate_1d is that
      when migrate_3d calculates (time = time_phase - time_p), both 
      time_phase and time_p have been calculated by ray tracing through
      a 3d model

      #NOTE: This only currently is intended for stations along the equator.
      '''
      #preliminaries-----------------------------------------------------------
      eq_depth = self.ses3d_seismogram.sz/1000.0
      dist     = self.delta_deg
      d_start  = 50.0
      d_end    = 800.0
      dz       = 5
      depth = np.arange(d_start,d_end,dz)

      #taup model--------------------------------------------------------------
      model = TauPyModel(model='pyrolite_5km')
      value = np.zeros((len(depth)))

      #read velocity perturbation model----------------------------------------
      #    note, the specific shape of the input arrays are taken to
      #    match the output of velocity_conversion.py
      #------------------------------------------------------------------------
      to_radians  = np.pi/180.0
      to_degrees  = 180.0/np.pi
      npts_theta  = 201
      npts_rad    = 288
      theta       = np.linspace(0,10.0*to_radians,npts_theta)
      rad         = np.linspace(3490.0,6371.0,npts_rad)
      model_in  = np.loadtxt(perturbation_model)
      #model_in  = np.loadtxt(perturbation_model,skiprows=1)

      dvs_vector  = model_in[:,6]
      dvp_vector  = model_in[:,5]
      #dvs_vector  = model_in[:,3]
      #dvp_vector  = model_in[:,2]

      dvs_array   = np.zeros((npts_theta,npts_rad))
      dvp_array   = np.zeros((npts_theta,npts_rad))

      #define location of plume axis-------------------------------------------
      #TODO: change this so it's not necessary
      ax_theta = 45.0*to_radians
      
      #assign values from vector to array--------------------------------------
      k = 0
      for i in range(0,npts_rad):
         for j in range(0,npts_theta):
            dvs_array[j,i] = dvs_vector[k]
            dvp_array[j,i] = dvp_vector[k]
            k += 1

      #create interpolators----------------------------------------------------
      #   to call the interpolators, give theta in radians and radius in km
      #   where theta is the arc distance from a point to the plume axis
      #------------------------------------------------------------------------
      dvs_interpolator = interp2d(rad,theta,dvs_array,fill_value=0.0)
      dvp_interpolator = interp2d(rad,theta,dvp_array,fill_value=0.0)

      #calculate P travel time (only need to do once)--------------------------
      p_path   = model.get_ray_paths(eq_depth,dist,phase_list=['P'])
      p_path   = p_path[0]
      p_ref    = p_path.time
      p_ray_dist    = p_path.path['dist']
      p_ray_depth   = p_path.path['depth']
      p_ray_time    = p_path.path['time']

      #interpolate p path------------------------------------------------------
      i_len = 2000
      ray_dist_new = np.linspace(0,p_ray_dist[(len(p_ray_dist)-1)],i_len)
      #time
      f = interp1d(p_ray_dist, p_ray_time)
      p_ray_time = f(ray_dist_new)
      #depth
      f = interp1d(p_ray_dist, p_ray_depth)
      p_ray_depth = f(ray_dist_new)
      p_ray_dist = ray_dist_new

      p_time_total = 0.0
      path_len_total = 0.0

      #integrate along P path to determine time--------------------------------
      for i in range(0,len(p_ray_dist)-1):
         r_1 = 6371.0-p_ray_depth[i]
         r_2 = 6371.0-p_ray_depth[i+1]
         theta_1 = p_ray_dist[i]
         theta_2 = p_ray_dist[i+1]
         ray_seg_len = np.sqrt(r_1**2 + r_2**2 - 2*r_1*r_2*np.cos(theta_2-theta_1))
         time_seg    = p_ray_time[i+1] - p_ray_time[i]
         ray_seg_vel = ray_seg_len / time_seg

         #get heterogeneity for the current ray segment
         arc_dist1 = np.abs(ax_theta - theta_1)
         arc_dist2 = np.abs(ax_theta - theta_2)
         dv_1 = dvp_interpolator(r_1,arc_dist1)
         dv_2 = dvp_interpolator(r_2,arc_dist2)
         dv_here = (dv_1+dv_2)/2.0

         #add time-------------------------------------------------------------
         #if using absolute velocity perturbations
         time_here = ray_seg_len / (ray_seg_vel + dv_here)

         #if using percente velocity perturbations
         plume_velocity = ray_seg_vel + ray_seg_vel*(dv_here/100.0)
         time_here = ray_seg_len / plume_velocity

         p_time_total += time_here
         path_len_total += ray_seg_len

      #calculate each pds time-------------------------------------------------
      for i in range(0,len(depth)):

         #get path data
         phase    = 'P'+str(depth[i])+'s'
         pds_path = model.get_ray_paths(eq_depth,dist,phase_list=[phase])
         pds_path = pds_path[0]

         pds_ray_dist  = pds_path.path['dist']
         pds_ray_depth = pds_path.path['depth']
         pds_ray_time  = pds_path.path['time']

         #interpolate pds path----------------------------------------------------
         i_len = 500
         ray_dist_new = np.linspace(0,pds_ray_dist[(len(pds_ray_dist)-1)],i_len)
         #time
         f = interp1d(pds_ray_dist, pds_ray_time)
         pds_ray_time = f(ray_dist_new)
         #depth
         f = interp1d(pds_ray_dist, pds_ray_depth)
         pds_ray_depth = f(ray_dist_new)
         pds_ray_dist = ray_dist_new

         pds_time_total = 0.0

         for j in range(0,len(pds_ray_dist)-1):
            r_1 = 6371.0-pds_ray_depth[j]
            r_2 = 6371.0-pds_ray_depth[j+1]
            theta_1 = pds_ray_dist[j]
            theta_2 = pds_ray_dist[j+1]
            time_seg    = pds_ray_time[j+1] - pds_ray_time[j]
            ray_seg_len = np.sqrt(r_1**2 + r_2**2 - 2*r_1*r_2*np.cos(theta_2-theta_1))
            ray_seg_vel = ray_seg_len / time_seg


            #get heterogeneity for the current ray segment
            arc_dist1 = np.abs(ax_theta - theta_1)
            arc_dist2 = np.abs(ax_theta - theta_2)

            #determine branch
            if ray_seg_vel < 8.0: 
               dv_1 = dvs_interpolator(r_1,arc_dist1)
               dv_2 = dvs_interpolator(r_2,arc_dist2)
               dv_here = (dv_1+dv_2)/2.0
            elif ray_seg_vel >= 8.0: 
               dv_1 = dvp_interpolator(r_1,arc_dist1)
               dv_2 = dvp_interpolator(r_2,arc_dist2)
               dv_here = (dv_1+dv_2)/2.0

            #add time----------------------------------------------------------
            #if using absolute velocity perturbations
            time_here = ray_seg_len / (ray_seg_vel + dv_here)

            #if using percente velocity perturbations
            #plume_velocity = ray_seg_vel + ray_seg_vel*(dv_here/100.0)
            #time_here = ray_seg_len / plume_velocity

            pds_time_total += time_here
            path_len_total += ray_seg_len

         delay = pds_time_total-p_time_total
         #print "P time, Pds time, delay: ",phase,p_time_total,pds_time_total,delay
         #print "Predicted arrival times and delay :", p_path.time, pds_path.time, (pds_path.time-p_path.time)
         pds_delay = pds_time_total - pds_path.time
         print phase, pds_delay
         

         #map value at t = (p_time - pds_time) to depth------------------------
         i_start  = int((0.0 - window_start)/self.ses3d_seismogram.dt)
         i_t      = int(delay/self.ses3d_seismogram.dt) + i_start
         print i_t
         self.pierce_dict[i]['value'] = self.prf[i_t]
Пример #36
0
def stochastic_simulation(home,project_name,rupture_name,GF_list,time_epi,model_name,
        rise_time_depths,moho_depth_in_km,total_duration=100,hf_dt=0.01,stress_parameter=50,
        kappa=0.04,Qexp=0.6,component='N',Pwave=False): 
    '''
    Run stochastic HF sims
    
    stress parameter is in bars
    '''
    
    from numpy import genfromtxt,pi,logspace,log10,mean,where,exp,arange,zeros,argmin,rad2deg,arctan2
    from pyproj import Geod
    from obspy.geodetics import kilometer2degrees
    from obspy.taup import taup_create,TauPyModel
    from mudpy.forward import get_mu
    from obspy import Stream,Trace
    from matplotlib import pyplot as plt
    
    #initalize  output object
    st=Stream()
    
    #Load the source
    fault=genfromtxt(home+project_name+'/output/ruptures/'+rupture_name)    
    
    #Onset times for each subfault
    onset_times=fault[:,12]
    
    #Load stations
    sta=genfromtxt(home+project_name+'/data/station_info/'+GF_list,usecols=[0],dtype='S')
    lonlat=genfromtxt(home+project_name+'/data/station_info/'+GF_list,usecols=[1,2])
    
    #load velocity structure
    structure=genfromtxt(home+project_name+'/structure/'+model_name)
    
    #Frequencies vector
    f=logspace(log10(hf_dt),log10(1/(2*hf_dt))+0.01,50)
    omega=2*pi*f
    
    #Output time vector (0 is origin time)
    t=arange(0,total_duration,hf_dt)
    
    #Projection object for distance calculations
    g=Geod(ellps='WGS84')
    
    #Create taup velocity model object, paste on top of iaspei91
    #taup_create.build_taup_model(home+project_name+'/structure/bbp_norcal.tvel',output_folder=home+project_name+'/structure/')
    velmod=TauPyModel(model=home+project_name+'/structure/bbp_norcal',verbose=True)
    
    #Moments
    slip=(fault[:,8]**2+fault[:,9]**2)**0.5
    subfault_M0=slip*fault[:,10]*fault[:,11]*fault[:,13]
    subfault_M0=subfault_M0*1e7 #to dyne-cm
    M0=subfault_M0.sum()
    relative_subfault_M0=subfault_M0/M0
    
    #Corner frequency scaling
    i=where(slip>0)[0] #Non-zero faults
    N=len(i) #number of subfaults
    dl=mean((fault[:,10]+fault[:,11])/2) #perdominant length scale
    dl=dl/1000 # to km
    
    # Frankel 95 scaling of corner frequency #verified this looks the same in GP
    # Right now this applies the same factor to all faults
    # Move inside the loop with right dl????
    fc_scale=(M0)/(N*stress_parameter*dl**3*1e21) #Frankel scaling
    
    #Move this inisde loop?
    small_event_M0 = stress_parameter*dl**3*1e21
    
    #Tau=p perturbation
    tau_perturb=0.1
    
    #Loop over stations
    for ksta in range(len(lonlat)):
    
        print '... working on '+component+' component semistochastic waveform for station '+sta[ksta]
    
        #initalize output seismogram
        tr=Trace()
        tr.stats.station=sta[ksta]
        tr.stats.delta=hf_dt
        tr.stats.starttime=time_epi
        hf=zeros(len(t))
        
        #Loop over subfaults
        for kfault in range(len(fault)):
            
            #Include only subfaults with non-zero slip
            if subfault_M0[kfault]>0:
            
                #Get subfault to station distance
                lon_source=fault[kfault,1]
                lat_source=fault[kfault,2]
                azimuth,baz,dist=g.inv(lon_source,lat_source,lonlat[ksta,0],lonlat[ksta,1])
                dist_in_degs=kilometer2degrees(dist/1000.)
                
                #Get rho, alpha, beta at subfault depth
                zs=fault[kfault,3]
                mu,alpha,beta=get_mu(structure,zs,return_speeds=True)
                rho=mu/beta**2
                
                #Get radiation scale factor
                Spartition=1/2**0.5
                if component=='N' :
                    component_angle=0
                elif component=='E':
                    component_angle=90
                
                rho=rho/1000 #to g/cm**3
                beta=(beta/1000)*1e5 #to cm/s
                alpha=(alpha/1000)*1e5
                
                #Verified this produces same value as in GP
                CS=(2*Spartition)/(4*pi*(rho)*(beta**3))
                CP=2/(4*pi*(rho)*(alpha**3))
                
                #Get local subfault rupture speed
                beta=beta/100 #to m/s
                vr=get_local_rupture_speed(zs,beta,rise_time_depths)
                vr=vr/1000 #to km/s
                dip_factor=get_dip_factor(fault[kfault,5],fault[kfault,8],fault[kfault,9])
                
                #Subfault corner frequency
                c0=2.0 #GP2015 value
                fc_subfault=(c0*vr)/(dip_factor*pi*dl)
                
                #get subfault source spectrum
                #S=((relative_subfault_M0[kfault]*M0/N)*f**2)/(1+fc_scale*(f/fc_subfault)**2)
                S=small_event_M0*(omega**2/(1+(f/fc_subfault)**2))
                frankel_conv_operator= fc_scale*((fc_subfault**2+f**2)/(fc_subfault**2+fc_scale*f**2))
                S=S*frankel_conv_operator
                
                #get high frequency decay
                P=exp(-pi*kappa*f)
                
                #get quarter wavelength amplificationf actors
                # pass rho in kg/m^3 (this units nightmare is what I get for following Graves' code)
                I=get_amplification_factors(f,structure,zs,beta,rho*1000)
                
                #Get other geometric parameters necessar for radiation pattern
                strike=fault[kfault,4]
                dip=fault[kfault,5]
                ss=fault[kfault,8]
                ds=fault[kfault,9]
                rake=rad2deg(arctan2(ds,ss))
                
                #Get ray paths for all direct S arrivals
                Ppaths=velmod.get_ray_paths(zs,dist_in_degs,phase_list=['P','p'])
                
                #Get ray paths for all direct S arrivals
                try:
                    Spaths=velmod.get_ray_paths(zs,dist_in_degs,phase_list=['S','s'])
                except:
                    Spaths=velmod.get_ray_paths(zs+tau_perturb,dist_in_degs,phase_list=['S','s'])

                #Get direct s path and moho reflection
                mohoS=None
                directS=Spaths[0]
                directP=Ppaths[0]
                #print len(Spaths)
                if len(Spaths)==1: #only direct S
                    pass
                else:
                    #turn_depth=zeros(len(Spaths)-1) #turning depth of other non-direct rays
                    #for k in range(1,len(Spaths)):
                    #    turn_depth[k-1]=Spaths[k].path['depth'].max()
                    ##If there's a ray that turns within 2km of Moho, callt hat guy the Moho reflection
                    #deltaz=abs(turn_depth-moho_depth_in_km)
                    #i=argmin(deltaz)
                    #if deltaz[i]<2: #Yes, this is a moho reflection
                    #    mohoS=Spaths[i+1]
                    #else:
                    #    mohoS=None
                    mohoS=Spaths[-1]
                     
 
                #######         Build Direct P ray           ######
                if Pwave==True:
                    take_off_angle_P=directP.takeoff_angle
                    
                    #Get attenuation due to geometrical spreading (from the path length)
                    path_length_P=get_path_length(directP,zs,dist_in_degs)
                    path_length_P=path_length_P*100 #to cm
                    
                    #Get effect of intrinsic aptimeenuation for that ray (path integrated)
                    Q_P=get_attenuation(f,structure,directS,Qexp,Qtype='P')
                    
                    #Build the entire path term
                    G_P=(I*Q_P)/path_length_P
    
                    #Get conically averaged radiation pattern terms
                    RP=conically_avg_P_radiation_pattern(strike,dip,rake,azimuth,take_off_angle_P)
                    RP=abs(RP)
                       
                    #Get partition of Pwave into Z and N,E components 
                    incidence_angle=directP.incident_angle
                    Npartition,Epartition,Zpartition=get_P_wave_partition(incidence_angle,azimuth)
                    if component=='Z':
                       Ppartition=Zpartition 
                    elif component=='N':
                        Ppartition=Npartition
                    else:
                        Ppartition=Epartition
                        
                    #And finally multiply everything together to get the subfault amplitude spectrum
                    AP=CP*S*G_P*P*RP*Ppartition           
    
                    #Generate windowed time series
                    duration=1./fc_subfault+0.09*(dist/1000)
                    w=windowed_gaussian(duration,hf_dt,window_type='saragoni_hart')
                    
                    #Go to frequency domain, apply amplitude spectrum and ifft for final time series
                    hf_seis_P=apply_spectrum(w,AP,f,hf_dt)
                    
                    #What time after OT should this time series start at?
                    time_insert=directP.path['time'][-1]+onset_times[kfault]
                    i=argmin(abs(t-time_insert))
                    j=i+len(hf_seis_P)
                    
                    #Add seismogram
                    hf[i:j]=hf[i:j]+hf_seis_P                    
                                               
                                                                      
                                                                                                                    
                              
                #######         Build Direct S ray           ######
                take_off_angle_S=directS.takeoff_angle
                
                #Get attenuation due to geometrical spreading (from the path length)
                path_length_S=get_path_length(directS,zs,dist_in_degs)
                path_length_S=path_length_S*100 #to cm
                
                #Get effect of intrinsic aptimeenuation for that ray (path integrated)
                Q_S=get_attenuation(f,structure,directS,Qexp)
                
                #Build the entire path term
                G_S=(I*Q_S)/path_length_S

                #Get conically averaged radiation pattern terms
                if component=='Z':
                    RP_vert=conically_avg_vert_radiation_pattern(strike,dip,rake,azimuth,take_off_angle_S)
                    #And finally multiply everything together to get the subfault amplitude spectrum
                    AS=CS*S*G_S*P*RP_vert   
                else:
                    RP=conically_avg_radiation_pattern(strike,dip,rake,azimuth,take_off_angle_S,component_angle)
                    RP=abs(RP)
                    #And finally multiply everything together to get the subfault amplitude spectrum
                    AS=CS*S*G_S*P*RP                

                #Generate windowed time series
                duration=1./fc_subfault+0.063*(dist/1000)
                w=windowed_gaussian(duration,hf_dt,window_type='saragoni_hart')
                #w=windowed_gaussian(3*duration,hf_dt,window_type='cua',ptime=Ppaths[0].path['time'][-1],stime=Spaths[0].path['time'][-1])
                
                #Go to frequency domain, apply amplitude spectrum and ifft for final time series
                hf_seis_S=apply_spectrum(w,AS,f,hf_dt)
                
                #What time after OT should this time series start at?
                time_insert=directS.path['time'][-1]+onset_times[kfault]
                #print 'ts = '+str(time_insert)+' , Td = '+str(duration)
                #time_insert=Ppaths[0].path['time'][-1]
                i=argmin(abs(t-time_insert))
                j=i+len(hf_seis_S)
                
                #Add seismogram
                hf[i:j]=hf[i:j]+hf_seis_S
                
                
                #######         Build Moho reflected S ray           ######
    #            if mohoS==None:
    #                pass
    #            else:
    #                if kfault%100==0:
    #                    print '... ... building Moho reflected S wave'
    #                take_off_angle_mS=mohoS.takeoff_angle
    #                
    #                #Get attenuation due to geometrical spreading (from the path length)
    #                path_length_mS=get_path_length(mohoS,zs,dist_in_degs)
    #                path_length_mS=path_length_mS*100 #to cm
    #                
    #                #Get effect of intrinsic aptimeenuation for that ray (path integrated)
    #                Q_mS=get_attenuation(f,structure,mohoS,Qexp)
    #                
    #                #Build the entire path term
    #                G_mS=(I*Q_mS)/path_length_mS
    #
    #                #Get conically averaged radiation pattern terms
    #                if component=='Z':
    #                    RP_vert=conically_avg_vert_radiation_pattern(strike,dip,rake,azimuth,take_off_angle_mS)
    #                    #And finally multiply everything together to get the subfault amplitude spectrum
    #                    A=C*S*G_mS*P*RP_vert   
    #                else:
    #                    RP=conically_avg_radiation_pattern(strike,dip,rake,azimuth,take_off_angle_mS,component_angle)
    #                    RP=abs(RP)
    #                    #And finally multiply everything together to get the subfault amplitude spectrum
    #                    A=C*S*G_mS*P*RP                
    #
    #                #Generate windowed time series
    #                duration=1./fc_subfault+0.063*(dist/1000)
    #                w=windowed_gaussian(duration,hf_dt,window_type='saragoni_hart')
    #                #w=windowed_gaussian(3*duration,hf_dt,window_type='cua',ptime=Ppaths[0].path['time'][-1],stime=Spaths[0].path['time'][-1])
    #                
    #                #Go to frequency domain, apply amplitude spectrum and ifft for final time series
    #                hf_seis=apply_spectrum(w,A,f,hf_dt)
    #                
    #                #What time after OT should this time series start at?
    #                time_insert=mohoS.path['time'][-1]+onset_times[kfault]
    #                #print 'ts = '+str(time_insert)+' , Td = '+str(duration)
    #                #time_insert=Ppaths[0].path['time'][-1]
    #                i=argmin(abs(t-time_insert))
    #                j=i+len(hf_seis)
    #                
    #                #Add seismogram
    #                hf[i:j]=hf[i:j]+hf_seis
    #                
    #                #Done, reset
    #                mohoS=None
                
        #Done add to trace and stream
        tr.data=hf/100 #convert to m/s**2
        st+=tr
    
    return st
Пример #37
0
    def test_paths_for_crustal_phases(self):
        """
        Tests that Pn and PmP are correctly modelled and not mixed up.

        See #1392.
        """
        model = TauPyModel(model='iasp91')
        paths = model.get_ray_paths(source_depth_in_km=0,
                                    distance_in_degree=1,
                                    phase_list=['Pn', 'PmP'])
        self.assertEqual(len(paths), 2)

        self.assertEqual(paths[0].name, "PmP")
        self.assertAlmostEqual(paths[0].time, 21.273, 3)
        self.assertEqual(paths[1].name, "Pn")
        self.assertAlmostEqual(paths[1].time, 21.273, 3)

        self.assertAlmostEqual(paths[0].time, 21.273, 3)

        # Values of visually checked paths to guard against regressions.
        pmp_path = [
            [0.0, 0.0],
            [8.732364066174294e-07, 0.005402127286288305],
            [0.00020293803558129412, 1.2550644943312363],
            [0.000405124234951687, 2.5047268613761844],
            [0.0008098613580518535, 5.004051595465171],
            [0.0016207981804224497, 10.002701063643144],
            [0.00243369214394241, 15.001350531821117],
            [0.0032485517460744207, 20.0],
            [0.0034500021984838003, 20.9375],
            [0.0036515675727796315, 21.875],
            [0.004055043605178164, 23.75],
            [0.004863380445624696, 27.5],
            [0.006485622554890742, 35.0],
            [0.008803860898528547, 35.018603858353345],
            [0.011122099242166353, 35.0],
            [0.012744341351432398, 27.5],
            [0.01355267819187893, 23.75],
            [0.013956154224277463, 21.875],
            [0.014157719598573294, 20.9375],
            [0.014359170050982674, 20.0],
            [0.015174029653114684, 15.001350531821117],
            [0.015986923616634643, 10.002701063643144],
            [0.01679786043900524, 5.004051595465171],
            [0.017202597562105407, 2.5047268613761844],
            [0.0174047837614758, 1.2550644943312363],
            [0.017606848560650475, 0.005402127286288305],
            [0.017607721797057094, 0.0]]
        pn_path = [
            [0.0, 0.0],
            [8.732421799574388e-07, 0.005402127286288305],
            [0.00020293937754080365, 1.2550644943312363],
            [0.0004051269144571584, 2.5047268613761844],
            [0.0008098667167377564, 5.004051595465171],
            [0.0016208089138889542, 10.002701063643144],
            [0.002433708274208186, 15.001350531821117],
            [0.003248573295310095, 20.0],
            [0.0034500255976490177, 20.9375],
            [0.0036515928239481774, 21.875],
            [0.004055072566590625, 23.75],
            [0.004863416852584004, 27.5],
            [0.0064856739540738425, 35.0],
            [0.0064856739540738425, 35.0],
            [0.010967618565869454, 35.0],
            [0.010967618565869454, 35.0],
            [0.012589875667359293, 27.5],
            [0.013398219953352672, 23.75],
            [0.01380169969599512, 21.875],
            [0.01400326692229428, 20.9375],
            [0.014204719224633202, 20.0],
            [0.015019584245735112, 15.001350531821117],
            [0.015832483606054343, 10.002701063643144],
            [0.01664342580320554, 5.004051595465171],
            [0.017048165605486137, 2.5047268613761844],
            [0.017250353142402492, 1.2550644943312363],
            [0.017452419277763337, 0.005402127286288305],
            [0.017453292519943295, 0.0]]

        np.testing.assert_allclose([_i[0] for _i in pmp_path],
                                   paths[0].path["dist"])
        np.testing.assert_allclose([_i[1] for _i in pmp_path],
                                   paths[0].path["depth"])
        np.testing.assert_allclose([_i[0] for _i in pn_path],
                                   paths[1].path["dist"])
        np.testing.assert_allclose([_i[1] for _i in pn_path],
                                   paths[1].path["depth"])
Пример #38
0
def run_parallel_hfsims(home,project_name,rupture_name,N,M0,sta,sta_lon,sta_lat,component,model_name,
                        rise_time_depths0,rise_time_depths1,moho_depth_in_km,total_duration,
                        hf_dt,stress_parameter,kappa,Qexp,Pwave,Swave,high_stress_depth,
                        Qmethod,scattering,Qc_exp,baseline_Qc,rank,size): 
    '''
    Run stochastic HF sims
    
    stress parameter is in bars
    '''
    
    from numpy import genfromtxt,pi,logspace,log10,mean,where,exp,arange,zeros,argmin,rad2deg,arctan2,real,savetxt,c_
    from pyproj import Geod
    from obspy.geodetics import kilometer2degrees
    from obspy.taup import TauPyModel
    from mudpy.forward import get_mu, read_fakequakes_hypo_time
    from mudpy import hfsims
    from obspy import Stream,Trace
    from sys import stdout
    from os import path,makedirs
    from mudpy.hfsims import is_subfault_in_smga
    import warnings

    rank=int(rank)
    
    if rank==0 and component=='N':
        #print out what's going on:
        out='''Running with input parameters:
        home = %s
        project_name = %s
        rupture_name = %s
        N = %s
        M0 (N-m) = %s
        sta = %s
        sta_lon = %s
        sta_lat = %s
        model_name = %s
        rise_time_depths = %s
        moho_depth_in_km = %s
        total_duration = %s
        hf_dt = %s
        stress_parameter = %s
        kappa = %s
        Qexp = %s
        component = %s
        Pwave = %s
        Swave = %s
        high_stress_depth = %s
        Qmethod = %s
        scattering = %s
        Qc_exp = %s
        baseline_Qc = %s
        '''%(home,project_name,rupture_name,str(N),str(M0/1e7),sta,str(sta_lon),str(sta_lat),model_name,str([rise_time_depths0,rise_time_depths1]),
        str(moho_depth_in_km),str(total_duration),str(hf_dt),str(stress_parameter),str(kappa),str(Qexp),str(component),str(Pwave),str(Swave),
        str(high_stress_depth),str(Qmethod),str(scattering),str(Qc_exp),str(baseline_Qc))
        print(out)

    if rank==0:
        out='''
        Rupture_Name = %s
        Station = %s
        Component (N,E,Z) = %s
        Sample rate = %sHz
        Duration = %ss
        '''%(rupture_name,sta,component,str(1/hf_dt),str(total_duration))
        print(out)
        
    #print 'stress is '+str(stress_parameter)

    #I don't condone it but this cleans up the warnings
    warnings.filterwarnings("ignore")
    
    
    #Fix input formats:
    rise_time_depths=[rise_time_depths0,rise_time_depths1]
    #Load the source
    mpi_rupt=home+project_name+'/output/ruptures/mpi_rupt.'+str(rank)+'.'+rupture_name
    fault=genfromtxt(mpi_rupt)  
    
    #Onset times for each subfault
    onset_times=fault[:,12]
    
    #load velocity structure
    structure=genfromtxt(home+project_name+'/structure/'+model_name)
    
    #Frequencies vector
    f=logspace(log10(1/total_duration),log10(1/(2*hf_dt))+0.01,100)
    omega=2*pi*f
    
    #Output time vector (0 is origin time)
    t=arange(0,total_duration,hf_dt)
    
    #Projection object for distance calculations
    g=Geod(ellps='WGS84')
    
    #Create taup velocity model object, paste on top of iaspei91
    #taup_create.build_taup_model(home+project_name+'/structure/bbp_norcal.tvel',output_folder=home+project_name+'/structure/')
#    velmod=TauPyModel(model=home+project_name+'/structure/iquique',verbose=True)
    velmod = TauPyModel(model=home+project_name+'/structure/'+model_name.split('.')[0]+'.npz')
    
    #Get epicentral time
    epicenter,time_epi=read_fakequakes_hypo_time(home,project_name,rupture_name)
    
    #Moments
    slip=(fault[:,8]**2+fault[:,9]**2)**0.5
    subfault_M0=slip*fault[:,10]*fault[:,11]*fault[:,13]
    subfault_M0=subfault_M0*1e7 #to dyne-cm
    relative_subfault_M0=subfault_M0/M0
    Mw=(2./3)*(log10(M0*1e-7)-9.1)
    
    #Corner frequency scaling
    i=where(slip>0)[0] #Non-zero faults
    dl=mean((fault[:,10]+fault[:,11])/2) #predominant length scale
    dl=dl/1000 # to km
    
    #Tau=p perturbation
    tau_perturb=0.1
    
    #Deep faults receive a higher stress
    stress_multiplier=1

    #initalize output seismogram
    tr=Trace()
    tr.stats.station=sta
    tr.stats.delta=hf_dt
    tr.stats.starttime=time_epi
    #info for sac header (added at the end)
    az,backaz,dist_m=g.inv(epicenter[0],epicenter[1],sta_lon,sta_lat)
    dist_in_km=dist_m/1000.    
    
    hf=zeros(len(t))
    
    #Loop over subfaults
    for kfault in range(len(fault)):
        if rank==0:
            #Print status to screen            
            if kfault % 25 == 0:
                if kfault==0:
                    stdout.write('      [.')
                    stdout.flush()
                stdout.write('.')
                stdout.flush()
            if kfault==len(fault)-1:
                stdout.write('.]\n')
                stdout.flush()                
        
        #Include only subfaults with non-zero slip
        if subfault_M0[kfault]>0:
            
            #Get subfault to station distance
            lon_source=fault[kfault,1]
            lat_source=fault[kfault,2]
            azimuth,baz,dist=g.inv(lon_source,lat_source,sta_lon,sta_lat)
            dist_in_degs=kilometer2degrees(dist/1000.)
            
            #Source depth?
            z_source=fault[kfault,3]
            
            #No change
            stress=stress_parameter
            
            #Is subfault in an SMGA?
            #SMGA1
#            radius_in_km=15.0
#            smga_center_lon=-71.501
#            smga_center_lat=-30.918
            
            
            #SMGA2
#            radius_in_km=15.0
#            smga_center_lon=-71.863
#            smga_center_lat=-30.759
            
            #smga3
#            radius_in_km=7.5  
#            smga_center_lon=-72.3923
#            smga_center_lat=-30.58
            
            
            #smga4
            # radius_in_km=7.5  
            # smga_center_lon=-72.3923
            # smga_center_lat=-30.61
            
            # in_smga=is_subfault_in_smga(lon_source,lat_source,smga_center_lon,smga_center_lat,radius_in_km)
            
            # ###Apply multiplier?
            # if in_smga==True:
            #     stress=stress_parameter*stress_multiplier
            #     print("%.4f,%.4f is in SMGA, stress is %d" % (lon_source,lat_source,stress))
            # else:
            #     stress=stress_parameter
            
            #Apply multiplier?
            #if slip[kfault]>7.5:
            #    stress=stress_parameter*stress_multiplier
            ##elif lon_source>-72.057 and lon_source<-71.2 and lat_source>-30.28:
            ##    stress=stress_parameter*stress_multiplier
            #else:
            #    stress=stress_parameter
                
            #Apply multiplier?
            #if z_source>high_stress_depth:
            #    stress=stress_parameter*stress_multiplier
            #else:
            #    stress=stress_parameter
            
            # Frankel 95 scaling of corner frequency #verified this looks the same in GP
            # Right now this applies the same factor to all faults
            fc_scale=(M0)/(N*stress*dl**3*1e21) #Frankel scaling
            small_event_M0 = stress*dl**3*1e21
            
        

            
            #Get rho, alpha, beta at subfault depth
            zs=fault[kfault,3]
            mu,alpha,beta=get_mu(structure,zs,return_speeds=True)
            rho=mu/beta**2
            
            #Get radiation scale factor
            Spartition=1/2**0.5
            if component=='N' :
                component_angle=0
            elif component=='E':
                component_angle=90
            
            rho=rho/1000 #to g/cm**3
            beta=(beta/1000)*1e5 #to cm/s
            alpha=(alpha/1000)*1e5
            
            # print('rho = '+str(rho))
            # print('beta = '+str(beta))
            # print('alpha = '+str(alpha))
            
            #Verified this produces same value as in GP
            CS=(2*Spartition)/(4*pi*(rho)*(beta**3))
            CP=2/(4*pi*(rho)*(alpha**3))

            
            #Get local subfault rupture speed
            beta=beta/100 #to m/s
            vr=hfsims.get_local_rupture_speed(zs,beta,rise_time_depths)
            vr=vr/1000 #to km/s
            dip_factor=hfsims.get_dip_factor(fault[kfault,5],fault[kfault,8],fault[kfault,9])
            
            #Subfault corner frequency
            c0=2.0 #GP2015 value
            fc_subfault=(c0*vr)/(dip_factor*pi*dl)
            
            #get subfault source spectrum
            #S=((relative_subfault_M0[kfault]*M0/N)*f**2)/(1+fc_scale*(f/fc_subfault)**2)
            S=small_event_M0*(omega**2/(1+(f/fc_subfault)**2))
            frankel_conv_operator= fc_scale*((fc_subfault**2+f**2)/(fc_subfault**2+fc_scale*f**2))
            S=S*frankel_conv_operator
            
            #get high frequency decay
            P=exp(-pi*kappa*f)
            
            
            #Get other geometric parameters necessar for radiation pattern
            strike=fault[kfault,4]
            dip=fault[kfault,5]
            ss=fault[kfault,8]
            ds=fault[kfault,9]
            rake=rad2deg(arctan2(ds,ss))
            
            #Get ray paths for all direct P arrivals
            Ppaths=velmod.get_ray_paths(zs,dist_in_degs,phase_list=['P','p'])
            
            #Get ray paths for all direct S arrivals
            try:
                Spaths=velmod.get_ray_paths(zs,dist_in_degs,phase_list=['S','s'])
            except:
                Spaths=velmod.get_ray_paths(zs+tau_perturb,dist_in_degs,phase_list=['S','s'])
            
            #sometimes there's no S, weird I know. Check twice.
            if len(Spaths)==0:
                Spaths=velmod.get_ray_paths(zs+tau_perturb,dist_in_degs,phase_list=['S','s'])
            if len(Spaths)==0:
                Spaths=velmod.get_ray_paths(zs+5*tau_perturb,dist_in_degs,phase_list=['S','s'])   
            if len(Spaths)==0:
                Spaths=velmod.get_ray_paths(zs-5*tau_perturb,dist_in_degs,phase_list=['S','s'])
            if len(Spaths)==0:
                Spaths=velmod.get_ray_paths(zs+5*tau_perturb,dist_in_degs,phase_list=['S','s'])  
            if len(Spaths)==0:
                Spaths=velmod.get_ray_paths(zs-10*tau_perturb,dist_in_degs,phase_list=['S','s'])
            if len(Spaths)==0:
                Spaths=velmod.get_ray_paths(zs+10*tau_perturb,dist_in_degs,phase_list=['S','s']) 
            if len(Spaths)==0:
                Spaths=velmod.get_ray_paths(zs-50*tau_perturb,dist_in_degs,phase_list=['S','s'])
            if len(Spaths)==0:
                Spaths=velmod.get_ray_paths(zs+50*tau_perturb,dist_in_degs,phase_list=['S','s']) 
            if len(Spaths)==0:
                Spaths=velmod.get_ray_paths(zs-75*tau_perturb,dist_in_degs,phase_list=['S','s'])
            if len(Spaths)==0:
                Spaths=velmod.get_ray_paths(zs+75*tau_perturb,dist_in_degs,phase_list=['S','s']) 
            if len(Spaths)==0:
                print('ERROR: I give up, no direct S in spite of multiple attempts at subfault '+str(kfault))

            #Which ray should I keep? 
            
            #This is the fastest arriving P
            directP=Ppaths[0]
            
            #Get moho depth from velmod
            moho_depth  = velmod.model.moho_depth
            
            # In this method here are the rules:
            #For S do not allow Moho turning rays, keep the fastest non Moho turning ray. If
            #only Moho rays are available, then keep the one that turns the shallowest.
            if Qmethod == 'no_moho':
            
                #get turning depths and arrival times of S rays
                turning_depths = zeros(len(Spaths))
                S_ray_times = zeros(len(Spaths))
                
                for kray in range(len(Spaths)):
                    turning_depths[kray] = Spaths[kray].path['depth'].max()
                    S_ray_times[kray] = Spaths[kray].path['time'].max()
                    
                #Keep only rays that turn above Moho
                i=where(turning_depths < moho_depth)[0]
                
                if len(i) == 0: #all rays turn below Moho, keep shallowest turning
                    i_min_depth = argmin(turning_depths)
                    directS = Spaths[i_min_depth]
                
                else:  #Keep fastest arriving ray that turns above Moho
                    Spaths = [Spaths[j] for j in i]  #Rays turning above Moho, NOTE: I hate list comprehension
                    S_ray_times = S_ray_times[i]
                    i_min_time = argmin(S_ray_times)
                    directS = Spaths[i_min_time]
                    
            elif Qmethod =='shallowest':
                                
                #get turning depths and arrival times of S rays
                turning_depths = zeros(len(Spaths))
                
                for kray in range(len(Spaths)):
                    turning_depths[kray] = Spaths[kray].path['depth'].max()

                i_min_depth = argmin(turning_depths)
                directS = Spaths[i_min_depth]
                
            elif Qmethod == 'fastest' or Qmethod=='direct':   #Pick first arriving S wave
                
                directS = Spaths[0]
                
                
            
            #directS=Spaths[0]  #this is the old way, kept fastest S
            mohoS=None
            
            # #print len(Spaths)
            # if len(Spaths)==1: #only direct S
            #     pass
            # else:
            #     #turn_depth=zeros(len(Spaths)-1) #turning depth of other non-direct rays
            #     #for k in range(1,len(Spaths)):
            #     #    turn_depth[k-1]=Spaths[k].path['depth'].max()
            #     ##If there's a ray that turns within 2km of Moho, callt hat guy the Moho reflection
            #     #deltaz=abs(turn_depth-moho_depth_in_km)
            #     #i=argmin(deltaz)
            #     #if deltaz[i]<2: #Yes, this is a moho reflection
            #     #    mohoS=Spaths[i+1]
            #     #else:
            #     #    mohoS=None
            #     mohoS=Spaths[-1]
                

                 
 
            #######         Build Direct P ray           ######
            if Pwave==True:
                take_off_angle_P=directP.takeoff_angle
                
                # #Get attenuation due to geometrical spreading (from the path length)
                # path_length_P=hfsims.get_path_length(directP,zs,dist_in_degs)
                # path_length_P=path_length_P*100 #to cm
                
                # #Get effect of intrinsic attenuation for that ray (path integrated)
                # #Q_P=hfsims.get_attenuation(f,structure,directP,Qexp,Qtype='P')   <- This causes problems and I don't know why underlying assumptions might be bad
                # Q_P=hfsims.get_attenuation(f,structure,directS,Qexp,Qtype='S')
                
                # #get quarter wavelength amplificationf actors
                # # pass rho in kg/m^3 (this units nightmare is what I get for following Graves' code)
                # I_P=hfsims.get_amplification_factors(f,structure,zs,alpha,rho*1000)
                
                # #Build the entire path term
                # G_P=(I_P*Q_P)/path_length_P
                
                #Get attenuation due to geometrical spreading (from the path length)
                path_length_S=hfsims.get_path_length(directS,zs,dist_in_degs)
                path_length_S=path_length_S*100 #to cm
                
                #Get effect of intrinsic aptimeenuation for that ray (path integrated)
                Q_S=hfsims.get_attenuation(f,structure,directS,Qexp)
                
                #get quarter wavelength amplificationf actors
                # pass rho in kg/m^3 (this units nightmare is what I get for following Graves' code)
                I_S=hfsims.get_amplification_factors(f,structure,zs,beta,rho*1000)
                
                #Build the entire path term
                # G_S=(I_S*Q_S)/path_length_S
                G_S=(1*Q_S)/path_length_S
                
                

                #Get conically averaged radiation pattern terms
                RP=hfsims.conically_avg_P_radiation_pattern(strike,dip,rake,azimuth,take_off_angle_P)
                RP=abs(RP)
                   
                #Get partition of Pwave into Z and N,E components 
                incidence_angle=directP.incident_angle
                Npartition,Epartition,Zpartition=hfsims.get_P_wave_partition(incidence_angle,azimuth)
                if component=='Z':
                   Ppartition=Zpartition 
                elif component=='N':
                    Ppartition=Npartition
                else:
                    Ppartition=Epartition
                    
                #And finally multiply everything together to get the subfault amplitude spectrum
                AP=CP*S*G_S*P*RP*Ppartition           

                #Generate windowed time series
                duration=1./fc_subfault+0.09*(dist/1000)
                w=hfsims.windowed_gaussian(duration,hf_dt,window_type='saragoni_hart')
                
                #Go to frequency domain, apply amplitude spectrum and ifft for final time series
                hf_seis_P=hfsims.apply_spectrum(w,AP,f,hf_dt)
                
                #save thigns to check
                # if sta=='AL2H':
                #     path_out = '/Users/dmelgarm/FakeQuakes/ONC_debug/analysis/frequency/Pwave/'
                #     path_out = path_out+str(kfault)
                #     # savetxt(path_out+'.all',c_[f,AP])
                #     # savetxt(path_out+'.source',c_[f,CP*S])
                #     # savetxt(path_out+'.path',c_[f,G_P])
                #     # savetxt(path_out+'.site',c_[f,P])
                
                
                #What time after OT should this time series start at?
                time_insert=directP.path['time'][-1]+onset_times[kfault]
                i=argmin(abs(t-time_insert))
                j=i+len(hf_seis_P)
                
                #Check seismogram doesn't go past last sample
                if i<len(hf)-1: #if i (the beginning of the seimogram) is less than the length
                    if j>len(hf): #seismogram goes past total_duration length, trim it
                        len_paste=len(hf)-i
                        j=len(hf)
                        #Add seismogram
                        hf[i:j]=hf[i:j]+real(hf_seis_P[0:len_paste])
                    else: #Lengths are fine
                        hf[i:j]=hf[i:j]+real(hf_seis_P)      
                else: #Seismogram starts after end of available space
                    pass   
                
                                           
                                                                  
                                                                                                                
                          
            #######         Build Direct S ray           ######

            if Swave==True:
                take_off_angle_S=directS.takeoff_angle
                
                #Get attenuation due to geometrical spreading (from the path length)
                path_length_S=hfsims.get_path_length(directS,zs,dist_in_degs)
                path_length_S=path_length_S*100 #to cm
                
                #Get effect of intrinsic aptimeenuation for that ray (path integrated)
                if Qmethod == 'direct':#No ray tracing use bulka ttenuation along path
                    Q_S = hfsims.get_attenuation_linear(f,structure,zs,dist,Qexp,Qtype='S')
                else: #Use ray tracing
                    Q_S=hfsims.get_attenuation(f,structure,directS,Qexp,scattering=scattering,
                                               Qc_exp=Qc_exp,baseline_Qc=baseline_Qc)
                
                #get quarter wavelength amplificationf actors
                # pass rho in kg/m^3 (this units nightmare is what I get for following Graves' code)
                I_S=hfsims.get_amplification_factors(f,structure,zs,beta,rho*1000)
                
                #Build the entire path term
                G_S=(I_S*Q_S)/path_length_S
                # G_S=(1*Q_S)/path_length_S
    
                #Get conically averaged radiation pattern terms
                if component=='Z':
                    RP_vert=hfsims.conically_avg_vert_radiation_pattern(strike,dip,rake,azimuth,take_off_angle_S)
                    #And finally multiply everything together to get the subfault amplitude spectrum
                    AS=CS*S*G_S*P*RP_vert   
                    # print('... RP_vert = '+str(RP_vert))
                else:
                    RP=hfsims.conically_avg_radiation_pattern(strike,dip,rake,azimuth,take_off_angle_S,component_angle)
                    RP=abs(RP)
                    # print('... RP_horiz = '+str(RP))
                    #And finally multiply everything together to get the subfault amplitude spectrum
                    AS=CS*S*G_S*P*RP                
    
                #Generate windowed time series
                duration=1./fc_subfault+0.063*(dist/1000)
                w=hfsims.windowed_gaussian(duration,hf_dt,window_type='saragoni_hart')
                #w=windowed_gaussian(3*duration,hf_dt,window_type='cua',ptime=Ppaths[0].path['time'][-1],stime=Spaths[0].path['time'][-1])
                
                #Go to frequency domain, apply amplitude spectrum and ifft for final time series
                hf_seis_S=hfsims.apply_spectrum(w,AS,f,hf_dt)
                
                #save thigns to check
                # if sta=='AL2H':
                #     path_out = '/Users/dmelgarm/FakeQuakes/ONC_debug/analysis/frequency/Swave/'
                #     path_out = path_out+str(kfault)
                #     # savetxt(path_out+'.soverp',c_[f,(CS*S)/(CP*S)])
                #     savetxt(path_out+'.all',c_[f,AS])
                #     savetxt(path_out+'.source',c_[f,CS*S])
                #     savetxt(path_out+'.path',c_[f,G_S])
                #     savetxt(path_out+'.site',c_[f,P])
                
                #What time after OT should this time series start at?
                time_insert=directS.path['time'][-1]+onset_times[kfault]
                #print 'ts = '+str(time_insert)+' , Td = '+str(duration)
                #time_insert=Ppaths[0].path['time'][-1]
                i=argmin(abs(t-time_insert))
                j=i+len(hf_seis_S)
                
                
                #Check seismogram doesn't go past last sample
                if i<len(hf)-1: #if i (the beginning of the seimogram) is less than the length
                    if j>len(hf): #seismogram goes past total_duration length, trim it
                        len_paste=len(hf)-i
                        j=len(hf)
                        #Add seismogram
                        hf[i:j]=hf[i:j]+real(hf_seis_S[0:len_paste])
                    else: #Lengths are fine
                        hf[i:j]=hf[i:j]+real(hf_seis_S)
                else: #Beginning of seismogram is past end of available space
                    pass

            
            
            #######         Build Moho reflected S ray           ######
#            if mohoS==None:
#                pass
#            else:
#                if kfault%100==0:
#                    print '... ... building Moho reflected S wave'
#                take_off_angle_mS=mohoS.takeoff_angle
#                
#                #Get attenuation due to geometrical spreading (from the path length)
#                path_length_mS=get_path_length(mohoS,zs,dist_in_degs)
#                path_length_mS=path_length_mS*100 #to cm
#                
#                #Get effect of intrinsic aptimeenuation for that ray (path integrated)
#                Q_mS=get_attenuation(f,structure,mohoS,Qexp)
#                
#                #Build the entire path term
#                G_mS=(I*Q_mS)/path_length_mS
#
#                #Get conically averaged radiation pattern terms
#                if component=='Z':
#                    RP_vert=conically_avg_vert_radiation_pattern(strike,dip,rake,azimuth,take_off_angle_mS)
#                    #And finally multiply everything together to get the subfault amplitude spectrum
#                    A=C*S*G_mS*P*RP_vert   
#                else:
#                    RP=conically_avg_radiation_pattern(strike,dip,rake,azimuth,take_off_angle_mS,component_angle)
#                    RP=abs(RP)
#                    #And finally multiply everything together to get the subfault amplitude spectrum
#                    A=C*S*G_mS*P*RP                
#
#                #Generate windowed time series
#                duration=1./fc_subfault+0.063*(dist/1000)
#                w=windowed_gaussian(duration,hf_dt,window_type='saragoni_hart')
#                #w=windowed_gaussian(3*duration,hf_dt,window_type='cua',ptime=Ppaths[0].path['time'][-1],stime=Spaths[0].path['time'][-1])
#                
#                #Go to frequency domain, apply amplitude spectrum and ifft for final time series
#                hf_seis=apply_spectrum(w,A,f,hf_dt)
#                
#                #What time after OT should this time series start at?
#                time_insert=mohoS.path['time'][-1]+onset_times[kfault]
#                #print 'ts = '+str(time_insert)+' , Td = '+str(duration)
#                #time_insert=Ppaths[0].path['time'][-1]
#                i=argmin(abs(t-time_insert))
#                j=i+len(hf_seis)
#                
#                #Add seismogram
#                hf[i:j]=hf[i:j]+hf_seis
#                
#                #Done, reset
#                mohoS=None        
           
    #Done
    tr.data=hf/100 #convert to m/s**2
    #Add station location, event location, and first P-wave arrival time to SAC header
    tr.stats.update({'sac':{'stlo':sta_lon,'stla':sta_lat,'evlo':epicenter[0],'evla':epicenter[1],'evdp':epicenter[2],'dist':dist_in_km,'az':az,'baz':backaz,'mag':Mw}}) #,'idep':"ACC (m/s^2)" not sure why idep won't work
    
    #Write out to file 
    #old
    rupture=rupture_name.split('.')[0]+'.'+rupture_name.split('.')[1]
    #new
    rupture=rupture_name.rsplit('.',1)[0]
    if not path.exists(home+project_name+'/output/waveforms/'+rupture+'/'):
        makedirs(home+project_name+'/output/waveforms/'+rupture+'/')
    if rank < 10:
        tr.write(home+project_name+'/output/waveforms/'+rupture+'/'+sta+'.HN'+component+'.00'+str(rank)+'.sac',format='SAC')
    elif rank < 100:
        tr.write(home+project_name+'/output/waveforms/'+rupture+'/'+sta+'.HN'+component+'.0'+str(rank)+'.sac',format='SAC')
    else:
        tr.write(home+project_name+'/output/waveforms/'+rupture+'/'+sta+'.HN'+component+'.'+str(rank)+'.sac',format='SAC')
Пример #39
0
class TauPyPlottingTestCase(unittest.TestCase):
    """
    TauPy plotting tests.
    """
    def setUp(self):
        self.image_dir = os.path.join(os.path.dirname(__file__),
                                      'images')
        self.model = TauPyModel(model="iasp91")

    def test_spherical_many_phases(self):
        """
        Spherical plot of the ray paths for many phases for a single
        epicentral distance, but both ways around the globe.
        """
        with ImageComparison(self.image_dir,
                             "spherical_many_phases.png") as ic:
            self.model.get_ray_paths(500,
                                     140).plot_rays(plot_type="spherical",
                                                    plot_all=True,
                                                    show=False)
            plt.savefig(ic.name)

    def test_spherical_many_phases_buried_station(self):
        """
        Same as test_spherical_many_phases, but this time the receiver is
        buried.
        """
        with ImageComparison(self.image_dir,
                             "spherical_many_phases_buried_station.png") as ic:
            arrivals = self.model.get_ray_paths(500, 140,
                                                receiver_depth_in_km=1000)
            arrivals.plot_rays(plot_type="spherical",
                               plot_all=True, show=False)
            plt.savefig(ic.name)

    def test_spherical_many_phases_one_way(self):
        """
        Same as test_spherical_many_phases, but this time no phases
        travelling the other way around the globe are plotted.
        """
        with ImageComparison(self.image_dir,
                             "spherical_many_phases_one_way.png") as ic:
            self.model.get_ray_paths(500,
                                     140).plot_rays(plot_type="spherical",
                                                    plot_all=False,
                                                    show=False)
            plt.savefig(ic.name)

    def test_spherical_more_then_360_degrees(self):
        """
        Spherical plot with rays traveling more than 360.0 degrees.
        """
        with ImageComparison(self.image_dir,
                             "spherical_more_then_360.png") as ic:
            self.model.get_ray_paths(0, 10, phase_list=["PPPPPP"]).plot_rays(
                plot_type="spherical", plot_all=True, show=False,
                phase_list=['PPPPPP'])
            plt.savefig(ic.name)

    def test_spherical_diff_phases(self):
        """
        Spherical plot of ``diff`` phases.
        """
        with ImageComparison(self.image_dir,
                             "spherical_diff_phases.png") as ic:
            self.model.get_ray_paths(
                700, 140, phase_list=["Pdiff", "Sdiff", "pSdiff", "sSdiff",
                                      "pPdiff", "sPdiff"]).plot_rays(
                                          phase_list=["Pdiff", "Sdiff",
                                                      "pSdiff", "sSdiff",
                                                      "pPdiff", "sPdiff"],
                                          plot_type="spherical", legend=True,
                                          plot_all=True, show=False)
            plt.savefig(ic.name)

    def test_cartesian_many_phases(self):
        """
         Cartesian plot of the ray paths for many phases for a single
         epicentral distance, but both ways around the globe.
         """
        with ImageComparison(self.image_dir,
                             "cartesian_many_phases.png") as ic:
            self.model.get_ray_paths(500, 140).plot_rays(plot_type="cartesian",
                                                         plot_all=True,
                                                         show=False)
            plt.savefig(ic.name)

    def test_cartesian_many_phases_buried_station(self):
        """
        Same as test_cartesian_many_phases but this time the receiver is
        buried.
        """
        with ImageComparison(self.image_dir,
                             "cartesian_many_phases_buried_station.png") as ic:
            arrivals = self.model.get_ray_paths(500, 140,
                                                receiver_depth_in_km=1000)
            arrivals.plot_rays(plot_type="cartesian", plot_all=True,
                               show=False)
            plt.savefig(ic.name)

    def test_cartesian_many_phases_one_way(self):
        """
        Same as test_cartesian_many_phases but this time no phases
        travelling the other way around the globe are plotted.
        """
        arrivals = self.model.get_ray_paths(500, 140)
        with ImageComparison(self.image_dir,
                             "cartesian_many_phases_one_way.png") as ic:
            arrivals.plot_rays(plot_type="cartesian", plot_all=False,
                               show=False)
            plt.savefig(ic.name)
        # check warning message on deprecated routine
        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter("always")
            with ImageComparison(self.image_dir,
                                 "cartesian_many_phases_one_way.png") as ic:
                # default for legend was True in legacy method
                arrivals.plot(plot_type="cartesian", plot_all=False,
                              show=False, legend=False)
                plt.savefig(ic.name)
            self.assertGreaterEqual(len(w), 1)
            for w_ in w:
                try:
                    self.assertEqual(
                        str(w_.message), 'The plot() function is '
                        'deprecated. Please use arrivals.plot_rays()')
                    self.assertEqual(w_.category, ObsPyDeprecationWarning)
                except AssertionError:
                    continue
                break
            else:
                raise

    def test_plot_travel_times(self):
        """
        Travel time plot for many phases at a single epicentral distance.
        """
        with ImageComparison(self.image_dir,
                             "traveltimes_many_phases.png") as ic:
            self.model.get_ray_paths(10, 100,
                                     phase_list=("ttbasic",)).plot_times(
                                         show=False, legend=True)
            plt.savefig(ic.name)

    def test_plot_travel_times_convenience(self):
        """
        Travel time plot for many phases at multiple epicentral distances,
        convenience function
        """
        with ImageComparison(
                self.image_dir,
                "traveltimes_many_phases_multiple_degrees.png") as ic:
            # base line image looks awkward with points at the left/right end
            # of the plot but that's only due to the "classic" style sheet used
            # in tests. default mpl2 style makes room around plotted artists
            # larger point size to ensure plot can fail properly if points
            # should move
            mpl.rcParams['lines.markersize'] = 20
            plot_travel_times(10, phase_list=("P", "S", "SKS", "PP"),
                              min_degrees=40, max_degrees=60, show=False,
                              legend=True, npoints=4)
            plt.savefig(ic.name)

        def _test_plot_all(plot_all):
            mpl.rcParams['lines.markersize'] = 200
            plot_travel_times(10, phase_list=("SSS",), min_degrees=150,
                              max_degrees=200, npoints=4, legend=False,
                              plot_all=plot_all)

        # now test option plot_all=False
        with ImageComparison(
                self.image_dir, "traveltimes_plot_all_False.png") as ic:
            _test_plot_all(plot_all=False)
            plt.savefig(ic.name)

        # Now with option plot_all=True
        with ImageComparison(
                self.image_dir, "traveltimes_plot_all_True.png") as ic:
            _test_plot_all(plot_all=True)
            plt.savefig(ic.name)

    def test_ray_plot_mismatching_axes_type_warnings(self):
        """
        Test warnings when attempting ray path plots in spherical/cartesian
        with bad axes type (polar/not polar).
        """
        arrivals = self.model.get_ray_paths(500, 20, phase_list=['P'])
        # polar pot attempted in cartesian axes
        fig, ax = plt.subplots()
        expected_message = ("Axes instance provided for plotting with "
                            "`plot_type='spherical'` but it seems the axes is "
                            "not a polar axes.")
        try:
            with warnings.catch_warnings(record=True) as w:
                warnings.simplefilter("always")
                # this raises an exception as well:
                # "AttributeError: 'AxesSubplot' object has no attribute "
                # "'set_theta_zero_location'"
                with self.assertRaises(AttributeError):
                    arrivals.plot_rays(plot_type="spherical", ax=ax,
                                       show=False)
            self.assertEqual(len(w), 1)
            self.assertEqual(str(w[0].message), expected_message)
            self.assertEqual(w[0].category, UserWarning)
        finally:
            plt.close(fig)
        # cartesian pot attempted in polar axes
        fig, ax = plt.subplots(subplot_kw=dict(projection='polar'))
        expected_message = ("Axes instance provided for plotting with "
                            "`plot_type='cartesian'` but it seems the axes is "
                            "a polar axes.")
        try:
            with warnings.catch_warnings(record=True) as w:
                warnings.simplefilter("always")
                arrivals.plot_rays(plot_type="cartesian", ax=ax, show=False)
            self.assertEqual(len(w), 1)
            self.assertEqual(str(w[0].message), expected_message)
            self.assertEqual(w[0].category, UserWarning)
        finally:
            plt.close(fig)

    def test_invalid_plot_option(self):
        """
        Test error message when attempting ray path plots with invalid plot
        type
        """
        arrivals = self.model.get_ray_paths(500, 20, phase_list=['P'])
        # polar plot attempted in cartesian axes
        expected_msg = "Plot type 'spam' is not a valid option."
        with self.assertRaisesRegexp(ValueError, expected_msg):
            arrivals.plot_rays(plot_type="spam")
Пример #40
0
 def test_deep_source(self):
     # Regression test -- check if deep sources are ok
     model = TauPyModel("ak135")
     arrivals = model.get_ray_paths(2000.0, 60.0, ["P"])
     assert abs(arrivals[0].time - 480.32) < 1e-2
Пример #41
0
                       label='twin', frameon=False)
ax_left.set_theta_zero_location('N')
ax_left.set_theta_direction(+1)
ax_left.xaxis.set_visible(False)
ax_left.yaxis.set_visible(False)

# Plot all pre-determined phases
for phase, distance in PHASES:
    if distance < 0:
        realdist = -distance
        ax = ax_left
    else:
        realdist = distance
        ax = ax_right

    arrivals = model.get_ray_paths(700, realdist, phase_list=[phase])
    if not len(arrivals):
        print('FAIL', phase, distance)
        continue
    arrivals.plot(plot_type='spherical', plot_all=phase in PLOT_ALL,
                  legend=False, label_arrivals=True,
                  show=False, ax=ax)

# Annotate regions
ax_right.text(0, 0, 'Solid\ninner\ncore',
              horizontalalignment='center', verticalalignment='center',
              bbox=dict(facecolor='white', edgecolor='none', alpha=0.7))
ocr = (model.model.radiusOfEarth -
       (model.model.sMod.vMod.iocbDepth + model.model.sMod.vMod.cmbDepth) / 2)
ax_right.text(np.deg2rad(180), ocr, 'Fluid outer core',
              horizontalalignment='center',
Пример #42
0
ax_left = fig.add_axes(ax_right.get_position(), projection="polar", label="twin", frameon=False)
ax_left.set_theta_zero_location("N")
ax_left.set_theta_direction(+1)
ax_left.xaxis.set_visible(False)
ax_left.yaxis.set_visible(False)

# Plot all ray paths:
for distance in DISTANCES:
    if distance < 0:
        realdist = -distance
        ax = ax_left
    else:
        realdist = distance
        ax = ax_right

    arrivals = model.get_ray_paths(sourcedepth, realdist, phase_list=PHASES)
    if not len(arrivals):
        # print('FAIL', PHASES, distance)
        continue
    arrivals.plot(plot_type="spherical", legend=False, label_arrivals=True, show=False, ax=ax)

# Annotate regions:
ax_right.text(
    0,
    0,
    "Solid\ninner\ncore",
    horizontalalignment="center",
    verticalalignment="center",
    bbox=dict(facecolor="white", edgecolor="none", alpha=0.7),
)
ocr = model.model.radiusOfEarth - (model.model.sMod.vMod.iocbDepth + model.model.sMod.vMod.cmbDepth) / 2
Пример #43
0
Phase1arrivals = []
Phase2arrivals = []
Phase1_IA = []
Phase2_IA = []
for dist_deg in dists[:]:
    temparr = model.get_travel_times(source_depth_in_km=sourcedepth,
                                     distance_in_degree=dist_deg,
                                     phase_list=[phases[0]])
    temparr2 = model.get_travel_times(source_depth_in_km=sourcedepth,
                                      distance_in_degree=dist_deg,
                                      phase_list=[phases2[0]])

    # there may be something wrong with obpsy and plotting since the error is that the arrivals does not have the attribute for plot_rays(), see Vipul's email for another way to plot.
    try:
        somearray = model.get_ray_paths(source_depth_in_km=sourcedepth,
                                        distance_in_degree=dist_deg,
                                        phase_list=[phases[0]])

    except:
        print('no somearray!')

    if len(temparr) == 0:
        Phase1arrivals.append(math.nan)
        Phase1_IA.append(math.nan)
    else:
        Phase1arrivals.append(temparr[0].time)
        Phase1_IA.append(temparr[0].incident_angle)
    if len(temparr2) == 0:
        Phase2arrivals.append(math.nan)
        Phase2_IA.append(math.nan)
    else:
Пример #44
0
class TauPyPlottingTestCase(unittest.TestCase):
    """
    TauPy plotting tests.
    """
    def setUp(self):
        self.image_dir = os.path.join(os.path.dirname(__file__), 'images')
        self.model = TauPyModel(model="iasp91")

    def test_spherical_many_phases(self):
        """
        Spherical plot of the ray paths for many phases for a single
        epicentral distance, but both ways around the globe.
        """
        with ImageComparison(self.image_dir,
                             "spherical_many_phases.png") as ic:
            self.model.get_ray_paths(500, 140).plot_rays(plot_type="spherical",
                                                         plot_all=True,
                                                         show=False)
            plt.savefig(ic.name)

    def test_spherical_many_phases_buried_station(self):
        """
        Same as test_spherical_many_phases, but this time the receiver is
        buried.
        """
        with ImageComparison(self.image_dir,
                             "spherical_many_phases_buried_station.png") as ic:
            arrivals = self.model.get_ray_paths(500,
                                                140,
                                                receiver_depth_in_km=1000)
            arrivals.plot_rays(plot_type="spherical",
                               plot_all=True,
                               show=False)
            plt.savefig(ic.name)

    def test_spherical_many_phases_one_way(self):
        """
        Same as test_spherical_many_phases, but this time no phases
        travelling the other way around the globe are plotted.
        """
        with ImageComparison(self.image_dir,
                             "spherical_many_phases_one_way.png") as ic:
            self.model.get_ray_paths(500, 140).plot_rays(plot_type="spherical",
                                                         plot_all=False,
                                                         show=False)
            plt.savefig(ic.name)

    def test_spherical_more_then_360_degrees(self):
        """
        Spherical plot with rays traveling more than 360.0 degrees.
        """
        with ImageComparison(self.image_dir,
                             "spherical_more_then_360.png") as ic:
            self.model.get_ray_paths(0, 10, phase_list=["PPPPPP"]).plot_rays(
                plot_type="spherical",
                plot_all=True,
                show=False,
                phase_list=['PPPPPP'])
            plt.savefig(ic.name)

    def test_spherical_diff_phases(self):
        """
        Spherical plot of ``diff`` phases.
        """
        with ImageComparison(self.image_dir,
                             "spherical_diff_phases.png") as ic:
            self.model.get_ray_paths(700,
                                     140,
                                     phase_list=[
                                         "Pdiff", "Sdiff", "pSdiff", "sSdiff",
                                         "pPdiff", "sPdiff"
                                     ]).plot_rays(phase_list=[
                                         "Pdiff", "Sdiff", "pSdiff", "sSdiff",
                                         "pPdiff", "sPdiff"
                                     ],
                                                  plot_type="spherical",
                                                  legend=True,
                                                  plot_all=True,
                                                  show=False)
            plt.savefig(ic.name)

    def test_cartesian_many_phases(self):
        """
         Cartesian plot of the ray paths for many phases for a single
         epicentral distance, but both ways around the globe.
         """
        with ImageComparison(self.image_dir,
                             "cartesian_many_phases.png") as ic:
            self.model.get_ray_paths(500, 140).plot_rays(plot_type="cartesian",
                                                         plot_all=True,
                                                         show=False)
            plt.savefig(ic.name)

    def test_cartesian_many_phases_buried_station(self):
        """
        Same as test_cartesian_many_phases but this time the receiver is
        buried.
        """
        with ImageComparison(self.image_dir,
                             "cartesian_many_phases_buried_station.png") as ic:
            arrivals = self.model.get_ray_paths(500,
                                                140,
                                                receiver_depth_in_km=1000)
            arrivals.plot_rays(plot_type="cartesian",
                               plot_all=True,
                               show=False)
            plt.savefig(ic.name)

    def test_cartesian_many_phases_one_way(self):
        """
        Same as test_cartesian_many_phases but this time no phases
        travelling the other way around the globe are plotted.
        """
        arrivals = self.model.get_ray_paths(500, 140)
        with ImageComparison(self.image_dir,
                             "cartesian_many_phases_one_way.png") as ic:
            arrivals.plot_rays(plot_type="cartesian",
                               plot_all=False,
                               show=False)
            plt.savefig(ic.name)
        # check warning message on deprecated routine
        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter("always")
            with ImageComparison(self.image_dir,
                                 "cartesian_many_phases_one_way.png") as ic:
                # default for legend was True in legacy method
                arrivals.plot(plot_type="cartesian",
                              plot_all=False,
                              show=False,
                              legend=False)
                plt.savefig(ic.name)
            self.assertGreaterEqual(len(w), 1)
            for w_ in w:
                try:
                    self.assertEqual(
                        str(w[0].message), 'The plot() function is '
                        'deprecated. Please use arrivals.plot_rays()')
                except:
                    continue
                break
            else:
                raise
            self.assertEqual(w[0].category, ObsPyDeprecationWarning)

    def test_plot_travel_times(self):
        """
        Travel time plot for many phases at a single epicentral distance.
        """
        with ImageComparison(self.image_dir,
                             "traveltimes_many_phases.png") as ic:
            self.model.get_ray_paths(
                10, 100, phase_list=("ttbasic", )).plot_times(show=False,
                                                              legend=True)
            plt.savefig(ic.name)

    def test_plot_travel_times_convenience(self):
        """
        Travel time plot for many phases at multiple epicentral distances,
        convenience function
        """
        with ImageComparison(
                self.image_dir,
                "traveltimes_many_phases_multiple_degrees.png") as ic:
            # base line image looks awkward with points at the left/right end
            # of the plot but that's only due to the "classic" style sheet used
            # in tests. default mpl2 style makes room around plotted artists
            # larger point size to ensure plot can fail properly if points
            # should move
            mpl.rcParams['lines.markersize'] = 20
            plot_travel_times(10,
                              phase_list=("P", "S", "SKS", "PP"),
                              min_degrees=40,
                              max_degrees=60,
                              show=False,
                              legend=True,
                              npoints=4)
            plt.savefig(ic.name)

        def _test_plot_all(plot_all):
            mpl.rcParams['lines.markersize'] = 200
            plot_travel_times(10,
                              phase_list=("SSS", ),
                              min_degrees=150,
                              max_degrees=200,
                              npoints=4,
                              legend=False,
                              plot_all=plot_all)

        # now test option plot_all=False
        with ImageComparison(self.image_dir,
                             "traveltimes_plot_all_False.png") as ic:
            _test_plot_all(plot_all=False)
            plt.savefig(ic.name)
        # same test should fail if plot_all=True
        tol = {}
        # adjust tolerance on Travis minimum dependency build, tolerance is set
        # so high for that build that image comparison can virtually never
        # fail.. (also adjust for matplotlib 1.2.0 on centos)
        if MATPLOTLIB_VERSION <= [1, 2]:
            tol['reltol'] = 5
            tol['adjust_tolerance'] = False
        with self.assertRaises(ImageComparisonException):
            with ImageComparison(self.image_dir,
                                 "traveltimes_plot_all_False.png",
                                 no_uploads=True,
                                 **tol) as ic:
                _test_plot_all(plot_all=True)
                plt.savefig(ic.name)

    def test_ray_plot_mismatching_axes_type_warnings(self):
        """
        Test warnings when attempting ray path plots in spherical/cartesian
        with bad axes type (polar/not polar).
        """
        arrivals = self.model.get_ray_paths(500, 20, phase_list=['P'])
        # polar pot attempted in cartesian axes
        fig, ax = plt.subplots()
        expected_message = ("Axes instance provided for plotting with "
                            "`plot_type='spherical'` but it seems the axes is "
                            "not a polar axes.")
        try:
            with warnings.catch_warnings(record=True) as w:
                warnings.simplefilter("always")
                # this raises an exception as well:
                # "AttributeError: 'AxesSubplot' object has no attribute "
                # "'set_theta_zero_location'"
                with self.assertRaises(AttributeError):
                    arrivals.plot_rays(plot_type="spherical",
                                       ax=ax,
                                       show=False)
            self.assertEqual(len(w), 1)
            self.assertEqual(str(w[0].message), expected_message)
            self.assertEqual(w[0].category, UserWarning)
        finally:
            plt.close(fig)
        # cartesian pot attempted in polar axes
        fig, ax = plt.subplots(subplot_kw=dict(projection='polar'))
        expected_message = ("Axes instance provided for plotting with "
                            "`plot_type='cartesian'` but it seems the axes is "
                            "a polar axes.")
        try:
            with warnings.catch_warnings(record=True) as w:
                warnings.simplefilter("always")
                arrivals.plot_rays(plot_type="cartesian", ax=ax, show=False)
            self.assertEqual(len(w), 1)
            self.assertEqual(str(w[0].message), expected_message)
            self.assertEqual(w[0].category, UserWarning)
        finally:
            plt.close(fig)

    def test_invalid_plot_option(self):
        """
        Test error message when attempting ray path plots with invalid plot
        type
        """
        arrivals = self.model.get_ray_paths(500, 20, phase_list=['P'])
        # polar plot attempted in cartesian axes
        expected_msg = "Plot type 'spam' is not a valid option."
        with self.assertRaisesRegexp(ValueError, expected_msg):
            arrivals.plot_rays(plot_type="spam")
Пример #45
0
from obspy.taup import taup_create, TauPyModel

tvel = u'/Users/dmelgar/FakeQuakes/M6_validation/structure/test.tvel'
out = '/Users/dmelgar/FakeQuakes/M6_validation/structure/'

print 'Building model'

taup_create.build_taup_model(tvel, output_folder=out)

print 'Loading model'
velmod = TauPyModel(
    model='/Users/dmelgar/FakeQuakes/M6_validation/structure/test.npz',
    verbose=True)

print 'Getting phases'
#paths=velmod.get_ray_paths(10.1,1.0,phase_list=['S','s','Sn'])
#paths2=velmod.get_ray_paths(10.1,3.0,phase_list=['S','s','Sn'])
paths3 = velmod.get_ray_paths(18,
                              0.4,
                              phase_list=['S', 's', 'Sn', 'SmS', 'Sm'])

paths3.plot(plot_type='cartesian')
#paths.plot(plot_type='cartesian')
#paths2.plot(plot_type='cartesian')

#from obspy.taup import TauPyModel
#
#velmod=TauPyModel(model='iasp91')
#paths=velmod.get_ray_paths(10.1,3.0,phase_list=['p','P','Pn','S','s','Sn'])
#paths.plot(plot_type='cartesian')
Пример #46
0
    ASH = -qL * np.cos(jS) - pL * np.sin(jS)

    return AP, ASV, ASH


# Earth testing
earth = TauPyModel(model="iasp91")
etimes = earth.get_travel_times(source_depth_in_km=55,
                                distance_in_degree=40,
                                phase_list=["P", "S"])
print('EARTH')
print(etimes)
print(etimes[0].time, etimes[0].ray_param, etimes[0].incident_angle)

erays = earth.get_ray_paths(source_depth_in_km=55,
                            distance_in_degree=40,
                            phase_list=["P", "S"])
erays.plot_rays()

# move on to Mars:
radius = 3389.5
mars = TauPyModel(model="TAYAK")
mtimes = mars.get_travel_times(source_depth_in_km=55,
                               distance_in_degree=40,
                               phase_list=["P", "S"])
print('MARS')
print(mtimes)

print(mtimes[0].time, mtimes[0].ray_param, mtimes[0].incident_angle)
# testing...
#incident angle at the station
Пример #47
0
                          ["blue"] * len(Conversion_rec) +
                          ["green"] * len(Underside_refl_src) +
                          ["purple"] * len(Reflection_phases))
    phase_labels = {
        "grey": "Direct/Double/Depth phase",
        "red": "source side",
        "blue": "receiver side",
        "green": "underside reflection",
    }
    """ Vizualize the reflection phases """
    if not os.path.exists(os.path.join(save_path, "ray_paths")):
        os.mkdir(os.path.join(save_path, "ray_paths"))
        for depth in depths:
            for phase in extra_phases:
                arrivals = model.get_ray_paths(source_depth_in_km=depth,
                                               distance_in_degree=epi,
                                               phase_list=[phase])
                if not arrivals:
                    continue
                ax = arrivals.plot_rays(plot_type="cartesian",
                                        show=False,
                                        legend=True)
                plt.savefig(
                    os.path.join(save_path, "ray_paths", f"d_{depth}_{phase}"))
                plt.close()
    """ Define forward solver """

    fwd = SS_MTI.Forward.Instaseis(
        instaseis_db=db,
        taup_model=npz_file,
        or_time=or_time,