Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

# -*- coding: utf-8 -*- 

""" 

SAC bindings to ObsPy core module. 

 

:copyright: 

    The ObsPy Development Team (devs@obspy.org) & C. J. Ammon 

:license: 

    GNU Lesser General Public License, Version 3 

    (http://www.gnu.org/copyleft/lesser.html) 

""" 

 

from obspy import Trace, Stream 

from obspy.sac.sacio import SacIO, _isText 

import os 

import struct 

 

 

def isSAC(filename): 

    """ 

    Checks whether a file is a SAC file or not. 

 

    :type filename: string 

    :param filename: SAC file to be checked. 

    :rtype: bool 

    :return: ``True`` if a SAC file. 

 

    .. rubric:: Example 

 

    >>> isSAC('/path/to/test.sac')  #doctest: +SKIP 

    """ 

    try: 

        f = open(filename, 'rb') 

        # 70 header floats, 9 position in header integers 

        f.seek(4 * 70 + 4 * 9) 

        data = f.read(4) 

        f.close() 

        npts = struct.unpack('<i', data)[0] 

    except: 

        return False 

    # check file size 

    st = os.stat(filename) 

    sizecheck = st.st_size - (632 + 4 * npts) 

    if sizecheck != 0: 

        # check if file is big-endian 

        npts = struct.unpack('>i', data)[0] 

        sizecheck = st.st_size - (632 + 4 * npts) 

        if sizecheck != 0: 

            # File-size and theoretical size inconsistent! 

            return False 

    return True 

 

 

def isSACXY(filename): 

    """ 

    Checks whether a file is alphanumeric SAC file or not. 

 

    :type filename: string 

    :param filename: Alphanumeric SAC file to be checked. 

    :rtype: bool 

    :return: ``True`` if a alphanumeric SAC file. 

 

    .. rubric:: Example 

 

    >>> isSACXY('/path/to/testxy.sac')  #doctest: +SKIP 

    """ 

    ### First find out if it is a text or a binary file. This should 

    ### always be true if a file is a text-file and only true for a 

    ### binary file in rare occasions (Recipe 173220 found on 

    ### http://code.activestate.com/ 

    if not _isText(filename, blocksize=512): 

        return False 

    try: 

        f = open(filename) 

        hdcards = [] 

        # read in the header cards 

        for _i in xrange(30): 

            hdcards.append(f.readline()) 

        npts = int(hdcards[15].split()[-1]) 

        # read in the seismogram 

        seis = f.read(-1).split() 

    except: 

        return False 

    # check that npts header value and seismogram length are consistent 

    if npts != len(seis): 

        return False 

    return True 

 

 

def readSACXY(filename, headonly=False, debug_headers=False, 

              **kwargs):  # @UnusedVariable 

    """ 

    Reads an alphanumeric SAC file and returns an ObsPy Stream object. 

 

    .. warning:: 

        This function should NOT be called directly, it registers via the 

        ObsPy :func:`~obspy.core.stream.read` function, call this instead. 

 

    :type filename: str 

    :param filename: Alphanumeric SAC file to be read. 

    :type headonly: bool, optional 

    :param headonly: If set to True, read only the head. This is most useful 

        for scanning available data in huge (temporary) data sets. 

    :type debug_headers: bool, optional 

    :param debug_headers: Extracts also the SAC headers ``'nzyear', 'nzjday', 

        'nzhour', 'nzmin', 'nzsec', 'nzmsec', 'delta', 'scale', 'npts', 

        'knetwk', 'kstnm', 'kcmpnm'`` which are usually directly mapped to the 

        :class:`~obspy.core.stream.Stream` object if set to ``True``. Those 

        values are not synchronized with the Stream object itself and won't 

        be used during writing of a SAC file! Defaults to ``False``. 

    :rtype: :class:`~obspy.core.stream.Stream` 

    :return: A ObsPy Stream object. 

 

    .. rubric:: Example 

 

    >>> from obspy import read # doctest: +SKIP 

    >>> st = read("/path/to/testxy.sac") # doctest: +SKIP 

    """ 

    t = SacIO(debug_headers=debug_headers) 

    if headonly: 

        t.ReadSacXYHeader(filename) 

    else: 

        t.ReadSacXY(filename) 

    # assign all header entries to a new dictionary compatible with ObsPy 

    header = t.get_obspy_header() 

 

    if headonly: 

        tr = Trace(header=header) 

    else: 

        tr = Trace(header=header, data=t.seis) 

    return Stream([tr]) 

 

 

def writeSACXY(stream, filename, **kwargs):  # @UnusedVariable 

    """ 

    Writes a alphanumeric SAC file. 

 

    .. warning:: 

        This function should NOT be called directly, it registers via the 

        the :meth:`~obspy.core.stream.Stream.write` method of an 

        ObsPy :class:`~obspy.core.stream.Stream` object, call this instead. 

 

    :type stream: :class:`~obspy.core.stream.Stream` 

    :param stream: The ObsPy Stream object to write. 

    :type filename: str 

    :param filename: Name of file to write. 

 

    .. rubric:: Example 

 

    >>> from obspy import read 

    >>> st = read() 

    >>> st.write("testxy.sac", format="SACXY")  #doctest: +SKIP 

    """ 

    # Translate the common (renamed) entries 

    base, ext = os.path.splitext(filename) 

    for i, trace in enumerate(stream): 

        t = SacIO(trace) 

        if len(stream) != 1: 

            filename = "%s%02d%s" % (base, i + 1, ext) 

        t.WriteSacXY(filename) 

    return 

 

 

def readSAC(filename, headonly=False, debug_headers=False, 

            **kwargs):  # @UnusedVariable 

    """ 

    Reads an SAC file and returns an ObsPy Stream object. 

 

    .. warning:: 

        This function should NOT be called directly, it registers via the 

        ObsPy :func:`~obspy.core.stream.read` function, call this instead. 

 

    :type filename: str 

    :param filename: SAC file to be read. 

    :type headonly: bool, optional 

    :param headonly: If set to True, read only the head. This is most useful 

        for scanning available data in huge (temporary) data sets. 

    :type debug_headers: bool, optional 

    :param debug_headers: Extracts also the SAC headers ``'nzyear', 'nzjday', 

        'nzhour', 'nzmin', 'nzsec', 'nzmsec', 'delta', 'scale', 'npts', 

        'knetwk', 'kstnm', 'kcmpnm'`` which are usually directly mapped to the 

        :class:`~obspy.core.stream.Stream` object if set to ``True``. Those 

        values are not synchronized with the Stream object itself and won't 

        be used during writing of a SAC file! Defaults to ``False``. 

    :rtype: :class:`~obspy.core.stream.Stream` 

    :return: A ObsPy Stream object. 

 

    .. rubric:: Example 

 

    >>> from obspy import read # doctest: +SKIP 

    >>> st = read("/path/to/test.sac") # doctest: +SKIP 

    """ 

    # read SAC file 

    t = SacIO(debug_headers=debug_headers) 

    if headonly: 

        t.ReadSacHeader(filename) 

    else: 

        t.ReadSacFile(filename) 

    # assign all header entries to a new dictionary compatible with an ObsPy 

    header = t.get_obspy_header() 

 

    if headonly: 

        tr = Trace(header=header) 

    else: 

        tr = Trace(header=header, data=t.seis) 

    return Stream([tr]) 

 

 

def writeSAC(stream, filename, **kwargs):  # @UnusedVariable 

    """ 

    Writes a SAC file. 

 

    .. warning:: 

        This function should NOT be called directly, it registers via the 

        the :meth:`~obspy.core.stream.Stream.write` method of an 

        ObsPy :class:`~obspy.core.stream.Stream` object, call this instead. 

 

    :type stream: :class:`~obspy.core.stream.Stream` 

    :param stream: The ObsPy Stream object to write. 

    :type filename: str 

    :param filename: Name of file to write. 

 

    .. rubric:: Example 

 

    >>> from obspy import read 

    >>> st = read() 

    >>> st.write("test.sac", format="SAC")  #doctest: +SKIP 

    """ 

    # Translate the common (renamed) entries 

    base, ext = os.path.splitext(filename) 

    for i, trace in enumerate(stream): 

        t = SacIO(trace) 

        if len(stream) != 1: 

            filename = "%s%02d%s" % (base, i + 1, ext) 

        t.WriteSacBinary(filename) 

    return