Skip to content

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

@lowbontimp

Description

@lowbontimp

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions