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