The big endian and little endian confilict for merging seismogram

Hello everyone,

I’ve encountered an issue while working with Obspy where reading data for different endians leads to an error being raised

Exception: Can’t merge traces with same ids but differing data types

(which >f4 for big endian, and float32, or <f4 for little endian)." While it’s relatively simple to resolve by overwriting the SAC data, I’m curious as to why the io API of the SAC format still preserves the endian status in st[0].data.

I believe it might be beneficial to enforce the endian to follow the system when reading SAC format files to prevent this error from occurring. This adjustment could streamline the process and enhance compatibility. Any insights or suggestions on this matter would be greatly appreciated.

Can you open a ticket on github, ideally with a fully self contained example? Indeed sounds like something we should handle somehow.

Hi Megies,

I must acknowledge that my post may have led to some confusion, and I sincerely apologize for any misunderstanding caused. The error arises during the merging of different types of endian data. Here’s the procedure to replicate the error:

from obspy.core import read


# make different endian sacfile
st = read()
st = st[0]
starttime = st.stats.starttime
first_part = st.copy()
first_part = first_part.trim(starttime, starttime + 5)
first_part.write("first.sac", format = "SAC", byteorder = "<")
second_part = st.copy()
second_part = second_part.trim(starttime + 5, starttime + 10)
first_part.write("second.sac", format = "SAC", byteorder = ">")

# merge them
st = read("first.sac")
st += read("second.sac")
st.merge(method = 1)

The output will be

/home/junliu/anaconda3/envs/obspy/lib/python3.11/site-packages/obspy/core/stream.py:3037: UserWarning: Incompatible traces (sampling_rate, dtype, ...) with same id detected. Doing nothing.
  warnings.warn(msg)
Traceback (most recent call last):
  File "/home/junliu/test.py", line 21, in <module>
    st.merge(method = 1)
  File "/home/junliu/anaconda3/envs/obspy/lib/python3.11/site-packages/obspy/core/stream.py", line 2037, in merge
    self._merge_checks()
  File "/home/junliu/anaconda3/envs/obspy/lib/python3.11/site-packages/obspy/core/stream.py", line 1981, in _merge_checks
    raise Exception(msg)
Exception: Can't merge traces with same ids but differing data types!

If we print the dtype and typename for two streams

print("first datatype {}, and second datatype {} ".format(st[0].data.dtype, st[1].data.dtype))
print("first typename {}, and second typename {} ".format(st[0].data.dtype.name, st[1].data.dtype.name))

The output will be

first datatype float32, and second datatype >f4
first typename float32, and second typename float32

So that is the reason why I said maybe we should enforce the endian to follow the system when reading SAC format files to prevent this error from occurring. Is there any special reason for preserving the endian status when reading the SAC format data?

Thanks for the example. I understood what the issue was, just it helps to make it quicker to look at with a minimal fully self-contained example. :grin:

@JunliuSuwen see Convert byte order to native on reading data or merging traces? · Issue #3417 · obspy/obspy · GitHub

You can work around the issue in your code by converting everything to native byteorder:

for tr in st:                                                                   
    dtype = tr.data.dtype.newbyteorder('native')                                
    tr.data = np.require(tr.data, dtype=dtype)