obspy / obspy

ObsPy: A Python Toolbox for seismology/seismological observatories.

Home Page:https://www.obspy.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

real_error and imag_error of RESP file format are parsed in unexpected behavior

lowbontimp opened this issue · comments

Avoid duplicates

  • I searched existing issues

Bug Summary

real_error and imag_error in the RESP file format are parsed, violating the FDSN Station XML schema.

This is the simple code to find problem.

from obspy.io.xseed.core import _read_resp

a = _read_resp('./RESP')
#./RESP
#...
# #              Complex poles:
# #              i  real          imag          real_error    imag_error
#B053F15-18     0  -5.00000E+01  -5.00000E+01  +1.00000E+00  +2.00000E+00
#...

b = a[0][0][0]

print(f'Poles0= {b.response.get_paz().poles[0]}')
print(f'Poles0_upper_uncertainty= {b.response.get_paz().poles[0].upper_uncertainty} (this should be 1+2j)')
print(f'Poles0_lower_uncertainty= {b.response.get_paz().poles[0].lower_uncertainty} (this should be 1+2j)')

The code prints below.

Poles0= (-50-50j)
Poles0_upper_uncertainty= (-49-48j) (this should be 1+2j)
Poles0_lower_uncertainty= (-51-52j) (this should be 1+2j)

upper_uncertainty is parsed as poles[0]+(real_error+imag_error x j). Similarly, lower_uncertainty is parsed as poles[0]-(real_error+imag_error x j). This behavior does not follow the FDSN Station XML schema.

upper_uncertainty should be (real_error+imag_error x j). lower_uncertainty should be (real_error+imag_error x j)

Following part might need modification (obspy/obspy/io/xseed/parser.py).

                if hasattr(b53, "real_zero"):
                    for r, i, r_err, i_err in zip(
                            _list(b53.real_zero), _list(b53.imaginary_zero),
                            _list(b53.real_zero_error),
                            _list(b53.imaginary_zero_error)):
                        z = ComplexWithUncertainties(r, i)
                        err = ComplexWithUncertainties(r_err, i_err)
                        z.lower_uncertainty = z - err #here (z - err -> err)
                        z.upper_uncertainty = z + err #here (z - err -> err)
                        zeros.append(z)
                poles = []
                # Might somehow also not have zeros.
                if hasattr(b53, "real_pole"):
                    for r, i, r_err, i_err in zip(
                            _list(b53.real_pole), _list(b53.imaginary_pole),
                            _list(b53.real_pole_error),
                            _list(b53.imaginary_pole_error)):
                        p = ComplexWithUncertainties(r, i)
                        err = ComplexWithUncertainties(r_err, i_err)
                        p.lower_uncertainty = p - err #here (z - err -> err)
                        p.upper_uncertainty = p + err #here (z - err -> err)
                        poles.append(p)

Although errors of zeros and poles are not used in normal situations, I report it here.

Code to Reproduce

from obspy.io.xseed.core import _read_resp

a = _read_resp('./RESP')

#./RESP
#...
# #              Complex poles:
# #              i  real          imag          real_error    imag_error
#B053F15-18     0  -5.00000E+01  -5.00000E+01  +1.00000E+00  +2.00000E+00
#...

b = a[0][0][0]

print(f'Poles0= {b.response.get_paz().poles[0]}')
print(f'Poles0_upper_uncertainty= {b.response.get_paz().poles[0].upper_uncertainty} (this should be 1+2j)')
print(f'Poles0_lower_uncertainty= {b.response.get_paz().poles[0].lower_uncertainty} (this should be 1+2j)')

Error Traceback

No error

ObsPy Version?

1.4.0

Operating System?

Rocky-Linux-9 (5.14.0-284.30.1.el9_2.x86_64)

Python Version?

Python 3.9.18

Installation Method?

pip

@lowbontimp do you happen to have a real world file with errors specified? Some open station with metadata available via FDSN would be best to compare to other formats

@megies here is an example: link . We stopped publishing these as we figured no one was using them.