Repository navigation
Conversation
…G axes Simpeg3DData converts mtpy (EDI) components, x = north, y = east, z = down, to SimPEG's x = east, y = north, z = up. Three things were wrong: - Tipper receivers used nsem.receivers.Point3DTipper, which current SimPEG (0.25) removes: constructing one raises NotImplementedError, so `survey` failed for any data carrying tipper. Use nsem.receivers.Tipper. - The tipper kept its sign. Swapping x and y only reorders the indices of the impedance, a ratio of two horizontal fields, but the tipper is H_z / H_h and H_z changes sign with z: SimPEG tzx = -mtpy t_zy and tzy = -mtpy t_zx. to_rec_array now negates t_zx and t_zy (on its copy of the dataframe). Checked against a SimPEG simulation: with a conductor to the east, SimPEG's Re(tzx) is positive, so mtpy's Re(t_zy) is negative, the real induction arrow pointing away from the conductor. - The survey's receivers used mtpy's orientation as SimPEG's: `source_z_xy` built a SimPEG "xy" receiver, which is mtpy z_yx, while to_rec_array labels z_xy's data "zyx". With all four elements the sets coincided; inverting a subset gave the wrong receivers. Orientations now come from component_map. Adds tests that need no data files: receiver types and orientations per component, the rec array's swap and sign, the untouched dataframe, and a small SimPEG simulation pinning the tipper sign. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
0.23.0 is the first release with nsem.receivers.Impedance and Tipper, which data_3d.py, data_2d.py and the 1D inversion recipe use. simpeg was unpinned, so an older install failed with an AttributeError at the first receiver. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tions It built the `<component>_model_error` frame and then returned None. The columns stay in mtpy's names: each is the standard deviation of a complex element, which the index swap and the tipper's sign change leave alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Three fixes to
mtpy/modeling/simpeg/data_3d.py(Simpeg3DData), which converts mtpy components (x = north, y = east, z = down) to SimPEG's (x = east, y = north, z = up), and one fix to pin the SimPEG minimum version:Tipper receivers use
nsem.receivers.Tipper.Point3DTipperwas removed in current SimPEG (0.25): constructing one raisesNotImplementedError: Point3DTipper has been removed, please use Tipper.As a result,Simpeg3DData.surveyfailed for any data containing tipper.Tipperis available in every SimPEG version that has theImpedancereceiver this module already uses.The tipper changes sign when converted to SimPEG axes. Swapping x and y only reorders the impedance indices, because impedance is a ratio of two horizontal fields. The tipper is H_z / H_horizontal, and H_z changes sign when z flips from down to up. The correct mapping is therefore:
tzx= −mtpyt_zytzy= −mtpyt_zxcomponent_mapalready swapped the indices but kept the sign.to_rec_arraynow negatest_zxandt_zyon its own copy of the dataframe, so the caller's dataframe is unchanged.Survey receivers use SimPEG's orientation, not mtpy's.
_sources_listiterates over mtpy component names, but eachsource_*property built a receiver with mtpy's orientation. For example,source_z_xybuilt a SimPEG"xy"receiver, which corresponds to mtpyz_yx, whileto_rec_arraylabelsz_xy's data"zyx". With all four impedance elements selected the two sets happen to coincide. With a subset (e.g.invert_z_xy=Trueand the othersFalse), the survey measured a different element from the one the data described. Orientations now come fromcomponent_map.standard_deviations()returns its dataframe. It built the<component>_model_errorframe (z_xx…t_zy) and returnedNone. The columns keep mtpy's names: each is the standard deviation of a complex element, which the index swap and tipper sign change don't affect.Pins
simpeg>=0.23.0. 0.23.0 is the first release with theImpedanceandTipperreceivers thatdata_3d.py,data_2d.pyand the 1D inversion recipe use.simpegwas unpinned inpyproject.tomlandenvironment.yml, so on older installs these modules failed with anAttributeError.Motivation and Context
Running a SimPEG 3D forward from
MTData.to_simpeg_3d()with tipper failed on SimPEG 0.25 because of (1). Working around that exposed (2): simulated tipper came out with the opposite sign to the observed EDI tipper.The sign was checked against SimPEG directly. With a conductor to the east of a station, SimPEG's Re(
tzx) is positive. That means mtpy's Re(t_zy) is negative, which is the usual convention: the real induction arrow points away from the conductor.How Has This Been Tested?
New
tests/modeling/simpeg/test_simpeg_3d_conventions.py, 11 tests that need nomtpy_datafiles:Tipperinstances; this fails withPoint3DTipperon SimPEG 0.25.to_rec_arraylabels its data with.to_rec_arrayswaps the impedance indices and negates the tipper.to_rec_arrayleaves the caller's dataframe unchanged.get_simpeg_data_object()carries the negated tipper.Simulation3DPrimarySecondarywith a conductor to the east confirms Re(t_zy) < 0 in mtpy's convention (about 7 s).Reverting each fix makes at least one of these tests fail.
pytest tests/modeling/simpeg: 18 passed, 3 skipped (the skips needmtpy_data, which I didn't have installed). Environment: Python 3.12, SimPEG 0.25.2 (minimum now pinned at 0.23.0), macOS arm64.Types of changes
Note: the tipper values
to_rec_array/get_simpeg_data_objectreturn change sign. That's the fix, but any downstream code that compensated for the old sign will need to drop its workaround.Checklist:
Not addressed here:
from_simpeg_data_objectis stillNotImplementedError.