Skip to content

Commit 5d20e3e

Browse files
committed
Added prelim FPFIT input function to I/O, works for test SCSN data
1 parent 1a1381a commit 5d20e3e

File tree

2 files changed

+193
-1
lines changed

2 files changed

+193
-1
lines changed

hashpy/io/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
"ANTELOPE" : { "module" : "antelopeIO" },
2626

27-
"FPFIT" : { "module" : NotImplemented },
27+
"FPFIT" : { "module" : 'fpfitIO' },
2828
}
2929
##############################################################################
3030

hashpy/io/fpfitIO.py

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
# -*- coding: utf-8 -*-
2+
3+
# INPUT FILE: "fpfile" FPFIT-like format - ** YOU MAY NEED TO CHANGE THE INPUT FORMAT **
4+
#
5+
# event line:
6+
# columns format value
7+
# -------------------------
8+
# 1-4 i4 origin time, year
9+
# 5-12 4i2 origin time, month, day, hour, minute
10+
# 13-17 f5.2 origin time, seconds
11+
# 18-19 i2 latitude, degrees
12+
# 20 a1 latitude, 'S'=south
13+
# 21-25 f5.2 latitude, minutes
14+
# 26-28 i3 longitude, degrees
15+
# 29 a1 longitude, 'E'=east
16+
# 30-34 f5.2 longitude, minutes
17+
# 35-39 f5.2 depth, km
18+
# 89-93 f5.2 horizontal location uncertainty, km
19+
# 95-99 f5.2 vertical location uncertainty, km
20+
# 140-143 f4.2 magnitude
21+
# 150-165 a16 event ID
22+
#
23+
# polarity line:
24+
# columns format value
25+
# -------------------------
26+
# 1-4 a4 station name
27+
# 6-7 a2 station network
28+
# 10-12 a3 station component
29+
# 14 a1 P onset, I or E
30+
# 16 a1 P polarity : U, u, +, D, d, or -
31+
#
32+
import numpy as np
33+
import datetime
34+
35+
degrad = 180. / np.pi
36+
37+
def get_sta_coords(f_sta):
38+
'''
39+
Stub which reads in the HASH example station file
40+
41+
:param f_sta: file handle with station info
42+
43+
:returns: dict of list of floats -> { 'station_code' : [lat, lon, elv] }
44+
45+
'''
46+
coords = {}
47+
for s in f_sta:
48+
sta = s[0:4]
49+
lat = float(s[42:50])
50+
lon = float(s[51:61])
51+
elv = float(s[62:67])/1000.
52+
if sta not in coords:
53+
coords[sta] = [lat,lon,elv]
54+
return coords
55+
56+
def check_polarity_file(polarity_file, sta_name, year, month, day, hour):
57+
"""
58+
Stub for checking polarity file FPFIT style, there's a fortran sub for this,
59+
ideally, rewrite, but this will work for now...
60+
61+
:param str polarity_file: name of polarity file in rando SC esoteric anti-format
62+
63+
"""
64+
from hashpy import libhashpy
65+
return libhashpy.check_pol(polarity_file, sta_name, year, month, day, hour)
66+
67+
def input(hp, files={} ):
68+
"""
69+
Input function for FPFIT-style HASH
70+
71+
:param dict files: dict of str filenames
72+
73+
Input dictionary has keys: ('station', 'polarity', 'input')
74+
for station file, polarity reversal file, and main event/phase
75+
input, respectively.
76+
77+
"""
78+
with open(files['station']) as fs:
79+
sta_coords = get_sta_coords(fs)
80+
81+
with open(files['input']) as fi:
82+
83+
while True:
84+
# read in earthquake location, etc SCEDC format
85+
line = fi.readline()
86+
if not line:
87+
break
88+
89+
iyr = int(line[0:4])
90+
imon = int(line[4:6])
91+
idy = int(line[6:8])
92+
ihr = int(line[8:10])
93+
imn = int(line[10:12])
94+
sec = line[12:17]
95+
ilatd = int(line[17:19])
96+
cns = line[19]
97+
qlatm = float(line[20:25])
98+
ilond = int(line[25:28])
99+
cew = line[28]
100+
qlonm = float(line[29:34])
101+
102+
hp.qdep = float(line[34:39]) # then 49x
103+
hp.seh = float(line[88:93]) # then 1x
104+
hp.sez = float(line[94:99]) # then 40x
105+
hp.qmag = float(line[139:143]) # then 6x
106+
hp.icusp = int(line[149:165])
107+
108+
qsec = float(sec)
109+
secs = sec.split('.')
110+
isec = int(secs[0])
111+
imsec = int(secs[1]+'0000')
112+
dt = datetime.datetime(iyr,imon,idy,ihr,imn,isec,imsec)
113+
hp.tstamp = (dt - datetime.datetime(1970, 1, 1)).total_seconds()
114+
115+
hp.qlat = ilatd + (qlatm / 60.0)
116+
if ('S' in cns):
117+
hp.qlat *= -1
118+
hp.qlon = -(ilond + (qlonm / 60.0))
119+
if ('E' in cew):
120+
hp.qlon *= -1
121+
aspect = np.cos(hp.qlat / degrad)
122+
123+
# set parameters not given in input file
124+
if not hp.sez:
125+
hp.sez = 1.
126+
terr = -9
127+
rms = -9
128+
nppick = -9
129+
nspick = -9
130+
evtype = 'L'
131+
magtype = 'X'
132+
locqual = 'X'
133+
134+
# read in polarities - SCEDC format - ** YOU MAY NEED TO CHANGE THE INPUT FORMAT **
135+
k = 0
136+
while True:
137+
ph = fi.readline()
138+
hp.sname[k] = ph[0:4]
139+
hp.snet[k] = ph[5:7]
140+
hp.scomp[k] = ph[9:12]
141+
hp.pickonset[k] = ph[13]
142+
hp.pickpol[k] = ph[15]
143+
hp.arid[k] = k
144+
145+
if (hp.sname[k] == ' '):
146+
break
147+
148+
#flat,flon,felv = getstat_tri(stfile,sname[k],scomp[k],snet[k])
149+
# SCSN station information - ** YOU MAY NEED TO USE YOUR OWN SUBROUTINE **
150+
#
151+
#-- the above sucks, I needed to use my own subroutine --#
152+
#
153+
if hp.sname[k] in sta_coords:
154+
hp.flat[k], hp.flon[k], hp.felv[k] = sta_coords[hp.sname[k]]
155+
else:
156+
continue
157+
158+
dx = (hp.flon[k] - hp.qlon) * 111.2 * aspect
159+
dy = (hp.flat[k] - hp.qlat) * 111.2
160+
hp.dist[k] = np.sqrt(dx**2 + dy**2)
161+
hp.qazi[k] = 90. - np.arctan2(dy,dx) * degrad
162+
163+
if (hp.qazi[k] < 0.):
164+
hp.qazi[k] += 360.
165+
166+
if (hp.dist[k] > hp.delmax):
167+
continue
168+
169+
if (hp.pickpol[k] in 'Uu+'):
170+
hp.p_pol[k] = 1
171+
elif (hp.pickpol[k] in 'Dd-'):
172+
hp.p_pol[k] = -1
173+
else:
174+
continue
175+
176+
if (hp.pickonset[k] in 'Ii'):
177+
hp.p_qual[k] = 0
178+
else:
179+
hp.p_qual[k] = 1
180+
181+
# Try to check a polarity file using sub
182+
try:
183+
spol = check_polarity_file(files['polarity'], hp.sname[k], iyr, imon, idy, ihr)
184+
except:
185+
spol = 1
186+
finally:
187+
hp.p_pol[k] *= spol
188+
189+
k += 1
190+
continue
191+
hp.npol = k - 1
192+

0 commit comments

Comments
 (0)