1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

# http://pyrocko.org - GPLv3 

# 

# The Pyrocko Developers, 21st Century 

# ---|P------/S----------~Lg---------- 

from __future__ import division, absolute_import 

 

import os 

import numpy as num 

 

from pyrocko import util, trace 

from .io_common import FileLoadError 

 

 

class KanError(Exception): 

pass 

 

 

class KanFile: 

 

nbytes_header = 512 

 

def __init__(self, *args, **kwargs): 

if args: 

self.read(*args, **kwargs) 

else: 

self.clear() 

 

def clear(self): 

'''Empty file record.''' 

 

# set the required attributes 

self.delta = 1.0 

self.npts = 0 

self.b = 0.0 

self.data = [num.arange(0, dtype=num.int32)] 

 

def read(self, filename, load_data=True): 

'''Read SAC file. 

 

filename -- Name of KAN file. 

load_data -- If True, the data is read, otherwise only read headers. 

''' 

nbh = KanFile.nbytes_header 

 

# read in all data 

with open(filename, 'rb') as f: 

if load_data: 

filedata = f.read() 

else: 

filedata = f.read(nbh) 

 

if len(filedata) < nbh: 

raise KanError('File too short to be a KAN file.') 

 

header_records = int(filedata[0:8]) 

npts = int(filedata[8:20]) 

leven = int(filedata[20:28]) 

datatype = int(filedata[28:36]) 

rate = float(filedata[36:50]) 

offset = float(filedata[50:64]) 

byte_sex = ('little', 'big')[int(filedata[382:390])] 

 

assert header_records == 1 

assert leven == 1 

assert datatype == 2 

assert offset == 0.0 

 

date = str(filedata[393:405].decode('ascii')).strip() 

tim = str(filedata[405:415].decode('ascii')).strip() 

microseconds = int(filedata[415:423]) 

ref_time = util.to_time_float(util.ctimegm('%s %s' % (date, tim))) \ 

+ microseconds/1.0e6 

 

stationname = os.path.basename(filename) 

stationname = stationname.replace('.kan', '') 

stationname = stationname.replace('.KAN', '') 

 

self.npts = npts 

self.delta = 1.0/rate 

self.kstnm = stationname 

self.ref_time = ref_time 

 

if load_data: 

if byte_sex == 'little': 

dtype = '<i4' 

else: 

dtype = '>i4' 

 

self.data = num.fromstring(filedata[nbh:], dtype=dtype) 

 

assert self.data.size == self.npts 

else: 

self.data = None 

 

def to_trace(self): 

return trace.Trace( 

'', self.kstnm, '', '', 

self.ref_time, 

self.ref_time+self.delta*(self.npts-1), 

self.delta, 

self.data) 

 

 

def iload(filename, load_data): 

try: 

kanf = KanFile(filename, load_data=load_data) 

tr = kanf.to_trace() 

yield tr 

 

except (OSError, KanError) as e: 

raise FileLoadError(e)