Earthquakes and maps

So an earthquake has happened... you have see some seismograms using the excellent Python Obsy toolkit and some simple scripts... now you want to plot a map or two.

Simple location map created in Python using the Folium library  
import folium
# setting the boundaries of the map and choosing a map style 
m = folium.Map(location=[50.067, -5.187],zoom_start=10,tiles='Stamen Terrain')
#  put a marker on the map for the reported BGS earthquake location
folium.Marker(location=[50.067,-5.187],popup='quake',icon=folium.Icon(color='red')).add_to(m)
#  next add markers for the locations of all the seismic monitoring stations in Cornwall 
folium.Marker(location=[50.1867,-5.2273], popup='BGS_CCA1', icon=folium.Icon(color='green')).add_to(m)
folium.Marker(location=[50.1486,-5.0945], popup='FL_RB30C', icon=folium.Icon(color='green')).add_to(m)
folium.Marker(location=[50.117, -5.535], popup='PZ_RB5E8', icon=folium.Icon(color='green')).add_to(m)
folium.Marker(location=[50.2344, -5.2384], popup='RD_RD93E', icon=folium.Icon(color='green')).add_to(m)
folium.Marker(location=[50.2596, -5.1027], popup='RL_R82BD', icon=folium.Icon(color='green')).add_to(m)
folium.Marker(location=[50.2609,-5.0434], popup='TS_R7FA5', icon=folium.Icon(color='green')).add_to(m)
#  save the map to a n html file that can be viewed in any browser 
m.save('simple_cornwall_map.html')

Perpendicular Bisectors

When we plotted the seismograms for these stations it was easy to see which station they arrived at first (station CCA1).  It follows that the event location must be closer to this station than any other.   If we consider two stations, e.g. CCA1 and PZ (penzance) the range of possible locations for the earthqauke must be in all the places that are closer to CCA1 than PZ.   This space is bounded by the perpendicular bisector of a line that joins the two stations.   If we carry out this procedure for a range of stations then we can narrow down the range of possible locations to a polygon.    
Estimating location using perpendicular bisectors 
import folium, utm, math

map = folium.Map(location=[50.187, -5.23],zoom_start=10,tiles='Stamen Terrain')

folium.Marker(location=[50.067,-5.187], popup='BGS_quake_location',
    icon=folium.Icon(color='red')).add_to(map)

# station statistics
seislist=['RB30C','RB5E8','RD93E','CCA1','R82BD','R7FA5']
locations=['FL','PZ','RD','CM','RL','TS']
latitudes=[50.1486,50.117,50.2344,50.1867,50.2596,50.2609]
longitudes=[-5.0945,-5.535,-5.2384,-5.2273,-5.1027,-5.0434]
arrival=[ 7.770, 8.46, 8.51,7.377, 9.413, 9.799]
easting=[]
northing=[]
zone=[]
band=[]

for i in range (len(seislist)):
    x, y, z, b = utm.from_latlon(latitudes[i], longitudes[i])
    easting.append(x)
    northing.append(y)
    zone.append(z)
    band.append(b)

#maxstation = len(seislist) # determines which bisectors get plotted
maxstation=len(seislist)-2 #PDS edit miss off CM RL and TS 
for stat1 in range(maxstation-1):
    
    for stat2 in range(stat1+1, maxstation):
        if arrival[stat1]<arrival[stat2]:
            s1 = stat1
            s2 = stat2
        else:
            s1 = stat2
            s2 = stat1
        # join the stations with a line
        folium.PolyLine([(latitudes[s1],longitudes[s1]), (latitudes[s2],longitudes[s2])],
            color="blue", weight=1, opacity=0.5).add_to(map)
        # gradient of perpendicular bisector = -1/gradient of line joining stations
        if northing[s1]-northing[s2] != 0:
            m = (easting[s2]-easting[s1])/(northing[s1]-northing[s2])
        else:
            m = (easting[s2]-easting[s1])/0.0001
        # calculate utm coordinate of midpoint and equation of line
        y = (northing[s1]+northing[s2])/2
        x = (easting[s1]+easting[s2])/2
        c = y - m * x
        # fix length of extrapolated line in x or y direction, depending on m
        d = 30000
        # calculate distance of shading from line
        diff = math.sqrt(15000*15000/(1+m*m))
        if northing[s1]>northing[s2]:
            dy = -1 * diff
        else:
            dy = diff
        if easting[s1]<easting[s2]:
            dx = diff * math.sqrt(m*m)
        else:
            dx = -1 * diff * math.sqrt(m*m)
        if m*m < 1:
            x1 = x-d
            y1 = m * (x-d) + c
            x2 = x+d
            y2 = m * (x+d) + c
        else:
            x1 = ((y-d)-c)/m
            y1 = y-d
            x2 = ((y+d)-c)/m
            y2 = y+d
        # plot the perpendicular bisector
        folium.PolyLine([utm.to_latlon(x1, y1,zone[s1],band[s1]), utm.to_latlon(x2, y2,zone[s1],band[s1])],
            color="black", weight=1, opacity=0.5).add_to(map)
        # plot the shaded polygon
        folium.Polygon([utm.to_latlon(x1, y1,zone[s1],band[s1]), utm.to_latlon(x2, y2,zone[s1],band[s1]),
            utm.to_latlon(x2+dx, y2+dy,zone[s1],band[s1]), utm.to_latlon(x1+dx, y1+dy,zone[s1],band[s1])],            
            color='black', fill=True, weight=0, opacity=1).add_to(map)

for x in range (len(seislist)):
        folium.Marker(location=[latitudes[x],longitudes[x]], popup=[locations[x]], icon=folium.Icon(color='green')).add_to(map)

map.save('cornwall_map4.html')

Intersecting Circles 

If it is possible to identify P and S waves from the seismograms you can estimate how far away the earthquake happened from each station by usinge teh delay time between P and S wave arrivals and knowweledge fo P and S wave evlocities 

Estimating the distance from each seismic station using P-S delay times 


import folium

map = folium.Map(location=[50.187, -5.23],zoom_start=10,tiles='Stamen Terrain')

folium.Marker(location=[50.067,-5.187],
    popup='BGS_quake_location',
    icon=folium.Icon(color='red')
).add_to(map)

# station statistics
seislist=['CCA1','RB30C','RB5E8','RD93E','R82BD','R7FA5']
locations=['CM','FL','PZ','RD','RL','TS']
latitudes=[50.1867,50.1486,50.117,50.2344,50.2596,50.2609]
longitudes=[-5.2273,-5.0945,-5.535,-5.2384,-5.1027,-5.0434]
P_arrival=[7.653, 7.885, 8.441, 8.491, 9.422, 9.802]
S_arrival=[9.57,9.99,10.93,11,12.7,13.5]
radius=[0,0,0,0,0,0]
colours=['red', 'orange', ' beige', 'green', 'blue', 'purple']

for x in range(6):
    ## estimate range for delay time between P and S arrival (P=5.76km/sec S=3.25km/sec)
    radius[x]=(S_arrival[x]-P_arrival[x])*7.48
    
    folium.Marker(location=[latitudes[x],longitudes[x]],
        popup=seislist[x], icon=folium.Icon(color='blue')).add_to(map)

    folium.Circle(
        radius=radius[x]*1000, location=[latitudes[x],longitudes[x]],
        popup=locations[x], color=colours[x], fill=False, weight=1
    ).add_to(map)

map.save('cornwall_map_circles.html')



see https://www.dentonseismo.co.uk for more details of educational and citizen seismology projects and resources 

Comments

Popular posts from this blog

lego seismometer

Getting data from a BBC:microbit

Barnsley Tyke quakes