Location: source_modelling/srf.py:615
What happens: In SrfFile.planes, the single-strike-point branch builds the along-strike offset as np.array([np.cos(strike_nztm), np.sin(strike_nztm), 0]). strike_nztm is returned by qcore.coordinates.great_circle_bearing_to_nztm_bearing in degrees, but it is passed to np.cos/np.sin without np.radians, so the value is interpreted as radians. The resulting plane corners point in an essentially arbitrary direction.
Why that is wrong: great_circle_bearing_to_nztm_bearing returns degrees — it ends in geo.oriented_bearing_wrt_normal(...), and a great-circle bearing of 45 deg comes back as 44.8266, not 0.782. Every other caller in this repo converts before use: fsp.py:124-125 does np.cos(np.radians(dip_dir)) on dip_dir = strike_nztm + 90 (fsp.py:122). Only srf.py:615 omits the conversion.
Measured angular error of the resulting strike unit vector at origin (-43.5, 172.6):
| input strike (deg) |
correct unit vec |
as-coded unit vec |
error |
| 0 |
+1.0000, -0.0048 |
-0.0125, +0.9999 |
90.99 deg |
| 20 |
+0.9409, +0.3386 |
+0.5893, +0.8079 |
34.10 deg |
| 90 |
+0.0048, +1.0000 |
-0.1883, +0.9821 |
11.13 deg |
| 200 |
-0.9409, -0.3386 |
+0.2941, -0.9558 |
87.31 deg |
| 330 |
+0.8628, -0.5055 |
-0.9736, +0.2283 |
162.83 deg |
How to reproduce: Read any SRF whose header reports nstk == 1 and ndip > 1 for a segment, then inspect SrfFile.planes for that segment: the two top corners are displaced along a bearing unrelated to stk. The unit-vector discrepancy above is reproduced standalone with:
import numpy as np
from qcore import coordinates
b = coordinates.great_circle_bearing_to_nztm_bearing(np.array([-43.5, 172.6]), 10.0, 330.0)
print(np.array([np.cos(np.radians(b)), np.sin(np.radians(b))])) # correct
print(np.array([np.cos(b), np.sin(b)])) # as coded at srf.py:615
Suggested direction: Wrap strike_nztm in np.radians at the trig call, matching the convention already used in fsp.py:124-125, and consider a regression test over an nstk == 1 SRF fixture since this branch appears to be untested.
Confidence: high
Location:
source_modelling/srf.py:615What happens: In
SrfFile.planes, the single-strike-point branch builds the along-strike offset asnp.array([np.cos(strike_nztm), np.sin(strike_nztm), 0]).strike_nztmis returned byqcore.coordinates.great_circle_bearing_to_nztm_bearingin degrees, but it is passed tonp.cos/np.sinwithoutnp.radians, so the value is interpreted as radians. The resulting plane corners point in an essentially arbitrary direction.Why that is wrong:
great_circle_bearing_to_nztm_bearingreturns degrees — it ends ingeo.oriented_bearing_wrt_normal(...), and a great-circle bearing of 45 deg comes back as44.8266, not0.782. Every other caller in this repo converts before use:fsp.py:124-125doesnp.cos(np.radians(dip_dir))ondip_dir = strike_nztm + 90(fsp.py:122). Onlysrf.py:615omits the conversion.Measured angular error of the resulting strike unit vector at origin
(-43.5, 172.6):How to reproduce: Read any SRF whose header reports
nstk == 1andndip > 1for a segment, then inspectSrfFile.planesfor that segment: the two top corners are displaced along a bearing unrelated tostk. The unit-vector discrepancy above is reproduced standalone with:Suggested direction: Wrap
strike_nztminnp.radiansat the trig call, matching the convention already used infsp.py:124-125, and consider a regression test over annstk == 1SRF fixture since this branch appears to be untested.Confidence: high