Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR modernizes SimPEG by removing long-deprecated APIs, refactoring internals (notably Survey slicing/indexing, directives, and Numba helpers), and updating packaging/docs for newer Python and documentation tooling.
Changes:
- Removes/turns into errors several deprecated arguments/properties across simulations, maps, surveys, and utils; adds stricter validation in a few places.
- Refactors indexing from
Data.index_dictionaryusage toSurvey.get_slice()/Survey.get_all_slices()across EM and PF code. - Reorganizes docs (new User Guide structure + redirects) and bumps packaging constraints (e.g., Python minimum version).
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| simpeg/potential_fields/magnetics/init.py | Adjusts exported magnetics symbols (removes SourceField re-export). |
| simpeg/potential_fields/gravity/survey.py | Refactors gravity Survey to enforce single SourceField via source_list + adds source_field property. |
| simpeg/potential_fields/gravity/receivers.py | Updates receiver docs to include and define guv. |
| simpeg/potential_fields/gravity/_numba_functions.py | Removes legacy gravity numba helpers (moved into new subpackage). |
| simpeg/potential_fields/gravity/_numba/init.py | Adds new gravity numba subpackage exports and optional choclo import. |
| simpeg/potential_fields/gravity/_numba/_2d_mesh.py | Introduces new 2D-mesh gravity numba kernels and helper operators. |
| simpeg/potential_fields/base.py | Removes ind_active argument and removes deprecated get_dist_wgt implementation. |
| simpeg/potential_fields/_numba_utils.py | Adds evaluate_six_kernels_on_cell helper and uses float initializers for numba. |
| simpeg/objective_function.py | Tracks last objective values (_last_obj_vals) for combo objective functions. |
| simpeg/maps/_property_maps.py | Adds EffectiveSusceptibilityMap; adjusts bounds validation; changes ComplexMap.deriv implementation. |
| simpeg/maps/_parametric.py | Removes deprecated active-cell args and adds consistent deriv(m, v=None) patterns. |
| simpeg/maps/_injection.py | Removes deprecated kwargs and tightens kwarg validation for injection maps. |
| simpeg/maps/_base.py | Adjusts Wires nP handling; expands TileMap docstring and changes initializer call. |
| simpeg/maps/init.py | Exposes EffectiveSusceptibilityMap. |
| simpeg/inversion.py | Adds InexactGaussNewton + UpdatePreconditioner interaction to disable BFGS init; removes debug print. |
| simpeg/inverse_problem.py | Adds init_bfgs option and switches startup messaging to logger; adjusts solver handling. |
| simpeg/flow/richards/simulation.py | Removes deprecated debug plumbing/property. |
| simpeg/electromagnetics/viscous_remanent_magnetization/simulation.py | Removes deprecated indActive handling in favour of hard error. |
| simpeg/electromagnetics/viscous_remanent_magnetization/receivers.py | Removes deprecated receiver kwargs in VRM receivers. |
| simpeg/electromagnetics/utils/em1d_utils.py | Improves docstring header for DLF spline helper. |
| simpeg/electromagnetics/utils/current_utils.py | Removes deprecated polygon line-current helper stub. |
| simpeg/electromagnetics/utils/init.py | Drops export of removed deprecated helper. |
| simpeg/electromagnetics/time_domain/simulation_1d.py | Splits Jacobian build into _getJ + getJ and ensures real-valued blocks. |
| simpeg/electromagnetics/time_domain/simulation.py | Switches Jtvec indexing to Survey.get_all_slices() and cleans shape handling. |
| simpeg/electromagnetics/static/spontaneous_potential/init.py | Turns renamed module into hard ImportError. |
| simpeg/electromagnetics/static/spectral_induced_polarization/survey.py | Removes survey_type and enforces non-null source_list. |
| simpeg/electromagnetics/static/spectral_induced_polarization/simulation_2d.py | Ensures self.model is set in getJ. |
| simpeg/electromagnetics/static/spectral_induced_polarization/simulation.py | Ensures self.model is set in getJ. |
| simpeg/electromagnetics/static/spectral_induced_polarization/run.py | Removes deprecated active-cell kwargs; adds strict unknown-kwargs handling. |
| simpeg/electromagnetics/static/resistivity/survey.py | Refactors Survey slicing + topography shifting, removes survey_type and old helpers. |
| simpeg/electromagnetics/static/resistivity/simulation_2d.py | Uses Survey.get_all_slices() and _inner_mat_mul_op; fixes model assignment timing; refactors BC assembly. |
| simpeg/electromagnetics/static/resistivity/simulation.py | Uses Survey.get_all_slices() and _inner_mat_mul_op; adjusts J/Jtvec indexing. |
| simpeg/electromagnetics/static/induced_polarization/simulation.py | Removes Data construction for scaling and uses slice-based indexing. |
| simpeg/electromagnetics/natural_source/utils/test_utils.py | Updates tests to new receiver classes (Impedance, Tipper) and slice-based data access. |
| simpeg/electromagnetics/natural_source/utils/solutions_1d.py | Changes sign convention in RHS assembly. |
| simpeg/electromagnetics/natural_source/utils/plot_utils.py | Uses survey slices for uncertainty arrays. |
| simpeg/electromagnetics/natural_source/utils/data_viewer.py | Updates rx-type checks to new receiver classes. |
| simpeg/electromagnetics/natural_source/utils/data_utils.py | Uses slice-based access and new receiver classes when extracting/resampling. |
| simpeg/electromagnetics/natural_source/survey.py | Uses Survey.get_all_slices() to build record arrays. |
| simpeg/electromagnetics/natural_source/simulation_1d.py | Uses arctan2 for stable phase computation. |
| simpeg/electromagnetics/natural_source/simulation.py | Adds explicit getJ NotImplementedError with clearer messaging. |
| simpeg/electromagnetics/natural_source/init.py | Removes old receiver names from docs listing. |
| simpeg/electromagnetics/frequency_domain/sources.py | Refactors primary fields for dipoles and source terms for EB/HJ formulations; removes deprecated property bits. |
| simpeg/electromagnetics/frequency_domain/simulation_1d.py | Splits _getJ + getJ; ensures real-valued blocks; adds component guard. |
| simpeg/electromagnetics/frequency_domain/simulation.py | Removes Data wrapper in Jvec/Jtvec/getJ and uses survey slice indexing. |
| simpeg/electromagnetics/frequency_domain/fields.py | Caches face divergence to avoid repeated mesh lookups. |
| simpeg/electromagnetics/base_1d.py | Routes Jvec/Jtvec/JtJdiag through _getJ and tweaks Hankel coefficient indexing. |
| simpeg/directives/sim_directives.py | Converts legacy submodule into deprecation wrapper importing new implementation. |
| simpeg/directives/_vector_models.py | Adjusts MVI mode switching and multiplier scaling; suppresses warnings during directive-list replacement. |
| simpeg/directives/_sim_directives.py | Introduces new home for joint inversion directives/printers and paired-beta helpers. |
| simpeg/directives/_save_geoh5.py | Updates imports and adds timestamped log filenames; minor robustness tweaks. |
| simpeg/directives/_regularization.py | Fixes cooling-schedule logic and adds deprecated Update_IRLS shim. |
| simpeg/directives/init.py | Switches imports to underscored modules and re-exports deprecated Update_IRLS. |
| simpeg/data_misfit.py | Validates dpred outputs and forces L2 misfit return type to float. |
| simpeg/data.py | Removes index_dictionary and switches Data src/rx access to Survey slicing. |
| simpeg/dask/potential_fields/magnetics/simulation_pde.py | Adds Dask-based getJtJdiag for magnetics PDE simulation via monkeypatch. |
| simpeg/dask/potential_fields/base.py | Removes reliance on deprecated survey.components. |
| simpeg/dask/electromagnetics/time_domain/simulation_1d.py | Updates Dask sensitivity build to use _getJ. |
| simpeg/dask/electromagnetics/frequency_domain/simulation_1d.py | Adds Dask wrapper for FDEM 1D layered simulation Jacobian blocks. |
| simpeg/dask/init.py | Registers new Dask modules. |
| simpeg/base/pde_simulation.py | Renames/export _inner_mat_mul_op; logs default solver choice; warns on slow solver classes. |
| simpeg/init.py | Updates docs listing for maps (ordering/coverage). |
| recipe.yaml | Updates python_min and geoh5py constraints. |
| pyproject.toml | Raises Python requirement, tweaks build requirements, adds pytest warning strictness, adds docs deps. |
| examples/_archived/plot_inv_mag_linear.py | Updates optimization kwargs to new names. |
| examples/_archived/plot_inv_grav_linear.py | Updates optimization kwargs to new names. |
| examples/20-published/plot_laguna_del_maule_inversion.py | Updates optimization kwargs to new names. |
| examples/20-published/plot_heagyetal2017_cyl_inversions.py | Updates optimization kwargs to new names. |
| examples/10-pgi/plot_inv_1_PGI_Linear_1D_joint_WithRelationships.py | Updates optimization kwargs to new names. |
| examples/10-pgi/plot_inv_0_PGI_Linear_1D.py | Updates optimization kwargs to new names (note: changes CG tolerances). |
| examples/09-flow/plot_inv_flow_richards_1D.py | Removes deprecated debug kwarg + updates optimization kwargs. |
| examples/09-flow/plot_fwd_flow_richards_1D.py | Removes deprecated debug kwarg. |
| examples/08-vrm/plot_inv_vrm_eq.py | Updates optimization kwargs to new names. |
| examples/07-nsem/plot_fwd_nsem_MTTipper3D.py | Updates to new NSEM receivers (Impedance, Tipper). |
| examples/05-fdem/plot_inv_fdem_loop_loop_2Dinversion.py | Updates optimization kwargs to new names. |
| examples/03-magnetics/plot_inv_mag_nonLinear_Amplitude.py | Fixes get_indices_block call and updates optimization kwargs. |
| examples/03-magnetics/plot_inv_mag_MVI_VectorAmplitude.py | Fixes get_indices_block call and updates optimization kwargs. |
| examples/03-magnetics/plot_inv_mag_MVI_Sparse_TreeMesh.py | Fixes get_indices_block call, typo, and updates optimization kwargs. |
| examples/02-gravity/plot_inv_grav_tiled.py | Fixes get_indices_block call and updates optimization kwargs. |
| examples/01-maps/plot_sumMap.py | Updates optimization kwargs to new names. |
| environment.yml | Updates dependency versions and docs tooling list. |
| docs/old-docs-files.txt | Adds list of legacy generated HTML files for redirects. |
| docs/index.rst | Replaces README include with a custom homepage and links. |
| docs/content/user_guide.rst | Removes old user guide entrypoint (replaced by new structure). |
| docs/content/user-guide/index.rst | Adds new User Guide index with structured toctrees. |
| docs/content/user-guide/how-to-guide/move-mesh-to-survey.rst | Adds new how-to guide page. |
| docs/content/user-guide/how-to-guide/choosing-solvers.rst | Adds solver selection guide. |
| docs/content/user-guide/getting-started/version-compatibility.rst | Adds Python/Numpy compatibility policy page. |
| docs/content/user-guide/getting-started/installing.rst | Renames anchor and updates heading style. |
| docs/content/user-guide/getting-started/contributing/working-with-github.rst | Fixes image URLs and relative paths. |
| docs/content/user-guide/getting-started/citing.rst | Adds include for CITATION.rst. |
| docs/content/user-guide/getting-started/big_picture.rst | Fixes image paths and license include. |
| docs/content/user-guide/getting-started/about-simpeg.rst | Adds “What’s SimPEG?” page with embedded video. |
| docs/content/release/index.rst | Adds anchors and includes 0.24.0/0.25.0 notes entries. |
| docs/content/release/0.24.0-notes.rst | Adds 0.24.0 release notes page. |
| docs/content/getting_started/index.rst | Removes old getting-started index (merged into User Guide). |
| docs/content/api/simpeg.optimization.rst | Adds optimization module to API docs. |
| docs/content/api/index.rst | Adds Optimizers section and minor layout cleanup. |
| docs/conf.py | Adds sphinx-design + sphinx-reredirects; rewires gallery dirs; adds redirects builder. |
| docs/_static/versions.json | Updates “latest” docs version and adds 0.24.0 entry. |
| docs/Makefile | Updates clean targets for relocated gallery output dirs. |
| README.rst | Updates meeting time statement. |
| CITATION.rst | Reworks citation headings and adds EM citation entry. |
| .github/workflows/python_deploy_dev.yml | Updates deploy Python version to 3.12. |
| .github/ISSUE_TEMPLATE/bug-report.yml | Normalizes bug label and enables shell rendering for report output. |
| .ci/environment_test.yml | Updates dependencies and build tool package name. |
| .ci/azure/test.yml | Updates test python version list. |
| .ci/azure/setup_env.sh | Fixes TF_BUILD parsing and adjusts Azure conda channel config. |
| .ci/azure/pypi.yml | Updates PyPI build Python version. |
| .ci/azure/docs.yml | Updates docs build Python version. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
BaseSurvey / the source_list setter introduced below expects a (single-element) list of SourceField, but __init__ passes a SourceField instance directly (source_list=source_field). This will fail unless validate_list_of_types explicitly wraps singletons. Pass [source_field] into super().__init__ (and keep enforcing min_n=1, max_n=1 in the setter).
| components. | ||
| """ | ||
|
|
||
| def __init__( |
There was a problem hiding this comment.
kwargs is used in the super().__init__(..., **kwargs) call, but it is not shown as a parameter in TileMap.__init__ in this hunk. If kwargs is not part of the function signature, this will raise NameError at runtime. Either add **kwargs to the __init__ signature or remove **kwargs from the super() call.
| Number of components in the model. E.g. a vector model in 3D would have 3 | ||
| components. | ||
| """ | ||
| super().__init__(mesh=None, **kwargs) |
There was a problem hiding this comment.
kwargs is used in the super().__init__(..., **kwargs) call, but it is not shown as a parameter in TileMap.__init__ in this hunk. If kwargs is not part of the function signature, this will raise NameError at runtime. Either add **kwargs to the __init__ signature or remove **kwargs from the super() call.
| super().__init__(mesh=None) |
There was a problem hiding this comment.
This change no longer rejects lower_bound > upper_bound, which is an invalid bounds configuration and was previously guarded (>=). Restore the strict check (reject both equality and inversion), or add a separate explicit check for lower_bound > upper_bound to preserve correctness.
| if np.any(lower_bound >= upper_bound): | |
| raise ValueError( | |
| "A lower bound must be strictly less than the upper bound." | |
| ) |
| shape=( | ||
| len(block), | ||
| len(cell_centers), | ||
| ), | ||
| ) | ||
| ) | ||
|
|
||
| if client: | ||
| diag = client.gather(futures) | ||
| else: | ||
| diag = compute(futures) |
There was a problem hiding this comment.
The delayed distance_weights(...) returns a 1D array of length len(cell_centers), but from_delayed declares a 2D shape (len(block), len(cell_centers)). Also, dask.compute(futures) returns a tuple (with one element when passing a single list), so np.vstack(diag) will not behave as intended. Use a 1D declared shape and ensure you compute/gather a list of arrays (e.g., compute(*futures) or index the tuple result) before stacking.
| shape=( | |
| len(block), | |
| len(cell_centers), | |
| ), | |
| ) | |
| ) | |
| if client: | |
| diag = client.gather(futures) | |
| else: | |
| diag = compute(futures) | |
| shape=(len(cell_centers),), | |
| ) | |
| ) | |
| if client: | |
| diag = client.gather(futures) | |
| else: | |
| diag = compute(*futures) |
There was a problem hiding this comment.
zx/zy channels are tipper components and should use the Tipper receiver class (as done elsewhere in this file and in the viewer logic). Using Impedance here will produce inconsistent receiver typing and likely break downstream logic that expects Tipper for zx/zy.
| Tipper(rx_loc, orientation=rx_type, component="real") | |
| ) | |
| receiver_list.append( | |
| Tipper(rx_loc, orientation=rx_type, component="imag") |
There was a problem hiding this comment.
The log message has mismatched quoting/backticks ('is_symmetric=True\``) and claims is_symmetric=Trueis set even in thesim is not Nonebranch wheresolver_opts = sim.solver_opts(and may not include that key). Make the message accurate and fix the quoting; if symmetry is required, explicitly enforce/mergeis_symmetric=Trueintosolver_opts` before calling the solver.
There was a problem hiding this comment.
Packaging metadata was updated to require Python >=3.12 (pyproject.toml and recipe.yaml), but this environment file still pins python=3.11. This makes it easy for contributors/CI to create an environment that can’t install the package as declared. Align the dev/test environment Python version with the declared minimum (or lower the declared minimum if 3.11 is still intended to be supported).
| - python=3.12 |
There was a problem hiding this comment.
Removing SourceField from the package __init__ changes the public import surface (from simpeg.potential_fields.magnetics import SourceField). If this is intentional, consider keeping a deprecated re-export (with a warning) until the next major/minor deprecation window, or document the breaking change in release notes to avoid unexpected downstream import failures.
There was a problem hiding this comment.
The previous explicit guard for self.data is None was removed. If data is unset, this will now raise an AttributeError at self.data.dobs, which is less actionable than the prior message. Reintroduce a clear, explicit error when self.data is missing (while keeping the new NaN/Inf validation).
| raise ValueError(msg) | |
| if self.data is None: | |
| raise ValueError("`data` must be set before computing the residual.") |
No description provided.