Fail to change encoding from sac to mseed

Hello,

I got sac file and want to convert in mseed file with different encoding by using obspy stream. But I failed. The dtype of sac file is float32 and I want to convert to STEIM2 in mseed file, and I am using python 2.6.

Any idea?

Thanks in advance,

Xiao

The following is the output when I try to convert.

Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
[GCC 4.4.3] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.

from obspy import read
st=read(‘OBSB19-1.sac’)
st.write(‘out.mseed’, format=‘MSEED’, encoding=‘STEIM2’)
Traceback (most recent call last):
File “”, line 1, in
File “/usr/lib/pymodules/python2.6/obspy/core/stream.py”, line 1279, in write
writeFormat(self, filename, **kwargs)
File “/usr/lib/pymodules/python2.6/obspy/mseed/core.py”, line 536, in writeMSEED
raise Exception(msg)
Exception:
Wrong dtype for Stream[0].data for encoding STEIM2.
Please change the dtype of your data or use an appropriate
encoding. See the obspy.mseed documentation for more
information.

st[0].data
array([-160786., -135037., -160595., …, -178665., -122117., -66691.], dtype=float32)

Hi Xiao,

The type that miniSEED uses by default and for compression is integers, so you need to convert your float32 array type before you try to encode it:

import numpy
st[0].data = numpy.array(st[0].data, dtype=numpy.int32)

I believe there is also an easy way to do this in obspy.core.read. Try this:

st = read(‘OBSB19-1.sac’, dtype=‘int32’)
st.write(‘out.mseed’, format=‘MSEED’, encoding=‘STEIM2’)

You do need to be careful about altering data in conversions like this, I am not very familiar with how SAC formats things internally, it looks like from your example, there are no decimal places in your data, so this solution should work for you.

-Mark

Mark is essentially right. Although, miniSEED (and obspy.mseed) in
principle *can* handle float (see
http://docs.obspy.org/packages/obspy.mseed.html#writing) but STEIM2 is a
compression only for integer values. However, from what I know many
miniSEED readers do not support float MiniSEED (and filesize will be
quite large).
When using STEIM2 beware of decimals being cut off!

best,
Tobias

Hi!

You also need to manually convert the data to integers. ObsPy does not automatically perform operations that could result in data loss. You should also check the error you make by converting to integers!

Short untested example:

import obspy
import numpy as np
tr = obspy.read()[0]
# Estimate max absolute error. Overflows would in theory also be possible...
print "Max Error:", (tr. data % 1.0).max()
# Convert data to integers. STEIM2 only supports 32bit integers.
tr.data = np.require(tr.data, dtype="int32")
tr.write('blub.mseed', format='mseed', encoding='STEIM2')

In any case I would advise to just use the MiniSEED float encoding except any of the caveats Tobias mentioned apply in your case. Due to being an integer format, STEIM2 is really only useful for data straight from the digitizer.

Cheers!

Lion

Thanks Lion, Mark and Tobias,

All of your codes are working to me.

Thanks again,

Xiao