Skip to content

GEOPY-2799#136

Closed
domfournier wants to merge 6 commits intodevelopfrom
GEOPY-2799
Closed

GEOPY-2799#136
domfournier wants to merge 6 commits intodevelopfrom
GEOPY-2799

Conversation

@domfournier
Copy link
Copy Markdown

No description provided.

Copilot AI review requested due to automatic review settings April 13, 2026 20:20
@domfournier domfournier changed the base branch from main to develop April 13, 2026 20:20
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_dictionary usage to Survey.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.

Comment on lines 16 to 22
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copilot uses AI. Check for mistakes.
components.
"""

def __init__(
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Number of components in the model. E.g. a vector model in 3D would have 3
components.
"""
super().__init__(mesh=None, **kwargs)
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
super().__init__(mesh=None)

Copilot uses AI. Check for mistakes.
Comment on lines 369 to 370
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
if np.any(lower_bound >= upper_bound):
raise ValueError(
"A lower bound must be strictly less than the upper bound."
)

Copilot uses AI. Check for mistakes.
Comment on lines +66 to +76
shape=(
len(block),
len(cell_centers),
),
)
)

if client:
diag = client.gather(futures)
else:
diag = compute(futures)
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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)

Copilot uses AI. Check for mistakes.
Comment on lines 449 to 452
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
Tipper(rx_loc, orientation=rx_type, component="real")
)
receiver_list.append(
Tipper(rx_loc, orientation=rx_type, component="imag")

Copilot uses AI. Check for mistakes.
Comment on lines 235 to 245
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Suggested change
- python=3.12

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Suggested change
raise ValueError(msg)
if self.data is None:
raise ValueError("`data` must be set before computing the residual.")

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants