Staniční metadata a přístrojové odezvy


In [1]:
%pylab inline
from __future__ import print_function
import matplotlib.pylab as plt
plt.style.use('ggplot')
plt.rcParams['figure.figsize'] = 12, 8
import warnings
warnings.filterwarnings("ignore")
Populating the interactive namespace from numpy and matplotlib
In [3]:
from obspy.core import read, UTCDateTime
from obspy import read_inventory

Funkce read_inventory umožňuje načíst staniční metadata uložená v různých formátech do jednotného objektu Inventory.


Podporované formáty: INVENTORYXML (Arclink), RESP, SC3ML (Seiscomp), SEED, XSEED (SEED ascii verze), STATIONTXT, STATIONXML.

Formát XML je ascii, což umožňuje i přímou editaci souborů. Například CZ_XT_Z3.xml byl vytvořen poskládáním všech STATIONXML souborů pro stanice:

  • net CZ: české permanetní stanice, metadata uložená v silo:/arch/service/gfu/dataless/XML_2018MAY
  • net XT/CZ: stanice MOBNETu v AlpArray-EASI, metadata vlastní výroby
  • net Z3/CZ: stanice MOBNETu v AlpArray, metadata vlastní výroby
In [4]:
inv = read_inventory("CZ_XT_Z3.xml")
print(inv)
Inventory created at 2018-05-02T12:35:49.134000Z
	Created by: fdsn-stationxml-converter/1.0.9
		    http://www.iris.edu/fdsnstationconverter
	Sending institution: IG
	Contains:
		Networks (3):
			CZ, XT, Z3
		Stations (65):
			CZ.CHVC (Chvalec)
			CZ.CKRC (Cesky Krumlov)
			CZ.DPC (Dobruska/Polom, CZ)
			CZ.GOPC (Pecny)
			CZ.HSKC (Hora Sv.Kateriny)
			CZ.JAVC (Velka Javorina)
			CZ.KHC (Kasperske Hory)
			CZ.KRLC (Kraliky)
			CZ.KRUC (Moravsky Krumlov)
			CZ.LACW (Lazy)
			CZ.MORC (Moravsky Beroun)
			CZ.NKC (Novy Kostel)
			CZ.OKC (Ostrava/Krasne Pole)
			CZ.OSTC (Ostas)
			CZ.PBCC (Pribram)
			CZ.PRA (Praha)
			CZ.PRU (Pruhonice)
			CZ.PVCC (Panska Ves, CZ)
			CZ.SKAC (Skalice)
			CZ.STCW (Studenec)
			CZ.STEB (Steborice)
			CZ.TREC (Trest)
			CZ.UPC (Upice)
			CZ.VRAC (Vranov)
			XT.AAE01 (Hora Svate Kateriny, Czech Republic)
			XT.AAE02 (Hora Svateho Sebastiana, Czech Republic)
			XT.AAE03 (Drouzkovice, Czech Republic)
			XT.AAE04 (Uhostany, Czech Republic)
			XT.AAE05 (Krasny Dvur, Czech Republic)
			XT.AAE06 (Valec, Czech Republic)
			XT.AAE07 (Ostrovec, Czech Republic)
			XT.AAE08 (Manetin, Czech Republic)
			XT.AAE09 (Obora, Czech Republic)
			XT.AAE10 (Ceminy, Czech Republic)
			XT.AAE11 (Stary Plzenec, Czech Republic)
			XT.AAE12 (Dnesice, Czech Republic)
			XT.AAE13 (Lazne Letiny, Czech Republic)
			XT.AAE14 (Dolany, Czech Republic)
			XT.AAE15 (Zdeborice, Czech Republic)
			XT.AAE16 (Depoltice, Czech Republic)
			XT.AAE17 (Dobra Voda, Czech Republic)
			XT.AAE18 (Schwellhausl, Germany)
			XT.AAE19 (Breznik, Czech Republic)
			XT.AAE20 (Eppenschlag, Germany)
			Z3.A071A (Stare Sedliste, Czech Republic)
			Z3.A072A (Chudenice, Czech Republic)
			Z3.A073A (Manetin, Czech Republic)
			Z3.A074A (Kozel, Czech Republic)
			Z3.A075A (Krivoklat, Czech Republic)
			Z3.A076A (Makova Hora, Czech Republic)
			Z3.A077A (Kestrany, Czech Republic)
			Z3.A078A (Klet, Czech Republic)
			Z3.A079A (Drachov, Czech Republic)
			Z3.A080A (Loreta, Czech Republic)
			Z3.A081A (Dobrichov, Czech Republic)
			Z3.A082A (Zivanice, Czech Republic)
			Z3.A083A (Cachotin, Czech Republic)
			Z3.A084A (Bitov, Czech Republic)
			Z3.A085A (Strazek, Czech Republic)
			Z3.A086A (Nove Hrady, Czech Republic)
			Z3.A087A (Bouzov, Czech Republic)
			Z3.A088A (Tovacov, Czech Republic)
			Z3.A088B (Tovacov, Czech Republic)
			Z3.A089A (Nesovice, Czech Republic)
			Z3.A090A (Maruska, Czech Republic)
		Channels (678):
			CZ.CHVC..BHZ, CZ.CHVC..BHN, CZ.CHVC..BHE, CZ.CHVC..HHZ, 
			CZ.CHVC..HHN, CZ.CHVC..HHE, CZ.CKRC..BHZ, CZ.CKRC..BHN, 
			CZ.CKRC..BHE, CZ.CKRC..HHZ, CZ.CKRC..HHN, CZ.CKRC..HHE, 
			CZ.DPC..BHZ (6x), CZ.DPC..BHN (6x), CZ.DPC..BHE (6x), 
			CZ.DPC..BNZ (2x), CZ.DPC..BNN (2x), CZ.DPC..BNE (2x), 
			CZ.DPC..HHZ (4x), CZ.DPC..HHN (4x), CZ.DPC..HHE (4x), CZ.DPC..HNZ, 
			CZ.DPC..HNN, CZ.DPC..HNE, CZ.DPC..LCE, CZ.DPC..LCQ, CZ.DPC..VCO, 
			CZ.DPC..VEA, CZ.DPC..VEC, CZ.DPC..VEP, CZ.DPC..VKI, CZ.DPC..VMU, 
			CZ.DPC..VMV, CZ.DPC..VMW, CZ.DPC..VPB, CZ.GOPC..BHZ, CZ.GOPC..BHN, 
			CZ.GOPC..BHE, CZ.GOPC..HHZ, CZ.GOPC..HHN, CZ.GOPC..HHE, 
			CZ.HSKC..BHZ, CZ.HSKC..BHN, CZ.HSKC..BHE, CZ.HSKC..HHZ, 
			CZ.HSKC..HHN, CZ.HSKC..HHE, CZ.HSKC..LCE, CZ.HSKC..LCQ, 
			CZ.HSKC..VCO, CZ.HSKC..VEA, CZ.HSKC..VEC, CZ.HSKC..VEP, 
			CZ.HSKC..VKI, CZ.HSKC..VMU, CZ.HSKC..VMV, CZ.HSKC..VMW, 
			CZ.HSKC..VPB, CZ.JAVC..BHZ, CZ.JAVC..BHN, CZ.JAVC..BHE, 
			CZ.JAVC..HHZ, CZ.JAVC..HHN, CZ.JAVC..HHE, CZ.JAVC..LCQ, 
			CZ.JAVC..UFC, CZ.KHC..BHZ (3x), CZ.KHC..BHN (3x), CZ.KHC..BHE (3x)
			CZ.KHC..EHZ, CZ.KHC..EHN, CZ.KHC..EHE, CZ.KHC..HHZ (2x), 
			CZ.KHC..HHN (2x), CZ.KHC..HHE (2x), CZ.KHC..LCE, CZ.KHC..LCQ, 
			CZ.KHC..SHZ (2x), CZ.KHC..SHN (2x), CZ.KHC..SHE (2x), CZ.KHC..VCO, 
			CZ.KHC..VEA, CZ.KHC..VEC, CZ.KHC..VEP, CZ.KHC..VKI, CZ.KHC..VMU, 
			CZ.KHC..VMV, CZ.KHC..VMW, CZ.KHC..VPB, CZ.KRLC..BHZ (2x), 
			CZ.KRLC..BHN (2x), CZ.KRLC..BHE (2x), CZ.KRLC..HHZ (2x), 
			CZ.KRLC..HHN (2x), CZ.KRLC..HHE (2x), CZ.KRUC..BHZ (2x), 
			CZ.KRUC..BHN (2x), CZ.KRUC..BHE (2x), CZ.KRUC..HHZ (2x), 
			CZ.KRUC..HHN (2x), CZ.KRUC..HHE (2x), CZ.KRUC..LCE, 
			CZ.KRUC..LCQ (2x), CZ.KRUC..UFC, CZ.KRUC..VCO, CZ.KRUC..VEA, 
			CZ.KRUC..VEC, CZ.KRUC..VEP, CZ.KRUC..VKI, CZ.KRUC..VMU, 
			CZ.KRUC..VMV, CZ.KRUC..VMW, CZ.KRUC..VPB, CZ.LACW..BHZ, 
			CZ.LACW..BHN, CZ.LACW..BHE, CZ.LACW..HHZ, CZ.LACW..HHN, 
			CZ.LACW..HHE, CZ.MORC..BHZ (2x), CZ.MORC..BHN (2x), 
			CZ.MORC..BHE (2x), CZ.MORC..HHZ (2x), CZ.MORC..HHN (2x), 
			CZ.MORC..HHE (2x), CZ.MORC..LCE, CZ.MORC..LCQ (2x), CZ.MORC..UFC, 
			CZ.MORC..VCO, CZ.MORC..VEA, CZ.MORC..VEC, CZ.MORC..VEP, 
			CZ.MORC..VKI, CZ.MORC..VMU, CZ.MORC..VMV, CZ.MORC..VMW, 
			CZ.MORC..VPB, CZ.NKC..BHZ (3x), CZ.NKC..BHN (3x), CZ.NKC..BHE (3x)
			CZ.NKC..HHZ (2x), CZ.NKC..HHN (2x), CZ.NKC..HHE (2x), 
			CZ.NKC..HNZ (2x), CZ.NKC..HNN (2x), CZ.NKC..HNE (2x), CZ.NKC..LCE, 
			CZ.NKC..LCQ, CZ.NKC..VCO, CZ.NKC..VEA, CZ.NKC..VEC, CZ.NKC..VEP, 
			CZ.NKC..VKI, CZ.NKC..VMU, CZ.NKC..VMV, CZ.NKC..VMW, CZ.NKC..VPB, 
			CZ.OKC..BHZ (3x), CZ.OKC..BHN (3x), CZ.OKC..BHE (3x), CZ.OKC..EHZ, 
			CZ.OKC..EHN, CZ.OKC..EHE, CZ.OKC..HHZ (2x), CZ.OKC..HHN (2x), 
			CZ.OKC..HHE (2x), CZ.OKC..LCE, CZ.OKC..LCQ, CZ.OKC..SHZ (2x), 
			CZ.OKC..SHN (2x), CZ.OKC..SHE (2x), CZ.OKC..VCO, CZ.OKC..VEA, 
			CZ.OKC..VEC, CZ.OKC..VEP, CZ.OKC..VKI, CZ.OKC..VMU, CZ.OKC..VMV, 
			CZ.OKC..VMW, CZ.OKC..VPB, CZ.OSTC..BHZ, CZ.OSTC..BHN, CZ.OSTC..BHE
			CZ.OSTC..HHZ, CZ.OSTC..HHN, CZ.OSTC..HHE, CZ.PBCC..BHZ, 
			CZ.PBCC..BHN, CZ.PBCC..BHE, CZ.PBCC..HHZ, CZ.PBCC..HHN, 
			CZ.PBCC..HHE, CZ.PRA..BHZ, CZ.PRA..BHN, CZ.PRA..BHE, CZ.PRA..HHZ, 
			CZ.PRA..HHN, CZ.PRA..HHE, CZ.PRU..BHZ (3x), CZ.PRU..BHN (3x), 
			CZ.PRU..BHE (3x), CZ.PRU..EHZ (2x), CZ.PRU..EHN (2x), 
			CZ.PRU..EHE (2x), CZ.PRU..HHZ (3x), CZ.PRU..HHN (3x), 
			CZ.PRU..HHE (3x), CZ.PRU..LCE, CZ.PRU..LCQ, CZ.PRU..SHZ (2x), 
			CZ.PRU..SHN (2x), CZ.PRU..SHE (2x), CZ.PRU..VCO, CZ.PRU..VEA, 
			CZ.PRU..VEC, CZ.PRU..VEP, CZ.PRU..VKI, CZ.PRU..VMU, CZ.PRU..VMV, 
			CZ.PRU..VMW, CZ.PRU..VPB, CZ.PVCC..BHZ (3x), CZ.PVCC..BHN (3x), 
			CZ.PVCC..BHE (3x), CZ.PVCC..HHZ (2x), CZ.PVCC..HHN (2x), 
			CZ.PVCC..HHE (2x), CZ.PVCC..LCE, CZ.PVCC..LCQ, CZ.PVCC..VCO, 
			CZ.PVCC..VEA, CZ.PVCC..VEC, CZ.PVCC..VEP, CZ.PVCC..VKI, 
			CZ.PVCC..VMU, CZ.PVCC..VMV, CZ.PVCC..VMW, CZ.PVCC..VPB, 
			CZ.SKAC..BHZ, CZ.SKAC..BHN, CZ.SKAC..BHE, CZ.SKAC..HHZ, 
			CZ.SKAC..HHN, CZ.SKAC..HHE, CZ.STCW..HHZ, CZ.STCW..HHN, 
			CZ.STCW..HHE, CZ.STEB..BHZ, CZ.STEB..BHN, CZ.STEB..BHE, 
			CZ.STEB..EHZ, CZ.STEB..EHN, CZ.STEB..EHE, CZ.TREC..BHZ (2x), 
			CZ.TREC..BHN (2x), CZ.TREC..BHE (2x), CZ.TREC..HHZ (2x), 
			CZ.TREC..HHN (2x), CZ.TREC..HHE (2x), CZ.TREC..LCE, CZ.TREC..LCQ, 
			CZ.TREC..VCO, CZ.TREC..VEA, CZ.TREC..VEC, CZ.TREC..VEP, 
			CZ.TREC..VKI, CZ.TREC..VMU, CZ.TREC..VMV, CZ.TREC..VMW, 
			CZ.TREC..VPB, CZ.UPC..BHZ (2x), CZ.UPC..BHN (2x), CZ.UPC..BHE (2x)
			CZ.UPC..HHZ (2x), CZ.UPC..HHN (2x), CZ.UPC..HHE (2x), CZ.UPC..LCE
			CZ.UPC..LCQ, CZ.UPC..VCO, CZ.UPC..VEA, CZ.UPC..VEC, CZ.UPC..VEP, 
			CZ.UPC..VKI, CZ.UPC..VMU, CZ.UPC..VMV, CZ.UPC..VMW, CZ.UPC..VPB, 
			CZ.VRAC..BHZ (2x), CZ.VRAC..BHN (2x), CZ.VRAC..BHE (2x), 
			CZ.VRAC..HHZ (2x), CZ.VRAC..HHN (2x), CZ.VRAC..HHE (2x), 
			CZ.VRAC..LCE, CZ.VRAC..LCQ, CZ.VRAC..VCO, CZ.VRAC..VEA, 
			CZ.VRAC..VEC, CZ.VRAC..VEP, CZ.VRAC..VKI, CZ.VRAC..VMU, 
			CZ.VRAC..VMV, CZ.VRAC..VMW, CZ.VRAC..VPB, XT.AAE01..HHZ (2x), 
			XT.AAE01..HHN (2x), XT.AAE01..HHE (2x), XT.AAE02..HHZ (2x), 
			XT.AAE02..HHN, XT.AAE02..HHE, XT.AAE02..HH2, XT.AAE02..HH3, 
			XT.AAE03..HHZ (2x), XT.AAE03..HHN (2x), XT.AAE03..HHE (2x), 
			XT.AAE04..HHZ, XT.AAE04..HH2, XT.AAE04..HH3, XT.AAE05..HHZ (3x), 
			XT.AAE05..HHN (3x), XT.AAE05..HHE (3x), XT.AAE06..HHZ (3x), 
			XT.AAE06..HHN (3x), XT.AAE06..HHE (3x), XT.AAE07..HHZ (2x), 
			XT.AAE07..HHN (2x), XT.AAE07..HHE (2x), XT.AAE08..HHZ (2x), 
			XT.AAE08..HHN (2x), XT.AAE08..HHE (2x), XT.AAE09..HHZ (2x), 
			XT.AAE09..HHN (2x), XT.AAE09..HHE (2x), XT.AAE10..HHZ (3x), 
			XT.AAE10..HHN, XT.AAE10..HHE, XT.AAE10..HH2 (2x), 
			XT.AAE10..HH3 (2x), XT.AAE11..HHZ (2x), XT.AAE11..HHN, 
			XT.AAE11..HHE, XT.AAE11..HH2, XT.AAE11..HH3, XT.AAE12..HHZ (2x), 
			XT.AAE12..HHN (2x), XT.AAE12..HHE (2x), XT.AAE13..HHZ (3x), 
			XT.AAE13..HHN, XT.AAE13..HHE, XT.AAE13..HH2 (2x), 
			XT.AAE13..HH3 (2x), XT.AAE14..HHZ (2x), XT.AAE14..HHN (2x), 
			XT.AAE14..HHE (2x), XT.AAE15..HHZ (2x), XT.AAE15..HHN (2x), 
			XT.AAE15..HHE (2x), XT.AAE16..HHZ (2x), XT.AAE16..HHN (2x), 
			XT.AAE16..HHE (2x), XT.AAE17..HHZ (3x), XT.AAE17..HHN (2x), 
			XT.AAE17..HHE (2x), XT.AAE17..HH2, XT.AAE17..HH3, 
			XT.AAE18..HHZ (3x), XT.AAE18..HHN, XT.AAE18..HHE, 
			XT.AAE18..HH2 (2x), XT.AAE18..HH3 (2x), XT.AAE19..HHZ (2x), 
			XT.AAE19..HHN, XT.AAE19..HHE, XT.AAE19..HH2, XT.AAE19..HH3, 
			XT.AAE20..HHZ (2x), XT.AAE20..HHN (2x), XT.AAE20..HHE (2x), 
			Z3.A071A..HHZ, Z3.A071A..HHN, Z3.A071A..HHE, Z3.A072A..HHZ (2x), 
			Z3.A072A..HHN (2x), Z3.A072A..HHE (2x), Z3.A073A..HHZ, 
			Z3.A073A..HHN, Z3.A073A..HHE, Z3.A074A..HHZ, Z3.A074A..HHN, 
			Z3.A074A..HHE, Z3.A075A..HHZ (3x), Z3.A075A..HHN (3x), 
			Z3.A075A..HHE (3x), Z3.A076A..HHZ, Z3.A076A..HHN, Z3.A076A..HHE, 
			Z3.A077A..HHZ (2x), Z3.A077A..HHN (2x), Z3.A077A..HHE (2x), 
			Z3.A078A..HHZ, Z3.A078A..HHN, Z3.A078A..HHE, Z3.A079A..HHZ, 
			Z3.A079A..HHN, Z3.A079A..HHE, Z3.A080A..HHZ, Z3.A080A..HHN, 
			Z3.A080A..HHE, Z3.A081A..HHZ (4x), Z3.A081A..HHN (4x), 
			Z3.A081A..HHE (4x), Z3.A082A..HHZ, Z3.A082A..HHN, Z3.A082A..HHE, 
			Z3.A083A..HHZ (2x), Z3.A083A..HHN (2x), Z3.A083A..HHE (2x), 
			Z3.A084A..HHZ, Z3.A084A..HHN, Z3.A084A..HHE, Z3.A085A..HHZ (3x), 
			Z3.A085A..HHN (3x), Z3.A085A..HHE (3x), Z3.A086A..HHZ (2x), 
			Z3.A086A..HHN (2x), Z3.A086A..HHE (2x), Z3.A087A..HHZ (2x), 
			Z3.A087A..HHN (2x), Z3.A087A..HHE (2x), Z3.A088A..HHZ (2x), 
			Z3.A088A..HHN (2x), Z3.A088A..HHE (2x), Z3.A088B..HHZ (2x), 
			Z3.A088B..HHN, Z3.A088B..HHE, Z3.A088B..HH1, Z3.A088B..HH2, 
			Z3.A089A..HHZ, Z3.A089A..HHN, Z3.A089A..HHE, Z3.A090A..HHZ (3x), 
			Z3.A090A..HHN (2x), Z3.A090A..HHE (2x), Z3.A090A..HH1, 
			Z3.A090A..HH2

Inventory

In [5]:
inv.plot(projection="ortho", label=False, color_per_network=True),
Out[5]:
(<matplotlib.figure.Figure at 0x1257e860>,)
In [6]:
plt.rcParams['figure.figsize'] = 12, 8
inv.plot(projection='local', color_per_network=True),
Out[6]:
(<matplotlib.figure.Figure at 0x104321d0>,)

Příklad použití metadat (lat, long, elev) uložených v Catalog pro výpočet arrayové odezvy / Array response function, pomocí procedury array_transff_wavenumber.

In [7]:
import numpy as np
from obspy.imaging.cm import viridis_r as cmap
from obspy.signal.array_analysis import array_transff_wavenumber

# array coordinates
coords = []
for net in inv.networks:
    for stat in net.stations:
        coords.append([stat.longitude, stat.latitude, stat.elevation/1000.])
coords = np.asarray(coords)
coords_CZ = []
for net in inv.select(network="CZ").networks:
    for stat in net.stations:
        coords_CZ.append([stat.longitude, stat.latitude, stat.elevation/1000.])
coords_CZ = np.asarray(coords_CZ)
        
# set limits for wavenumber differences to analyze
klim = 0.1; kstep = klim / 100.
kxmin = -klim; kxmax = klim
kymin = -klim; kymax = klim

# compute transfer function as a function of wavenumber difference
transff = array_transff_wavenumber(coords, klim, kstep, coordsys='lonlat')
transff_CZ = array_transff_wavenumber(coords_CZ, klim, kstep, coordsys='lonlat')

# FIGURE
fig = plt.figure(figsize=(14.5,6))
ax1 = fig.add_subplot(1,2,1)
ax2 = fig.add_subplot(1,2,2)
# plot CZ + AlpArray
sc1 = ax1.pcolor(np.arange(kxmin, kxmax + kstep * 1.1, kstep) - kstep / 2.,
           np.arange(kymin, kymax + kstep * 1.1, kstep) - kstep / 2.,
           transff.T, cmap=cmap)
plt.colorbar(sc1, ax=ax1)
sc1.set_clim(vmin=0., vmax=1.)
ax1.set_xlim(kxmin, kxmax); ax1.set_ylim(kymin, kymax)
ax1.set_xlabel('$K=1/\lambda \quad [m^{-1}]$')
ax1.set_ylabel('$K=1/\lambda \quad [m^{-1}]$')
ax1.set_title('Array response function: CZ + AlpArray')
# plot CZ PERM only
sc2 = plt.pcolor(np.arange(kxmin, kxmax + kstep * 1.1, kstep) - kstep / 2.,
            np.arange(kymin, kymax + kstep * 1.1, kstep) - kstep / 2.,
            transff_CZ.T, cmap=cmap)
plt.colorbar(sc2, ax=ax2)
sc2.set_clim(vmin=0., vmax=1.)
ax2.set_xlim(kxmin, kxmax); plt.ylim(kymin, kymax)
ax2.set_xlabel('$K=1/\lambda \quad [m^{-1}]$')
ax2.set_ylabel('$K=1/\lambda \quad [m^{-1}]$')
ax2.set_title('Array response function - CZ permanent')
plt.tight_layout()
plt.show()

Odezva seismometru



Informace k odezvě seismometru a datalogeru jsou uložené v Channel.

Podle metadat má stanice KHC v současnosti tyto instrumenty:

  • Streckeisen STS-2 + Quanterra Q330S (BH, HH)
  • krátkoperiodický Vegik + Earth Data PR6-24 (SH) / Quanterra Q330S (EH)
In [8]:
inv_KHC_Z = inv.select(station="KHC", channel="*Z")
print(inv_KHC_Z.select(time=UTCDateTime()).networks[0].stations[0].channels[0])
print(inv_KHC_Z.select(time=UTCDateTime()).networks[0].stations[0].channels[0].response)
print(inv_KHC_Z.select(time=UTCDateTime()).networks[0].stations[0].channels[0].response.response_stages[0])
Channel 'SHZ', Location '' 
	Time range: 2003-10-27T00:00:00.000000Z - --
	Latitude: 49.13, Longitude: 13.58, Elevation: 700.0 m, Local Depth: 0.0 m
	Azimuth: 0.00 degrees from north, clockwise
	Dip: -90.00 degrees down from horizontal
	Channel types: GEOPHYSICAL
	Sampling Rate: 20.00 Hz
	Sensor (Description): None (Vegik short-period/Earth Data PR6-24)
	Response information available
Channel Response
	From M/S (velocity in meters per second) to COUNTS (digital counts)
	Overall Sensitivity: 2.00182e+07 defined at 0.100 Hz
	7 stages:
		Stage 1: PolesZerosResponseStage from M/S to V, gain: 20.0167
		Stage 2: CoefficientsTypeResponseStage from V to COUNTS, gain: 1.0001e+06
		Stage 3: CoefficientsTypeResponseStage from COUNTS to COUNTS, gain: 1
		Stage 4: CoefficientsTypeResponseStage from COUNTS to COUNTS, gain: 1
		Stage 5: CoefficientsTypeResponseStage from COUNTS to COUNTS, gain: 1
		Stage 6: CoefficientsTypeResponseStage from COUNTS to COUNTS, gain: 1
		Stage 7: CoefficientsTypeResponseStage from COUNTS to COUNTS, gain: 1
Response type: PolesZerosResponseStage, Stage Sequence Number: 1
	From M/S (velocity in meters per second) to V (emf in volts)
	Stage gain: 20.0167, defined at 0.10 Hz
	Transfer function type: LAPLACE (RADIANS/SECOND)
	Normalization factor: 2.96906e+13, Normalization frequency: 0.10 Hz
	Poles: (-13.6006+33.2863j), (-13.6006-33.2863j), (-21.175+24.2739j), (-21.175-24.2739j), (-25.5848+15.9695j), (-25.5848-15.9695j), (-27.9812+7.9335j), (-27.9812-7.9335j), (-28.7466+0j), (-0.037004+0.037016j), (-0.037004-0.037016j)
	Zeros: 0j, 0j

Jeden obrázek lepší než plno textu ...

In [9]:
# díky time=UTCDateTime() vybere jen současné odezvy
inv_KHC_Z.plot_response(min_freq=0.001, time=UTCDateTime(), unwrap_phase=True),
Out[9]:
(<matplotlib.figure.Figure at 0x12f02e80>,)

Pro srovnání stanice GEC2, v současnosti instrumenty:

  • Streckeisen STS-2 + Nanometrics HRD24 (BH, HH)
  • Geotech GS13 + Nanometrics HRD24 (SH)
In [10]:
inv_GEC2_Z = read_inventory('GR.GEC2.xml', format="STATIONXML").select(channel="*Z")
inv_GEC2_Z.plot_response(min_freq=0.001, time=UTCDateTime()),
Out[10]:
(<matplotlib.figure.Figure at 0x201f2a20>,)

Odstranění odezvy seismometru, simulace jiného seismometru

  • attach_response - přiřadí ke složce signálu správnou staniční odezvu (už to není povinné)
  • remove_response - odstraní ze signálu staniční odezvu
  • simulate a simulate_seismometer - [odstraní ze signálu staniční odezvu a] přidá jinou odezvu

Během odstraňování odezvy/simulace je důležité, aby filtr byl stabilní, tj. aby se neúměrně nezvýraznily některé frekvence. Toto se dá kontrolovat pomocí další filtrace (pre_filt) a/nebo parametru water_level. Pro lepší přehled ObsPy umožňuje vizualizaci jednotlivých kroků, viz remove_response s parametrem plot=True.

In [11]:
t1 = UTCDateTime('20150806092228'); t2 = t1 + 60*60
st = read('KHC.EHZ.*', starttime=t1, endtime=t2)

pre_filt = [0.001, 0.005, 30, 50]
st.remove_response(inventory=inv, pre_filt=pre_filt, output="VEL", water_level=60, plot=True)
Out[11]:
1 Trace(s) in Stream:
CZ.KHC..EHZ | 2015-08-06T09:22:27.998400Z - 2015-08-06T10:22:27.998400Z | 100.0 Hz, 360001 samples

Příprava signálů na korelační pickování teleseismické P vlny

Signály P vlny na všech stanicích musí být podobné, odstranění odezvy seismometru pomůže (obzvláště při kombinaci krátkoperiodických a širokopásmových stanic. Výbornou kontrolou správného postupu jsou stanice s více instrumenty. Zde jako příklad ukážeme KHC a GEC2.

1. Původní signál

In [12]:
tP_KHC = UTCDateTime('2015-08-06T09:34:45.97') + 0.86             # manuálně určený začátek P vlny u KHC
tP_GEC2 = UTCDateTime('2015-08-06T09:34:46.84') + 0.52 - 0.076    # manuálně určený začátek P vlny u GEC2
inv_duo = inv.select(station='KHC', channel='*HZ') + inv_GEC2_Z   # staniční metadata jen pro tyto stanice

st = read('*.mseed', starttime=tP_KHC-60, endtime=tP_KHC+60).detrend('linear')
print(st)
st.plot(starttime=tP_KHC-5, endtime=tP_KHC+5, equal_scale=False, size=(1200, 600))   # okno +- 5 s kolem P onsetu
4 Trace(s) in Stream:
GR.GEC2..HHZ | 2015-08-06T09:33:46.825000Z - 2015-08-06T09:35:46.825000Z | 80.0 Hz, 9601 samples
GR.GEC2..SHZ | 2015-08-06T09:33:46.825000Z - 2015-08-06T09:35:46.825000Z | 40.0 Hz, 4801 samples
CZ.KHC..EHZ  | 2015-08-06T09:33:46.828400Z - 2015-08-06T09:35:46.828400Z | 100.0 Hz, 12001 samples
CZ.KHC..HHZ  | 2015-08-06T09:33:46.828400Z - 2015-08-06T09:35:46.828400Z | 100.0 Hz, 12001 samples

2. Simulace WWSSN SP odezvy (bez korekce staničních odezev)

aneb bandpass filtr kolem 1 s

In [13]:
paz_wwssn_sp =     {'poles': [-3.367788+3.731514j, -3.367788-3.731514j,
                              -7.037168+4.545562j, -7.037168-4.545562j],
                    'zeros': [0j, 0j],
                    'gain': 70.18386,
                    'sensitivity': 1.}

# sesazení počátků P vln u KHC a GEC2 stanice
for tr in st.select(station='GEC2'):
    tr.stats.starttime -= (tP_GEC2 - tP_KHC)
In [14]:
st_simul1 = st.copy()
st_simul1.simulate(paz_remove=None, paz_simulate=paz_wwssn_sp)
st_simul1.plot(starttime=tP_KHC-5, endtime=tP_KHC+5, equal_scale=False, size=(1200, 600))

3. Korekce staničních odezev a simulace WWSSN SP

In [15]:
pre_filt = [0.001, 0.005, 2, 4]
st_simul2 = st.copy()
st_simul2.attach_response(inv_duo)
st_simul2.remove_response(pre_filt=pre_filt, water_level=1e6)
st_simul2.simulate(paz_remove=None, paz_simulate=paz_wwssn_sp)
st_simul2.plot(starttime=tP_KHC-5, endtime=tP_KHC+5, equal_scale=False, size=(1200, 600))

Korekce mírných posuntí P vln pomocí korelačního xcorr_pick_correction.

In [16]:
from obspy.signal.cross_correlation import xcorr_pick_correction

# všechny stopy vstupující do xcorr_pick_correction musí mít stejný sampling!
for tr in st_simul1:
    if tr.stats.sampling_rate != 100.:
        tr.interpolate(sampling_rate=100.)
for tr in st_simul2:
    if tr.stats.sampling_rate != 100.:
        tr.interpolate(sampling_rate=100.)
In [17]:
#tr1 = st_simul2.select(id='GR.GEC2..HHZ')[0]; tr2 = st_simul2.select(id='GR.GEC2..SHZ')[0]
#tr1 = st_simul2.select(id='GR.GEC2..HHZ')[0]; tr2 = st_simul2.select(id='CZ.KHC..HHZ')[0]
tr1 = st_simul2.select(id='CZ.KHC..HHZ')[0]; tr2 = st_simul2.select(id='CZ.KHC..EHZ')[0]; 

dt, coeff = xcorr_pick_correction(tP_KHC, tr1, tP_KHC, tr2, 0.5, 2., 1., plot=True)
print('{:s} - {:s} : {:.3f} s   {:.0f} %'.format(tr2.id, tr1.id, dt, 100.*coeff))
CZ.KHC..EHZ - CZ.KHC..HHZ : 0.099 s   90 %
In [18]:
print('Bez korekce na odezvu seismometru:')
for i,j in [[0,1],[0,3],[3,2]]:
    tr1 = st_simul1[i]; tr2 = st_simul1[j]
    dt, coeff = xcorr_pick_correction(tP_KHC, tr1, tP_KHC, tr2, 0.5, 2., 1., plot=False)
    print('{:<12s} - {:<12s} : {:6.2f} s {:3.0f} %'.format(tr2.id, tr1.id, dt, 100.*coeff))
    
print('\nPo korekci na odezvu seismometru:')
for i,j in [[0,1],[0,3],[3,2]]:
    tr1 = st_simul2[i]; tr2 = st_simul2[j]
    dt, coeff = xcorr_pick_correction(tP_KHC, tr1, tP_KHC, tr2, 0.5, 2., 1., plot=False)
    print('{:<12s} - {:<12s} : {:6.2f} s {:3.0f} %'.format(tr2.id, tr1.id, dt, 100.*coeff))
Bez korekce na odezvu seismometru:
GR.GEC2..SHZ - GR.GEC2..HHZ :  -0.24 s  70 %
CZ.KHC..HHZ  - GR.GEC2..HHZ :  -0.01 s  95 %
CZ.KHC..EHZ  - CZ.KHC..HHZ  :   0.32 s  89 %

Po korekci na odezvu seismometru:
GR.GEC2..SHZ - GR.GEC2..HHZ :   0.00 s  98 %
CZ.KHC..HHZ  - GR.GEC2..HHZ :  -0.00 s  95 %
CZ.KHC..EHZ  - CZ.KHC..HHZ  :   0.10 s  90 %

ZDE NOTEBOOK UKONČÍME

In [ ]:
# dalsi namety:
# PRU   ... SH složka stejně špatná jako u KHC
# A077A ... CMG-3ESP/30s, ukáže rozdíl mezi GAIA1/25Hz a GAIA3

#inv.select(station="A077A", channel="*HZ").plot_response(min_freq=0.001),
In [ ]:
# pomocne funkce k zobrazení response stage
def plot_response_stages(inventory, min_freq, output="VEL", network="*", station="*",
                      location="*", channel="*", time=None, starttime=None,
                      endtime=None, axes=None, unwrap_phase=False, show=True,
                      outfile=None):
    import matplotlib.pyplot as plt

    if axes:
        ax1, ax2 = axes
        fig = ax1.figure
    else:
        fig = plt.figure(figsize=(12,11))
        ax1 = plt.subplot2grid((3,1), (0,0), rowspan=2)
        ax2 = plt.subplot2grid((3,1), (2,0), sharex=ax1)

    matching = inventory.select(network=network, station=station,
                               location=location, channel=channel, time=time,
                               starttime=starttime, endtime=endtime)

    if len(matching.networks) > 1:
        print('WARNING: too much networks, we take the first one from:')
        contents = matching.get_contents()
        print(" ".join(["%s" % _i for _i in contents["networks"]]))
    if len(matching.networks[0].stations) > 1:
        print('WARNING: too much stations, we take the first one from:')
        contents = matching.networks[0].get_contents()
        print(" ".join(["%s" % _i for _i in contents["stations"]]))
    if len(matching.networks[0].stations[0].channels) > 1:
        print('WARNING: too much channels, we take the first one from:')
        print(matching.networks[0].stations[0].__str__().split('\t')[-1])
        
    n_stages = len(matching.networks[0].stations[0].channels[0].response.response_stages)
    stat_id = ".".join((matching.networks[0].code, matching.networks[0].stations[0].code,
                      matching.networks[0].stations[0].channels[0].location_code,
                      matching.networks[0].stations[0].channels[0].code))
    
    for i in range(1,n_stages+1):
        matching.networks[0].stations[0].channels[0].plot(min_freq=min_freq, output=output, 
                            start_stage=i, end_stage=i, axes=(ax1, ax2),
                            label="Stage {0:d}".format(i), unwrap_phase=unwrap_phase, show=False,
                            outfile=None)
    matching.networks[0].stations[0].channels[0].plot(min_freq=min_freq, output=output, 
                            axes=(ax1, ax2),
                            label=stat_id, unwrap_phase=unwrap_phase, show=False,
                            outfile=None)

    # final adjustments to plot if we created the figure in here
    if not axes:
        from obspy.station.response import _adjust_bode_plot_figure
        _adjust_bode_plot_figure(fig, show=False)

    if outfile:
        fig.savefig(outfile)
    else:
        if show:
            plt.show()
            print(stat_id)
            print(matching.networks[0].stations[0].channels[0].response)

    return fig

def inventory_ids(inv):
    inv_ids = []
    for network in inv.networks:
        for station in network.stations:
            for channel in station.channels:
                if channel.start_date:
                    start_date = channel.start_date.strftime('%y%m%d%H%M')
                else:
                    start_date = '0000000000'
                if channel.end_date:
                    end_date = channel.end_date.strftime('%y%m%d%H%M')
                else:
                    end_date = '9999999999'
                inv_id = ".".join((network.code, station.code, channel.location_code, channel.code,
                                start_date, end_date))
                inv_ids.append(inv_id)
    return inv_ids

def inventory_table(inv, output=None):
    if output:
        f = open(output, 'w')
    for network in inv.networks:
        for station in network.stations:
            for channel in station.channels:
                if channel.start_date:
                    start_date = channel.start_date.strftime('%y%m%d%H%M')
                else:
                    start_date = '0000000000'
                if channel.end_date:
                    end_date = channel.end_date.strftime('%y%m%d%H%M')
                else:
                    end_date = '9999999999'
                sss = "{:2s} {:<5s} {:2s} {:8.4f} {:8.4f} {:4.0f}   {:3s} {:10s} {:10s} {:3.0f} {:3.0f}".format(
                    network.code, station.code, channel.location_code, 
                    channel.latitude, channel.longitude, channel.elevation,
                    channel.code, start_date, end_date, channel.dip, channel.azimuth)
                    #inv_id += '.{:03d}.{:03d}'.format(int(round(channel.azimuth)), int(round(channel.dip)))
                print(sss)
                if output:
                    f.write(sss + '\n')
    if output: f.close()
    return
     
def inventory_response_report(inv, output=None, label='---'):
    inv_ids = sorted(inventory_ids(inv))
    if output:
        f = open(output, 'w')
    for inv_id in inv_ids:
        _inv = inv.select(network=inv_id.split('.')[0], station=inv_id.split('.')[1],
                         location=inv_id.split('.')[2], channel=inv_id.split('.')[3],
                         time=UTCDateTime('20'+inv_id.split('.')[4]+'00')+60)
        __inv = inv.select(network=inv_id.split('.')[0], station=inv_id.split('.')[1],
                         location=inv_id.split('.')[2], channel=inv_id.split('.')[3])
        sss = '---- '
        sss += inv_id 
        sss += ' -------------------------------------------' + label + '---\n'
        sss += _inv.networks[0].stations[0].channels[0].response.__str__()
        print(sss)
        if output:
            f.write(sss + '\n')
    if output: f.close()
    return