From 837546f46e624e4c05ef68fed73965b8074a1231 Mon Sep 17 00:00:00 2001 From: domfournier Date: Thu, 19 Mar 2026 08:42:22 -0700 Subject: [PATCH 01/18] Remove forward_only from uijsons --- .../uijson/apparent_conductivity_forward.ui.json | 1 - .../uijson/apparent_conductivity_inversion.ui.json | 1 - simpeg_drivers-assets/uijson/direct_current_2d_forward.ui.json | 1 - simpeg_drivers-assets/uijson/direct_current_2d_inversion.ui.json | 1 - simpeg_drivers-assets/uijson/direct_current_3d_forward.ui.json | 1 - simpeg_drivers-assets/uijson/direct_current_3d_inversion.ui.json | 1 - simpeg_drivers-assets/uijson/fdem1d_forward.ui.json | 1 - simpeg_drivers-assets/uijson/fdem1d_inversion.ui.json | 1 - simpeg_drivers-assets/uijson/fdem_forward.ui.json | 1 - simpeg_drivers-assets/uijson/fdem_inversion.ui.json | 1 - simpeg_drivers-assets/uijson/gravity_forward.ui.json | 1 - simpeg_drivers-assets/uijson/gravity_inversion.ui.json | 1 - .../uijson/induced_polarization_2d_forward.ui.json | 1 - .../uijson/induced_polarization_2d_inversion.ui.json | 1 - .../uijson/induced_polarization_3d_forward.ui.json | 1 - .../uijson/induced_polarization_3d_inversion.ui.json | 1 - .../uijson/joint_cross_gradient_inversion.ui.json | 1 - .../uijson/joint_petrophysics_inversion.ui.json | 1 - simpeg_drivers-assets/uijson/joint_surveys_inversion.ui.json | 1 - simpeg_drivers-assets/uijson/magnetic_scalar_forward.ui.json | 1 - simpeg_drivers-assets/uijson/magnetic_scalar_inversion.ui.json | 1 - simpeg_drivers-assets/uijson/magnetic_vector_forward.ui.json | 1 - simpeg_drivers-assets/uijson/magnetic_vector_inversion.ui.json | 1 - simpeg_drivers-assets/uijson/magnetotellurics_forward.ui.json | 1 - simpeg_drivers-assets/uijson/magnetotellurics_inversion.ui.json | 1 - simpeg_drivers-assets/uijson/plate_match.ui.json | 1 - simpeg_drivers-assets/uijson/plate_simulation.ui.json | 1 - simpeg_drivers-assets/uijson/plate_sweep.ui.json | 1 - simpeg_drivers-assets/uijson/tdem1d_forward.ui.json | 1 - simpeg_drivers-assets/uijson/tdem1d_inversion.ui.json | 1 - simpeg_drivers-assets/uijson/tdem_forward.ui.json | 1 - simpeg_drivers-assets/uijson/tdem_inversion.ui.json | 1 - simpeg_drivers-assets/uijson/tipper_forward.ui.json | 1 - simpeg_drivers-assets/uijson/tipper_inversion.ui.json | 1 - 34 files changed, 34 deletions(-) diff --git a/simpeg_drivers-assets/uijson/apparent_conductivity_forward.ui.json b/simpeg_drivers-assets/uijson/apparent_conductivity_forward.ui.json index 684e9374..de090d93 100644 --- a/simpeg_drivers-assets/uijson/apparent_conductivity_forward.ui.json +++ b/simpeg_drivers-assets/uijson/apparent_conductivity_forward.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "apparent conductivity", "physical_property": "conductivity", - "forward_only": true, "data_object": { "main": true, "group": "Survey", diff --git a/simpeg_drivers-assets/uijson/apparent_conductivity_inversion.ui.json b/simpeg_drivers-assets/uijson/apparent_conductivity_inversion.ui.json index b877b1ad..c0429aa6 100644 --- a/simpeg_drivers-assets/uijson/apparent_conductivity_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/apparent_conductivity_inversion.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "apparent conductivity", "physical_property": "conductivity", - "forward_only": false, "data_object": { "main": true, "group": "Data", diff --git a/simpeg_drivers-assets/uijson/direct_current_2d_forward.ui.json b/simpeg_drivers-assets/uijson/direct_current_2d_forward.ui.json index 8494c3e1..0323c725 100644 --- a/simpeg_drivers-assets/uijson/direct_current_2d_forward.ui.json +++ b/simpeg_drivers-assets/uijson/direct_current_2d_forward.ui.json @@ -8,7 +8,6 @@ "geoh5": "", "monitoring_directory": "", "inversion_type": "direct current 2d", - "forward_only": true, "physical_property": "conductivity", "data_object": { "main": true, diff --git a/simpeg_drivers-assets/uijson/direct_current_2d_inversion.ui.json b/simpeg_drivers-assets/uijson/direct_current_2d_inversion.ui.json index 24d9e9d3..a14e03aa 100644 --- a/simpeg_drivers-assets/uijson/direct_current_2d_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/direct_current_2d_inversion.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "direct current 2d", "physical_property": "conductivity", - "forward_only": false, "data_object": { "main": true, "group": "Data", diff --git a/simpeg_drivers-assets/uijson/direct_current_3d_forward.ui.json b/simpeg_drivers-assets/uijson/direct_current_3d_forward.ui.json index 65d25644..7610b731 100644 --- a/simpeg_drivers-assets/uijson/direct_current_3d_forward.ui.json +++ b/simpeg_drivers-assets/uijson/direct_current_3d_forward.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "direct current 3d", "physical_property": "conductivity", - "forward_only": true, "data_object": { "main": true, "group": "Survey", diff --git a/simpeg_drivers-assets/uijson/direct_current_3d_inversion.ui.json b/simpeg_drivers-assets/uijson/direct_current_3d_inversion.ui.json index d535221f..d2312fde 100644 --- a/simpeg_drivers-assets/uijson/direct_current_3d_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/direct_current_3d_inversion.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "direct current 3d", "physical_property": "conductivity", - "forward_only": false, "data_object": { "main": true, "group": "Data", diff --git a/simpeg_drivers-assets/uijson/fdem1d_forward.ui.json b/simpeg_drivers-assets/uijson/fdem1d_forward.ui.json index 549d3ed8..aa9da759 100644 --- a/simpeg_drivers-assets/uijson/fdem1d_forward.ui.json +++ b/simpeg_drivers-assets/uijson/fdem1d_forward.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "fdem 1d", "physical_property": "conductivity", - "forward_only": true, "data_object": { "main": true, "group": "Survey", diff --git a/simpeg_drivers-assets/uijson/fdem1d_inversion.ui.json b/simpeg_drivers-assets/uijson/fdem1d_inversion.ui.json index 941f14da..72f57026 100644 --- a/simpeg_drivers-assets/uijson/fdem1d_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/fdem1d_inversion.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "fdem 1d", "physical_property": "conductivity", - "forward_only": false, "data_object": { "main": true, "group": "Data", diff --git a/simpeg_drivers-assets/uijson/fdem_forward.ui.json b/simpeg_drivers-assets/uijson/fdem_forward.ui.json index 8917d993..41cca911 100644 --- a/simpeg_drivers-assets/uijson/fdem_forward.ui.json +++ b/simpeg_drivers-assets/uijson/fdem_forward.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "fdem", "physical_property": "conductivity", - "forward_only": true, "data_object": { "main": true, "group": "Survey", diff --git a/simpeg_drivers-assets/uijson/fdem_inversion.ui.json b/simpeg_drivers-assets/uijson/fdem_inversion.ui.json index 109c7c15..8690f3d6 100644 --- a/simpeg_drivers-assets/uijson/fdem_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/fdem_inversion.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "fdem", "physical_property": "conductivity", - "forward_only": false, "data_object": { "main": true, "group": "Data", diff --git a/simpeg_drivers-assets/uijson/gravity_forward.ui.json b/simpeg_drivers-assets/uijson/gravity_forward.ui.json index 24bb730d..eea29d48 100644 --- a/simpeg_drivers-assets/uijson/gravity_forward.ui.json +++ b/simpeg_drivers-assets/uijson/gravity_forward.ui.json @@ -8,7 +8,6 @@ "geoh5": "", "monitoring_directory": "", "inversion_type": "gravity", - "forward_only": true, "physical_property": "density", "data_object": { "main": true, diff --git a/simpeg_drivers-assets/uijson/gravity_inversion.ui.json b/simpeg_drivers-assets/uijson/gravity_inversion.ui.json index 5a8ad198..c7e855c9 100644 --- a/simpeg_drivers-assets/uijson/gravity_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/gravity_inversion.ui.json @@ -8,7 +8,6 @@ "geoh5": "", "monitoring_directory": "", "inversion_type": "gravity", - "forward_only": false, "physical_property": "density", "data_object": { "main": true, diff --git a/simpeg_drivers-assets/uijson/induced_polarization_2d_forward.ui.json b/simpeg_drivers-assets/uijson/induced_polarization_2d_forward.ui.json index 057ce1ad..7a0c2bc1 100644 --- a/simpeg_drivers-assets/uijson/induced_polarization_2d_forward.ui.json +++ b/simpeg_drivers-assets/uijson/induced_polarization_2d_forward.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "induced polarization 2d", "physical_property": "chargeability", - "forward_only": true, "data_object": { "main": true, "group": "Survey", diff --git a/simpeg_drivers-assets/uijson/induced_polarization_2d_inversion.ui.json b/simpeg_drivers-assets/uijson/induced_polarization_2d_inversion.ui.json index f4273b1d..60dcd655 100644 --- a/simpeg_drivers-assets/uijson/induced_polarization_2d_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/induced_polarization_2d_inversion.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "induced polarization 2d", "physical_property": "chargeability", - "forward_only": false, "data_object": { "main": true, "group": "Data", diff --git a/simpeg_drivers-assets/uijson/induced_polarization_3d_forward.ui.json b/simpeg_drivers-assets/uijson/induced_polarization_3d_forward.ui.json index 879d62de..785a7469 100644 --- a/simpeg_drivers-assets/uijson/induced_polarization_3d_forward.ui.json +++ b/simpeg_drivers-assets/uijson/induced_polarization_3d_forward.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "induced polarization 3d", "physical_property": "chargeability", - "forward_only": true, "data_object": { "main": true, "group": "Survey", diff --git a/simpeg_drivers-assets/uijson/induced_polarization_3d_inversion.ui.json b/simpeg_drivers-assets/uijson/induced_polarization_3d_inversion.ui.json index 12eb9e54..b6eaa37e 100644 --- a/simpeg_drivers-assets/uijson/induced_polarization_3d_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/induced_polarization_3d_inversion.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "induced polarization 3d", "physical_property": "chargeability", - "forward_only": false, "data_object": { "main": true, "group": "Data", diff --git a/simpeg_drivers-assets/uijson/joint_cross_gradient_inversion.ui.json b/simpeg_drivers-assets/uijson/joint_cross_gradient_inversion.ui.json index 1e71ced6..7d6efe35 100644 --- a/simpeg_drivers-assets/uijson/joint_cross_gradient_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/joint_cross_gradient_inversion.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "joint cross gradient", "physical_property": "", - "forward_only": false, "group_a": { "main": true, "group": "Joint", diff --git a/simpeg_drivers-assets/uijson/joint_petrophysics_inversion.ui.json b/simpeg_drivers-assets/uijson/joint_petrophysics_inversion.ui.json index 635c0951..7b8bda42 100644 --- a/simpeg_drivers-assets/uijson/joint_petrophysics_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/joint_petrophysics_inversion.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "joint petrophysics", "physical_property": "", - "forward_only": false, "group_a": { "main": true, "group": "Joint", diff --git a/simpeg_drivers-assets/uijson/joint_surveys_inversion.ui.json b/simpeg_drivers-assets/uijson/joint_surveys_inversion.ui.json index e7d8e58c..73e31739 100644 --- a/simpeg_drivers-assets/uijson/joint_surveys_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/joint_surveys_inversion.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "joint surveys", "physical_property": "", - "forward_only": false, "group_a": { "main": true, "group": "Joint", diff --git a/simpeg_drivers-assets/uijson/magnetic_scalar_forward.ui.json b/simpeg_drivers-assets/uijson/magnetic_scalar_forward.ui.json index cb07287b..1296e653 100644 --- a/simpeg_drivers-assets/uijson/magnetic_scalar_forward.ui.json +++ b/simpeg_drivers-assets/uijson/magnetic_scalar_forward.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "magnetic scalar", "physical_property": "susceptibility", - "forward_only": true, "inducing_field_declination": { "min": -180.0, "max": 180.0, diff --git a/simpeg_drivers-assets/uijson/magnetic_scalar_inversion.ui.json b/simpeg_drivers-assets/uijson/magnetic_scalar_inversion.ui.json index 1ba267dc..1d372980 100644 --- a/simpeg_drivers-assets/uijson/magnetic_scalar_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/magnetic_scalar_inversion.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "magnetic scalar", "physical_property": "susceptibility", - "forward_only": false, "inducing_field_declination": { "min": -180.0, "max": 180.0, diff --git a/simpeg_drivers-assets/uijson/magnetic_vector_forward.ui.json b/simpeg_drivers-assets/uijson/magnetic_vector_forward.ui.json index 3c48abb6..9d22dbc9 100644 --- a/simpeg_drivers-assets/uijson/magnetic_vector_forward.ui.json +++ b/simpeg_drivers-assets/uijson/magnetic_vector_forward.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "magnetic vector", "physical_property": "susceptibility", - "forward_only": true, "inducing_field_declination": { "min": -180.0, "max": 180.0, diff --git a/simpeg_drivers-assets/uijson/magnetic_vector_inversion.ui.json b/simpeg_drivers-assets/uijson/magnetic_vector_inversion.ui.json index 8c3e9bac..76ee383f 100644 --- a/simpeg_drivers-assets/uijson/magnetic_vector_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/magnetic_vector_inversion.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "magnetic vector", "physical_property": "susceptibility", - "forward_only": false, "inducing_field_declination": { "min": -180.0, "max": 180.0, diff --git a/simpeg_drivers-assets/uijson/magnetotellurics_forward.ui.json b/simpeg_drivers-assets/uijson/magnetotellurics_forward.ui.json index 642c7d74..670ec26e 100644 --- a/simpeg_drivers-assets/uijson/magnetotellurics_forward.ui.json +++ b/simpeg_drivers-assets/uijson/magnetotellurics_forward.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "magnetotellurics", "physical_property": "conductivity", - "forward_only": true, "data_object": { "main": true, "group": "Survey", diff --git a/simpeg_drivers-assets/uijson/magnetotellurics_inversion.ui.json b/simpeg_drivers-assets/uijson/magnetotellurics_inversion.ui.json index 1c110c3b..b705e166 100644 --- a/simpeg_drivers-assets/uijson/magnetotellurics_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/magnetotellurics_inversion.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "magnetotellurics", "physical_property": "conductivity", - "forward_only": false, "data_object": { "main": true, "group": "Data", diff --git a/simpeg_drivers-assets/uijson/plate_match.ui.json b/simpeg_drivers-assets/uijson/plate_match.ui.json index 94c2600e..3fe0b4cc 100644 --- a/simpeg_drivers-assets/uijson/plate_match.ui.json +++ b/simpeg_drivers-assets/uijson/plate_match.ui.json @@ -8,7 +8,6 @@ "geoh5": "", "monitoring_directory": "", "inversion_type": "plate match", - "forward_only": true, "survey": { "main": true, "label": "Survey", diff --git a/simpeg_drivers-assets/uijson/plate_simulation.ui.json b/simpeg_drivers-assets/uijson/plate_simulation.ui.json index 563cd0e0..ac0ff572 100644 --- a/simpeg_drivers-assets/uijson/plate_simulation.ui.json +++ b/simpeg_drivers-assets/uijson/plate_simulation.ui.json @@ -8,7 +8,6 @@ "geoh5": "", "monitoring_directory": "", "inversion_type": "plate simulation", - "forward_only": true, "simulation": { "main": true, "label": "SimPEG group", diff --git a/simpeg_drivers-assets/uijson/plate_sweep.ui.json b/simpeg_drivers-assets/uijson/plate_sweep.ui.json index 91d3a96a..0a6e94f3 100644 --- a/simpeg_drivers-assets/uijson/plate_sweep.ui.json +++ b/simpeg_drivers-assets/uijson/plate_sweep.ui.json @@ -8,7 +8,6 @@ "geoh5": "", "monitoring_directory": "", "inversion_type": "plate sweep", - "forward_only": true, "template": { "main": true, "group": "Base", diff --git a/simpeg_drivers-assets/uijson/tdem1d_forward.ui.json b/simpeg_drivers-assets/uijson/tdem1d_forward.ui.json index 134fcce0..75928894 100644 --- a/simpeg_drivers-assets/uijson/tdem1d_forward.ui.json +++ b/simpeg_drivers-assets/uijson/tdem1d_forward.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "tdem 1d", "physical_property": "conductivity", - "forward_only": true, "data_object": { "main": true, "group": "Survey", diff --git a/simpeg_drivers-assets/uijson/tdem1d_inversion.ui.json b/simpeg_drivers-assets/uijson/tdem1d_inversion.ui.json index f02bf904..4de73b45 100644 --- a/simpeg_drivers-assets/uijson/tdem1d_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/tdem1d_inversion.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "tdem 1d", "physical_property": "conductivity", - "forward_only": false, "data_object": { "main": true, "group": "Data", diff --git a/simpeg_drivers-assets/uijson/tdem_forward.ui.json b/simpeg_drivers-assets/uijson/tdem_forward.ui.json index 13806380..babc8b54 100644 --- a/simpeg_drivers-assets/uijson/tdem_forward.ui.json +++ b/simpeg_drivers-assets/uijson/tdem_forward.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "tdem", "physical_property": "conductivity", - "forward_only": true, "data_object": { "main": true, "group": "Survey", diff --git a/simpeg_drivers-assets/uijson/tdem_inversion.ui.json b/simpeg_drivers-assets/uijson/tdem_inversion.ui.json index 79c6411c..f62eb44c 100644 --- a/simpeg_drivers-assets/uijson/tdem_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/tdem_inversion.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "tdem", "physical_property": "conductivity", - "forward_only": false, "data_object": { "main": true, "group": "Data", diff --git a/simpeg_drivers-assets/uijson/tipper_forward.ui.json b/simpeg_drivers-assets/uijson/tipper_forward.ui.json index 2c73996a..492b467c 100644 --- a/simpeg_drivers-assets/uijson/tipper_forward.ui.json +++ b/simpeg_drivers-assets/uijson/tipper_forward.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "tipper", "physical_property": "conductivity", - "forward_only": true, "data_object": { "main": true, "group": "Survey", diff --git a/simpeg_drivers-assets/uijson/tipper_inversion.ui.json b/simpeg_drivers-assets/uijson/tipper_inversion.ui.json index 848948d1..e3e975ff 100644 --- a/simpeg_drivers-assets/uijson/tipper_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/tipper_inversion.ui.json @@ -9,7 +9,6 @@ "monitoring_directory": "", "inversion_type": "tipper", "physical_property": "conductivity", - "forward_only": false, "data_object": { "main": true, "group": "Data", From 7b42a6d6e73b114d85c2ac9a4eacca0fd01d7a9b Mon Sep 17 00:00:00 2001 From: domfournier Date: Thu, 19 Mar 2026 08:46:40 -0700 Subject: [PATCH 02/18] Remove inversion_type and physical_property --- .../uijson/apparent_conductivity_forward.ui.json | 2 -- simpeg_drivers-assets/uijson/direct_current_2d_forward.ui.json | 2 -- simpeg_drivers-assets/uijson/direct_current_3d_forward.ui.json | 2 -- simpeg_drivers-assets/uijson/gravity_forward.ui.json | 2 -- simpeg_drivers-assets/uijson/gravity_inversion.ui.json | 2 -- .../uijson/induced_polarization_2d_forward.ui.json | 2 -- .../uijson/induced_polarization_2d_inversion.ui.json | 2 -- .../uijson/induced_polarization_3d_inversion.ui.json | 2 -- .../uijson/joint_petrophysics_inversion.ui.json | 2 -- simpeg_drivers-assets/uijson/joint_surveys_inversion.ui.json | 2 -- simpeg_drivers-assets/uijson/magnetic_scalar_forward.ui.json | 2 -- simpeg_drivers-assets/uijson/magnetic_scalar_inversion.ui.json | 2 -- simpeg_drivers-assets/uijson/magnetic_vector_forward.ui.json | 2 -- simpeg_drivers-assets/uijson/plate_match.ui.json | 1 - simpeg_drivers-assets/uijson/plate_sweep.ui.json | 1 - simpeg_drivers-assets/uijson/tdem1d_forward.ui.json | 2 -- simpeg_drivers-assets/uijson/tdem_forward.ui.json | 2 -- simpeg_drivers-assets/uijson/tipper_inversion.ui.json | 2 -- 18 files changed, 34 deletions(-) diff --git a/simpeg_drivers-assets/uijson/apparent_conductivity_forward.ui.json b/simpeg_drivers-assets/uijson/apparent_conductivity_forward.ui.json index de090d93..040a319c 100644 --- a/simpeg_drivers-assets/uijson/apparent_conductivity_forward.ui.json +++ b/simpeg_drivers-assets/uijson/apparent_conductivity_forward.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "apparent conductivity", - "physical_property": "conductivity", "data_object": { "main": true, "group": "Survey", diff --git a/simpeg_drivers-assets/uijson/direct_current_2d_forward.ui.json b/simpeg_drivers-assets/uijson/direct_current_2d_forward.ui.json index 0323c725..59c96f0d 100644 --- a/simpeg_drivers-assets/uijson/direct_current_2d_forward.ui.json +++ b/simpeg_drivers-assets/uijson/direct_current_2d_forward.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "direct current 2d", - "physical_property": "conductivity", "data_object": { "main": true, "group": "Survey", diff --git a/simpeg_drivers-assets/uijson/direct_current_3d_forward.ui.json b/simpeg_drivers-assets/uijson/direct_current_3d_forward.ui.json index 7610b731..5dac7658 100644 --- a/simpeg_drivers-assets/uijson/direct_current_3d_forward.ui.json +++ b/simpeg_drivers-assets/uijson/direct_current_3d_forward.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "direct current 3d", - "physical_property": "conductivity", "data_object": { "main": true, "group": "Survey", diff --git a/simpeg_drivers-assets/uijson/gravity_forward.ui.json b/simpeg_drivers-assets/uijson/gravity_forward.ui.json index eea29d48..dd5918d9 100644 --- a/simpeg_drivers-assets/uijson/gravity_forward.ui.json +++ b/simpeg_drivers-assets/uijson/gravity_forward.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "gravity", - "physical_property": "density", "data_object": { "main": true, "group": "Survey", diff --git a/simpeg_drivers-assets/uijson/gravity_inversion.ui.json b/simpeg_drivers-assets/uijson/gravity_inversion.ui.json index c7e855c9..a2fd3e1a 100644 --- a/simpeg_drivers-assets/uijson/gravity_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/gravity_inversion.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "gravity", - "physical_property": "density", "data_object": { "main": true, "group": "Data", diff --git a/simpeg_drivers-assets/uijson/induced_polarization_2d_forward.ui.json b/simpeg_drivers-assets/uijson/induced_polarization_2d_forward.ui.json index 7a0c2bc1..9a9ef4de 100644 --- a/simpeg_drivers-assets/uijson/induced_polarization_2d_forward.ui.json +++ b/simpeg_drivers-assets/uijson/induced_polarization_2d_forward.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "induced polarization 2d", - "physical_property": "chargeability", "data_object": { "main": true, "group": "Survey", diff --git a/simpeg_drivers-assets/uijson/induced_polarization_2d_inversion.ui.json b/simpeg_drivers-assets/uijson/induced_polarization_2d_inversion.ui.json index 60dcd655..1e3d6d3d 100644 --- a/simpeg_drivers-assets/uijson/induced_polarization_2d_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/induced_polarization_2d_inversion.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "induced polarization 2d", - "physical_property": "chargeability", "data_object": { "main": true, "group": "Data", diff --git a/simpeg_drivers-assets/uijson/induced_polarization_3d_inversion.ui.json b/simpeg_drivers-assets/uijson/induced_polarization_3d_inversion.ui.json index b6eaa37e..e355d2fa 100644 --- a/simpeg_drivers-assets/uijson/induced_polarization_3d_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/induced_polarization_3d_inversion.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "induced polarization 3d", - "physical_property": "chargeability", "data_object": { "main": true, "group": "Data", diff --git a/simpeg_drivers-assets/uijson/joint_petrophysics_inversion.ui.json b/simpeg_drivers-assets/uijson/joint_petrophysics_inversion.ui.json index 7b8bda42..f1dfade0 100644 --- a/simpeg_drivers-assets/uijson/joint_petrophysics_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/joint_petrophysics_inversion.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "joint petrophysics", - "physical_property": "", "group_a": { "main": true, "group": "Joint", diff --git a/simpeg_drivers-assets/uijson/joint_surveys_inversion.ui.json b/simpeg_drivers-assets/uijson/joint_surveys_inversion.ui.json index 73e31739..4d361e11 100644 --- a/simpeg_drivers-assets/uijson/joint_surveys_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/joint_surveys_inversion.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "joint surveys", - "physical_property": "", "group_a": { "main": true, "group": "Joint", diff --git a/simpeg_drivers-assets/uijson/magnetic_scalar_forward.ui.json b/simpeg_drivers-assets/uijson/magnetic_scalar_forward.ui.json index 1296e653..83c2b862 100644 --- a/simpeg_drivers-assets/uijson/magnetic_scalar_forward.ui.json +++ b/simpeg_drivers-assets/uijson/magnetic_scalar_forward.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "magnetic scalar", - "physical_property": "susceptibility", "inducing_field_declination": { "min": -180.0, "max": 180.0, diff --git a/simpeg_drivers-assets/uijson/magnetic_scalar_inversion.ui.json b/simpeg_drivers-assets/uijson/magnetic_scalar_inversion.ui.json index 1d372980..64c7f43e 100644 --- a/simpeg_drivers-assets/uijson/magnetic_scalar_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/magnetic_scalar_inversion.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "magnetic scalar", - "physical_property": "susceptibility", "inducing_field_declination": { "min": -180.0, "max": 180.0, diff --git a/simpeg_drivers-assets/uijson/magnetic_vector_forward.ui.json b/simpeg_drivers-assets/uijson/magnetic_vector_forward.ui.json index 9d22dbc9..cd9e5a05 100644 --- a/simpeg_drivers-assets/uijson/magnetic_vector_forward.ui.json +++ b/simpeg_drivers-assets/uijson/magnetic_vector_forward.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "magnetic vector", - "physical_property": "susceptibility", "inducing_field_declination": { "min": -180.0, "max": 180.0, diff --git a/simpeg_drivers-assets/uijson/plate_match.ui.json b/simpeg_drivers-assets/uijson/plate_match.ui.json index 3fe0b4cc..6218a27e 100644 --- a/simpeg_drivers-assets/uijson/plate_match.ui.json +++ b/simpeg_drivers-assets/uijson/plate_match.ui.json @@ -7,7 +7,6 @@ "run_command": "simpeg_drivers.plate_simulation.match.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "plate match", "survey": { "main": true, "label": "Survey", diff --git a/simpeg_drivers-assets/uijson/plate_sweep.ui.json b/simpeg_drivers-assets/uijson/plate_sweep.ui.json index 0a6e94f3..c8744500 100644 --- a/simpeg_drivers-assets/uijson/plate_sweep.ui.json +++ b/simpeg_drivers-assets/uijson/plate_sweep.ui.json @@ -7,7 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "plate sweep", "template": { "main": true, "group": "Base", diff --git a/simpeg_drivers-assets/uijson/tdem1d_forward.ui.json b/simpeg_drivers-assets/uijson/tdem1d_forward.ui.json index 75928894..1a41a849 100644 --- a/simpeg_drivers-assets/uijson/tdem1d_forward.ui.json +++ b/simpeg_drivers-assets/uijson/tdem1d_forward.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "tdem 1d", - "physical_property": "conductivity", "data_object": { "main": true, "group": "Survey", diff --git a/simpeg_drivers-assets/uijson/tdem_forward.ui.json b/simpeg_drivers-assets/uijson/tdem_forward.ui.json index babc8b54..beeccc0b 100644 --- a/simpeg_drivers-assets/uijson/tdem_forward.ui.json +++ b/simpeg_drivers-assets/uijson/tdem_forward.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "tdem", - "physical_property": "conductivity", "data_object": { "main": true, "group": "Survey", diff --git a/simpeg_drivers-assets/uijson/tipper_inversion.ui.json b/simpeg_drivers-assets/uijson/tipper_inversion.ui.json index e3e975ff..88508275 100644 --- a/simpeg_drivers-assets/uijson/tipper_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/tipper_inversion.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "tipper", - "physical_property": "conductivity", "data_object": { "main": true, "group": "Data", From cbdfe447714d872fee91c642f26266c394aeb144 Mon Sep 17 00:00:00 2001 From: domfournier Date: Thu, 19 Mar 2026 13:32:29 -0700 Subject: [PATCH 03/18] Split the forward and inversion driver. Move functionality to BaseDriver --- simpeg_drivers/components/windows.py | 116 --- simpeg_drivers/driver.py | 915 +++++++++--------- .../{driver.py => forward.py} | 0 .../three_dimensions/inversion.py | 30 + 4 files changed, 490 insertions(+), 571 deletions(-) delete mode 100644 simpeg_drivers/components/windows.py rename simpeg_drivers/electricals/direct_current/three_dimensions/{driver.py => forward.py} (100%) create mode 100644 simpeg_drivers/electricals/direct_current/three_dimensions/inversion.py diff --git a/simpeg_drivers/components/windows.py b/simpeg_drivers/components/windows.py deleted file mode 100644 index 38fb4abc..00000000 --- a/simpeg_drivers/components/windows.py +++ /dev/null @@ -1,116 +0,0 @@ -# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' -# Copyright (c) 2023-2026 Mira Geoscience Ltd. ' -# ' -# This file is part of simpeg-drivers package. ' -# ' -# simpeg-drivers is distributed under the terms and conditions of the MIT License ' -# (see LICENSE file at the root of this source code package). ' -# ' -# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' - - -from __future__ import annotations - -from typing import TYPE_CHECKING, Any - - -if TYPE_CHECKING: - from geoapps_utils.driver.params import BaseParams - from geoh5py.workspace import Workspace - - from simpeg_drivers.options import BaseForwardOptions, BaseInversionOptions - -import numpy as np -from geoh5py.objects import Grid2D, PotentialElectrode - - -class InversionWindow: - """ - Retrieve and store window data from workspace. - - If params contains no window data, the window will initialize with from the - data extents. - - Attributes - ---------- - - workspace: - Geoh5py workspace object containing window data. - params: - Options object containing window parameters. - window: - Center and size defining window for data, topography, etc. - - Methods - ------- - - is_empty(): - Check if window data is empty. - - """ - - window_keys = ["center_x", "center_y", "height", "width", "size", "center"] - - def __init__( - self, - workspace: Workspace, - params: BaseParams | BaseForwardOptions | BaseInversionOptions, - ): - """ - :param: workspace: Geoh5py workspace object containing window data. - :param: params: Options object containing window parameters. - :param: window: - """ - self.workspace = workspace - self.params = params - self._window: dict[str, Any] | None = None - - def is_empty(self) -> bool: - """Check if window data is empty.""" - if self._window is None: - return True - elif (self._window["size"][0] == 0) & (self._window["size"][1] == 0): - return True - else: - center_x_null = True if self._window["center"][0] is None else False - center_y_null = True if self._window["center"][1] is None else False - size_x_null = True if self._window["size"][0] is None else False - size_y_null = True if self._window["size"][1] is None else False - return center_x_null & center_y_null & size_x_null & size_y_null - - @property - def window(self): - """Get params.window data.""" - if self._window is None: - if self.is_empty(): - data_object = self.params.data_object - if isinstance(data_object, Grid2D): - locs = data_object.centroids - elif isinstance(data_object, PotentialElectrode): - locs = np.vstack( - [data_object.vertices, data_object.current_electrodes.vertices] - ) - locs = np.unique(locs, axis=0) - else: - locs = data_object.vertices - - if locs is None: - msg = f"Object {data_object} is not Grid2D object and doesn't contain vertices." - raise (ValueError(msg)) - - min_corner = np.min(locs[:, :2], axis=0) - max_corner = np.max(locs[:, :2], axis=0) - - size = max_corner - min_corner - size[size == 0] = np.mean(size) - - self._window = { - "center": np.mean([max_corner, min_corner], axis=0), - "size": size, - } - else: - self._window = self.params.window - return self._window - - def __call__(self): - return self.window diff --git a/simpeg_drivers/driver.py b/simpeg_drivers/driver.py index 82f4f57e..c1390137 100644 --- a/simpeg_drivers/driver.py +++ b/simpeg_drivers/driver.py @@ -13,6 +13,7 @@ from __future__ import annotations +from abc import abstractmethod, ABC import cProfile import pstats @@ -64,7 +65,6 @@ InversionMesh, InversionModelCollection, InversionTopography, - InversionWindow, ) from simpeg_drivers.components.factories import ( DirectivesFactory, @@ -83,7 +83,7 @@ mlogger.setLevel(logging.WARNING) -class BaseDriver(Driver): +class BaseDriver(Driver, ABC): """ Base class for drivers handling the parallel setup. """ @@ -93,178 +93,14 @@ def __init__( params: Options, client: Client | bool | None = None, workers: list[str] | None = None, - ): - super().__init__(params) - self.out_group = self.validate_out_group(self.params.out_group) - self._client: Client | bool = self.validate_client(client) - - if getattr(self.params, "store_sensitivities", None) == "disk" and self.client: - raise GeoAppsError( - "Disk storage of sensitivities is not compatible with distributed processing." - ) - - self._workers: list[tuple[str]] = self.validate_workers(workers) - - @property - def out_group(self) -> SimPEGGroup: - """ - Returns the output group for the simulation. - """ - return self._out_group - - @out_group.setter - def out_group(self, value: SimPEGGroup): - if not isinstance(value, SimPEGGroup): - raise TypeError("Output group must be a SimPEGGroup.") - - if self.params.out_group != value: - self.params.out_group = value - self.params.update_out_group_options() - - self._out_group = value - - def validate_out_group(self, out_group: SimPEGGroup | None) -> SimPEGGroup: - """ - Validate or create a SimPEGGroup to store results. - - :param out_group: Output group from selection. - """ - if isinstance(out_group, SimPEGGroup): - return out_group - - with fetch_active_workspace(self.params.geoh5, mode="r+"): - out_group = SimPEGGroup.create( - self.params.geoh5, - name=self.params.title, - ) - out_group.entity_type.name = self.params.title - - return out_group - - @property - def client(self) -> Client | bool | None: - """ - Dask client or False if not using Dask.distributed. - """ - return self._client - - @property - def workers(self) -> list[tuple[str]]: - """List of workers stored as a list of tuples.""" - return self._workers - - def validate_client(self, client: Client | bool | None) -> Client | bool: - """ - Validate or create a Dask client. - """ - if client is None: - try: - client = get_client() - except ValueError: - client = False - return client - - def validate_workers(self, workers: list[tuple[str]] | None) -> list[tuple[str]]: - """ - Validate the list of workers. - """ - if self.client: - available_workers = [(worker,) for worker in self.client.nthreads()] - else: - return [] - - if workers is None: - return available_workers - - if not isinstance(workers, list) or not all( - isinstance(w, tuple) for w in workers - ): - raise TypeError("Workers must be a list of tuple[str].") - - invalid_workers = [w for w in workers if w not in available_workers] - if invalid_workers: - raise ValueError( - f"The following workers are not available: {invalid_workers}. " - f"Available workers are: {available_workers}." - ) - - return workers - - @classmethod - def start_dask_run( - cls, - json_path: Path, - n_workers: int | None = None, - n_threads: int | None = None, - save_report: bool = True, - ): - """ - Sets Dask config settings. - - :param json_path: Path to input file (.ui.json) for the application. - :param n_workers: Number of Dask workers. - :param n_threads: Number of threads per Dask worker. - :param save_report: Whether to save a performance report. - """ - distributed_process = ( - n_workers is not None and n_workers > 1 - ) or n_threads is not None - - cluster = ( - LocalCluster( - processes=True, - n_workers=n_workers, - threads_per_worker=n_threads, - ) - if distributed_process - else None - ) - profiler = cProfile.Profile() - profiler.enable() - - with ( - cluster.get_client() - if cluster is not None - else contextlib.nullcontext() as context_client - ): - # Full run - with ( - performance_report(filename=json_path.parent / "dask_profile.html") - if (save_report and isinstance(context_client, Client)) - else contextlib.nullcontext() - ): - cls.start(json_path) - sys.stdout.close() - - profiler.disable() - - if save_report: - with open( - json_path.parent / "runtime_profile.txt", encoding="utf-8", mode="w" - ) as s: - ps = pstats.Stats(profiler, stream=s) - ps.sort_stats("cumulative") - ps.print_stats() - - -class InversionDriver(BaseDriver): - _params_class = BaseForwardOptions | BaseInversionOptions - _inversion_type: str | None = None - - def __init__( - self, - params: BaseForwardOptions | BaseInversionOptions, - client: Client | bool | None = None, - workers: list[tuple[str]] | None = None, logger: logging.Logger | None | bool = None, ): - super().__init__(params, client=client, workers=workers) + super().__init__(params) self.inversion_type = self.params.inversion_type self._data_misfit: objective_function.ComboObjectiveFunction | None = None self._directives: list[directives.InversionDirective] | None = None self._inverse_problem: inverse_problem.BaseInvProblem | None = None - self._inversion: inversion.BaseInversion | None = None self._inversion_data: InversionData | None = None self._inversion_mesh: InversionMesh | None = None self._inversion_topography: InversionTopography | None = None @@ -272,50 +108,27 @@ def __init__( self._mapping: list[maps.IdentityMap] | None = None self._models: InversionModelCollection | None = None self._n_values: int | None = None - self._optimization: optimization.ProjectedGNCG | None = None - self._regularization: None = None self._simulation: simulation.BaseSimulation | None = None - self._ordering: list[np.ndarray] | None = None self._mappings: list[maps.IdentityMap] | None = None - self._window = None - self.tiles: dict[str, list[np.ndarray]] - def split_list(self, tiles: list[np.ndarray]) -> list[list[np.ndarray]]: - """ - Number of splits for the data misfit to be distributed evenly among workers. - """ - if not self.workers: - return [[tile] for tile in tiles] - - n_tiles = len(tiles) - - n_channels = 1 - if isinstance(self.params.data_object, FEMSurvey) and not isinstance( - self.simulation, Simulation1DLayered - ): - n_channels = len(self.params.data_object.channels) - - split_list = [1] * n_tiles - - count = 0 - while (np.sum(split_list) * n_channels) % len(self.workers) != 0: - split_list[count % n_tiles] += 1 - count += 1 + self.out_group = self.validate_out_group(self.params.out_group) + self._client: Client | bool = validate_client(client) - if self.logger: - self.logger.write( - f"Number of misfits: {np.sum(split_list)} distributed over {len(self.workers)} workers.\n" + if getattr(self.params, "store_sensitivities", None) == "disk" and self.client: + raise GeoAppsError( + "Disk storage of sensitivities is not compatible with distributed processing." ) - flat_tile_list = [] - for tile, split in zip(tiles, split_list): - flat_tile_list.append( - [sub for sub in np.array_split(tile, split) if len(sub) > 0] - ) + self._workers: list[tuple[str]] = validate_workers(self._client, workers) - return flat_tile_list + @property + def client(self) -> Client | bool | None: + """ + Dask client or False if not using Dask.distributed. + """ + return self._client @property def data_misfit(self): @@ -368,30 +181,35 @@ def get_nested_tiles(self) -> list: return nested_tiles - @property - def inverse_problem(self): - if getattr(self, "_inverse_problem", None) is None: - self._inverse_problem = inverse_problem.BaseInvProblem( - self.data_misfit, - self.regularization, - self.optimization, - ) + def get_tiles(self) -> dict[str, list[np.ndarray]]: + """ + Parse the data locations into tiles for distributed processing. - if ( - not self.params.forward_only - and self.params.cooling_schedule.initial_beta - ): - self._inverse_problem.beta = self.params.cooling_schedule.initial_beta + Adapts differently to the inversion type (1D, 2D or 3D). - return self._inverse_problem + :return: Dictionary with channels as keys and list of tiles as values. + """ + tiles = tile_locations( + self.inversion_data.locations, + self.params.compute.tile_spatial, + labels=self.inversion_data.parts, + sorting=self.simulation.survey.sorting, + ) + tiles = self.split_list(tiles) - @property - def inversion(self): - if getattr(self, "_inversion", None) is None: - self._inversion = inversion.BaseInversion( - self.inverse_problem, directiveList=self.directives.directive_list - ) - return self._inversion + # Base slice over frequencies + if self.params.inversion_type in [ + "apparent conductivity", + "magnetotellurics", + "tipper", + "fdem", + ]: + channels = self.simulation.survey.frequencies + else: + channels = [None] + + # Duplicate tiles for each channel + return {channel: tiles for channel in channels} @property def inversion_data(self) -> InversionData: @@ -420,15 +238,21 @@ def inversion_topography(self): return self._inversion_topography @property - def inversion_type(self) -> str | None: - """Inversion type""" - return self._inversion_type + def inverse_problem(self): + if getattr(self, "_inverse_problem", None) is None: + self._inverse_problem = inverse_problem.BaseInvProblem( + self.data_misfit, + self.regularization, + self.optimization, + ) + + if ( + not self.params.forward_only + and self.params.cooling_schedule.initial_beta + ): + self._inverse_problem.beta = self.params.cooling_schedule.initial_beta - @inversion_type.setter - def inversion_type(self, value): - if value not in DRIVER_MAP: - raise ValueError(f"Invalid inversion type: {value}") - self._inversion_type = value + return self._inverse_problem @property def logger(self) -> InversionLogger | None: @@ -450,6 +274,26 @@ def logger(self, value: InversionLogger | None | bool): "Logger must be a InversionLogger instance, None, True or False." ) + @property + def mapping(self) -> list[maps.Projection] | None: + """Model mapping for the inversion.""" + if self._mapping is None: + mapping = [] + start = 0 + n_blocks = 3 if self.models.is_vector else 1 + + for _ in range(n_blocks): + mapping.append( + maps.Projection( + self.n_values * n_blocks, slice(start, start + self.n_values) + ) + ) + start += self.n_values + + self._mapping = mapping + + return self._mapping + @property def models(self): """Inversion models""" @@ -474,30 +318,80 @@ def n_values(self): return self._n_values - @property - def optimization(self): - if getattr(self, "_optimization", None) is None: - if self.params.forward_only: - return optimization.ProjectedGNCG(cg_rtol=1.0) + @mapping.setter + def mapping(self, value: maps.IdentityMap | list[maps.IdentityMap]): + if not isinstance(value, list): + value = [value] - self._optimization = optimization.ProjectedGNCG( - maxIter=self.params.optimization.max_global_iterations, - lower=self.models.lower_bound, - upper=self.models.upper_bound, - maxIterLS=self.params.optimization.max_line_search_iterations, - cg_maxiter=self.params.optimization.max_cg_iterations, - cg_rtol=self.params.optimization.tol_cg, - active_set_grad_scale=1e-8, - LSshorten=0.25, - require_decrease=False, + if not all( + isinstance(val, maps.IdentityMap) and val.shape[0] == self.n_values + for val in value + ): + raise TypeError( + "'mapping' must be an instance of maps.IdentityMap with shape (n_values, *). " + f"Provided {value}" ) - return self._optimization + + self._mapping = value + + def split_list(self, tiles: list[np.ndarray]) -> list[list[np.ndarray]]: + """ + Number of splits for the data misfit to be distributed evenly among workers. + """ + if not self.workers: + return [[tile] for tile in tiles] + + n_tiles = len(tiles) + + n_channels = 1 + if isinstance(self.params.data_object, FEMSurvey) and not isinstance( + self.simulation, Simulation1DLayered + ): + n_channels = len(self.params.data_object.channels) + + split_list = [1] * n_tiles + + count = 0 + while (np.sum(split_list) * n_channels) % len(self.workers) != 0: + split_list[count % n_tiles] += 1 + count += 1 + + if self.logger: + self.logger.write( + f"Number of misfits: {np.sum(split_list)} distributed over {len(self.workers)} workers.\n" + ) + + flat_tile_list = [] + for tile, split in zip(tiles, split_list): + flat_tile_list.append( + [sub for sub in np.array_split(tile, split) if len(sub) > 0] + ) + + return flat_tile_list @property def ordering(self): """List of ordering of the data.""" return self.inversion_data.survey.ordering + @property + def out_group(self) -> SimPEGGroup: + """ + Returns the output group for the simulation. + """ + return self._out_group + + @out_group.setter + def out_group(self, value: SimPEGGroup): + if not isinstance(value, SimPEGGroup): + raise TypeError("Output group must be a SimPEGGroup.") + + if self.params.out_group != value: + self.params.out_group = value + self.params.update_out_group_options() + + self._out_group = value + @property def params(self) -> BaseForwardOptions | BaseInversionOptions: """Application parameters.""" @@ -523,105 +417,201 @@ def params( @property def regularization(self): - if getattr(self, "_regularization", None) is None: - with fetch_active_workspace(self.workspace, mode="r"): - if self.logger: - self.logger.write("Creating the regularization functions...\n") + """ + Base regularization for the inversion. - self._regularization = self.get_regularization() + Returns a BaseRegularization if forward_only is True, otherwise returns a ComboObjectiveFunction. + """ - return self._regularization + return objective_function.ComboObjectiveFunction() - @regularization.setter - def regularization(self, regularization: objective_function.ComboObjectiveFunction): - if not isinstance(regularization, objective_function.ComboObjectiveFunction): - raise TypeError( - f"Regularization must be a ComboObjectiveFunction, not {type(regularization)}." + @property + def optimization(self): + """ + Base optimization for the inversion. + """ + return optimization.ProjectedGNCG() + + @property + def simulation(self): + """ + The simulation object used in the inversion. + """ + if getattr(self, "_simulation", None) is None: + simulation_factory = SimulationFactory(self.params) + self._simulation = simulation_factory.build( + mesh=self.inversion_mesh.mesh, + models=self.models, + survey=self.inversion_data.survey, ) - self._regularization = regularization - @property - def simulation(self): + if not hasattr(self._simulation, "active_cells"): + self._simulation.active_cells = self.models.active_cells + + return self._simulation + + @abstractmethod + def simpeg_run(self): + """ + Run call to simpeg. + """ + + @abstractmethod + def start_message(self): + """ + Starting message displayed by the logger. + """ + + def run(self): + """Run inversion from params""" + sys.stdout = self.logger + self.logger.start() + with fetch_active_workspace(self.workspace, mode="r+"): + if Path(self.params.input_file.path_name).is_file(): + self.out_group.add_file(self.params.input_file.path_name) + + try: + self.start_message() + self.simpeg_run() + + except np.core._exceptions._ArrayMemoryError as error: # pylint: disable=protected-access + raise GeoAppsError( + "Memory Error: Sensitivities too large for system. \n" + "Try reducing the number of data, reducing the number of cells in the mesh\n" + "or increase the number of tiles." + ) from error + + self.logger.end() + sys.stdout = self.logger.terminal + + with fetch_active_workspace(self.workspace, mode="r+"): + for directive in self.directives.save_directives: + if isinstance(directive, directives.SaveLogFilesGeoH5): + directive.write(1) + + @classmethod + def start_dask_run(cls, json_path: Path): + """ + Sets Dask config settings. + + :param json_path: Path to input file (.ui.json) for the application. + """ + ui_json = load_ui_json_as_dict(json_path) + + n_workers = (ui_json.get("n_workers", None),) + n_threads = (ui_json.get("n_threads", None),) + save_report = (ui_json.get("performance_report", False),) + + distributed_process = ( + n_workers is not None and n_workers > 1 + ) or n_threads is not None + + cluster = ( + LocalCluster( + processes=True, + n_workers=n_workers, + threads_per_worker=n_threads, + ) + if distributed_process + else None + ) + profiler = cProfile.Profile() + profiler.enable() + + with ( + cluster.get_client() + if cluster is not None + else contextlib.nullcontext() as context_client + ): + # Full run + with ( + performance_report(filename=json_path.parent / "dask_profile.html") + if (save_report and isinstance(context_client, Client)) + else contextlib.nullcontext() + ): + cls.start(json_path) + sys.stdout.close() + + profiler.disable() + + if save_report: + with open( + json_path.parent / "runtime_profile.txt", encoding="utf-8", mode="w" + ) as s: + ps = pstats.Stats(profiler, stream=s) + ps.sort_stats("cumulative") + ps.print_stats() + + def validate_out_group(self, out_group: SimPEGGroup | None) -> SimPEGGroup: """ - The simulation object used in the inversion. + Validate or create a SimPEGGroup to store results. + + :param out_group: Output group from selection. """ - if getattr(self, "_simulation", None) is None: - simulation_factory = SimulationFactory(self.params) - self._simulation = simulation_factory.build( - mesh=self.inversion_mesh.mesh, - models=self.models, - survey=self.inversion_data.survey, - ) + if isinstance(out_group, SimPEGGroup): + return out_group - if not hasattr(self._simulation, "active_cells"): - self._simulation.active_cells = self.models.active_cells + with fetch_active_workspace(self.params.geoh5, mode="r+"): + out_group = SimPEGGroup.create( + self.params.geoh5, + name=self.params.title, + ) + out_group.entity_type.name = self.params.title - return self._simulation + return out_group @property - def window(self): - """Inversion window""" - if getattr(self, "_window", None) is None: - self._window = InversionWindow(self.workspace, self.params) - return self._window + def workers(self) -> list[tuple[str]]: + """List of workers stored as a list of tuples.""" + return self._workers - def run(self): - """Run inversion from params""" - if self.logger: - sys.stdout = self.logger - self.logger.start() - with fetch_active_workspace(self.workspace, mode="r+"): - simpeg_inversion = self.inversion +class ForwardDriver(BaseDriver): + def __init__( + self, + params: BaseForwardOptions | BaseInversionOptions, + client: Client | bool | None = None, + workers: list[tuple[str]] | None = None, + ): + super().__init__(params, client=client, workers=workers) - if Path(self.params.input_file.path_name).is_file(): - self.out_group.add_file(self.params.input_file.path_name) + def simpeg_run(self): + """Run inversion from params""" - predicted = None - try: - if self.params.forward_only: - if self.logger: - self.logger.write("Running the forward simulation ...\n") - predicted = simpeg_inversion.invProb.get_dpred( - self.models.starting_model, None - ) - else: - # Run the inversion - if self.logger: - self.start_inversion_message() - simpeg_inversion.run(self.models.starting_model) + predicted = self.inverse_problem.get_dpred(self.models.starting_model, None) + self.directives.save_iteration_data_directive.write(0, predicted) - except np.core._exceptions._ArrayMemoryError as error: # pylint: disable=protected-access - raise GeoAppsError( - "Memory Error: Sensitivities too large for system. \n" - "Try reducing the number of data, reducing the number of cells in the mesh\n" - "or increase the number of tiles." - ) from error + if ( + isinstance( + self.directives.save_iteration_data_directive, + directives.SaveDataGeoH5, + ) + and len(self.directives.save_iteration_data_directive.channels) > 1 + ): + directives.SavePropertyGroup( + self.inversion_data.entity, + channels=self.directives.save_iteration_data_directive.channels, + components=self.directives.save_iteration_data_directive.components, + ).write(0) - if self.logger: - self.logger.end() - sys.stdout = self.logger.terminal + def start_message(self): + self.logger.write("Running the forward simulation ...\n") - if self.params.forward_only: - self.directives.save_iteration_data_directive.write(0, predicted) - if ( - isinstance( - self.directives.save_iteration_data_directive, - directives.SaveDataGeoH5, - ) - and len(self.directives.save_iteration_data_directive.channels) > 1 - ): - directives.SavePropertyGroup( - self.inversion_data.entity, - channels=self.directives.save_iteration_data_directive.channels, - components=self.directives.save_iteration_data_directive.components, - ).write(0) +class InversionDriver(BaseDriver): + _params_class = BaseForwardOptions | BaseInversionOptions - with fetch_active_workspace(self.workspace, mode="r+"): - for directive in self.directives.save_directives: - if isinstance(directive, directives.SaveLogFilesGeoH5): - directive.write(1) + def __init__( + self, + params: BaseForwardOptions | BaseInversionOptions, + client: Client | bool | None = None, + workers: list[tuple[str]] | None = None, + ): + super().__init__(params, client=client, workers=workers) + + self._inversion: inversion.BaseInversion | None = None + self._optimization: optimization.ProjectedGNCG | None = None + self._regularization: None = None def count_data(self): """ @@ -640,64 +630,6 @@ def count_data(self): return finite_data_count, total_data_count - def start_inversion_message(self): - # SimPEG reports half phi_d, so we scale to match - has_chi_start = self.params.irls.starting_chi_factor is not None - chi_start = ( - self.params.irls.starting_chi_factor - if has_chi_start - else self.params.cooling_schedule.chi_factor - ) - - finite_data_count, total_data_count = self.count_data() - rescale = finite_data_count / total_data_count - rescaled_chi_factor = self.params.cooling_schedule.chi_factor * rescale - rescaled_starting_chi_factor = chi_start * rescale - self.logger.write( - f"Target Misfit: {rescaled_chi_factor * total_data_count:.2e} ({finite_data_count} data " - f"with chifact = {self.params.cooling_schedule.chi_factor})\n" - ) - self.logger.write( - f"IRLS Start Misfit: {rescaled_starting_chi_factor * total_data_count:.2e} ({finite_data_count} data " - f"with chifact = {self.params.irls.starting_chi_factor})\n" - ) - - @property - def mapping(self) -> list[maps.Projection] | None: - """Model mapping for the inversion.""" - if self._mapping is None: - mapping = [] - start = 0 - n_blocks = 3 if self.models.is_vector else 1 - - for _ in range(n_blocks): - mapping.append( - maps.Projection( - self.n_values * n_blocks, slice(start, start + self.n_values) - ) - ) - start += self.n_values - - self._mapping = mapping - - return self._mapping - - @mapping.setter - def mapping(self, value: maps.IdentityMap | list[maps.IdentityMap]): - if not isinstance(value, list): - value = [value] - - if not all( - isinstance(val, maps.IdentityMap) and val.shape[0] == self.n_values - for val in value - ): - raise TypeError( - "'mapping' must be an instance of maps.IdentityMap with shape (n_values, *). " - f"Provided {value}" - ) - - self._mapping = value - def get_regularization(self): if self.params.forward_only: return BaseRegularization(mesh=self.inversion_mesh.mesh) @@ -798,78 +730,77 @@ def get_regularization(self): return objective_function.ComboObjectiveFunction(objfcts=reg_funcs) - def get_tiles(self) -> dict[str, list[np.ndarray]]: - """ - Parse the data locations into tiles for distributed processing. - - Adapts differently to the inversion type (1D, 2D or 3D). - - :return: Dictionary with channels as keys and list of tiles as values. - """ - tiles = tile_locations( - self.inversion_data.locations, - self.params.compute.tile_spatial, - labels=self.inversion_data.parts, - sorting=self.simulation.survey.sorting, - ) - tiles = self.split_list(tiles) - - # Base slice over frequencies - if self.params.inversion_type in [ - "apparent conductivity", - "magnetotellurics", - "tipper", - "fdem", - ]: - channels = self.simulation.survey.frequencies - else: - channels = [None] - - # Duplicate tiles for each channel - return {channel: tiles for channel in channels} + @property + def inversion(self): + if getattr(self, "_inversion", None) is None: + self._inversion = inversion.BaseInversion( + self.inverse_problem, directiveList=self.directives.directive_list + ) + return self._inversion - @classmethod - def start(cls, filepath: str | Path | InputFile, **kwargs) -> Self: - """ - Start the inversion driver. + @property + def optimization(self): + if getattr(self, "_optimization", None) is None: + if self.params.forward_only: + return optimization.ProjectedGNCG(cg_rtol=1.0) - :param filepath: Path to the input file or InputFile object. - :param kwargs: Additional keyword arguments for InputFile read_ui_json. + self._optimization = optimization.ProjectedGNCG( + maxIter=self.params.optimization.max_global_iterations, + lower=self.models.lower_bound, + upper=self.models.upper_bound, + maxIterLS=self.params.optimization.max_line_search_iterations, + cg_maxiter=self.params.optimization.max_cg_iterations, + cg_rtol=self.params.optimization.tol_cg, + active_set_grad_scale=1e-8, + LSshorten=0.25, + require_decrease=False, + ) + return self._optimization - :return: InversionDriver instance with the specified parameters. - """ - driver = super().start(filepath, **kwargs) + @property + def regularization(self): + if getattr(self, "_regularization", None) is None: + with fetch_active_workspace(self.workspace, mode="r"): + if self.logger: + self.logger.write("Creating the regularization functions...\n") - return driver + self._regularization = self.get_regularization() - @staticmethod - def driver_class_from_name( - name: str, forward_only: bool = False - ) -> type[InversionDriver]: - if name not in DRIVER_MAP: - msg = f"Inversion type '{name}' is not supported." - msg += f" Valid inversions are: {(*list(DRIVER_MAP),)}." - raise NotImplementedError(msg) + return self._regularization - mod_name, classes = DRIVER_MAP.get(name) - class_name = classes.get("inversion") - if forward_only: - class_name = classes.get("forward", class_name) + @regularization.setter + def regularization(self, regularization: objective_function.ComboObjectiveFunction): + if not isinstance(regularization, objective_function.ComboObjectiveFunction): + raise TypeError( + f"Regularization must be a ComboObjectiveFunction, not {type(regularization)}." + ) + self._regularization = regularization - module = __import__(mod_name, fromlist=[class_name]) - return getattr(module, class_name) + def simpeg_run(self): + """Run inversion from params""" + self.inversion.run(self.models.starting_model) - @classmethod - def from_input_file(cls, data: dict) -> type[InversionDriver]: - forward_only = data.get("forward_only", False) - inversion_type = data.get("inversion_type", "") - if inversion_type is None: - raise GeoAppsError( - "Key/value 'inversion_type' not found in the input file. " - "Please specify the inversion type in the UI JSON." - ) + def start_message(self): + # SimPEG reports half phi_d, so we scale to match + has_chi_start = self.params.irls.starting_chi_factor is not None + chi_start = ( + self.params.irls.starting_chi_factor + if has_chi_start + else self.params.cooling_schedule.chi_factor + ) - return cls.driver_class_from_name(inversion_type, forward_only=forward_only) + finite_data_count, total_data_count = self.count_data() + rescale = finite_data_count / total_data_count + rescaled_chi_factor = self.params.cooling_schedule.chi_factor * rescale + rescaled_starting_chi_factor = chi_start * rescale + self.logger.write( + f"Target Misfit: {rescaled_chi_factor * total_data_count:.2e} ({finite_data_count} data " + f"with chifact = {self.params.cooling_schedule.chi_factor})\n" + ) + self.logger.write( + f"IRLS Start Misfit: {rescaled_starting_chi_factor * total_data_count:.2e} ({finite_data_count} data " + f"with chifact = {self.params.irls.starting_chi_factor})\n" + ) class InversionLogger: @@ -917,14 +848,88 @@ def get_path(self, filepath: str | Path) -> str: return str(root_directory / filepath) +def driver_class_from_name( + name: str, forward_only: bool = False +) -> type[InversionDriver]: + """ + Get the driver class from the inversion type name. + + TODO: Only for backward compatibility. To be deprecated in future versions. + + :param name: The inversion type name. + :param forward_only: Whether to forward only the forward operators. + + :return: InversionDriver or ForwardDriver class. + """ + if name not in DRIVER_MAP: + msg = f"Inversion type '{name}' is not supported." + msg += f" Valid inversions are: {(*list(DRIVER_MAP),)}." + raise NotImplementedError(msg) + + mod_name, classes = DRIVER_MAP.get(name) + class_name = classes.get("inversion") + if forward_only: + class_name = classes.get("forward", class_name) + + module = __import__(mod_name, fromlist=[class_name]) + return getattr(module, class_name) + + +def from_input_file(data: dict) -> type[InversionDriver]: + forward_only = data.get("forward_only", False) + inversion_type = data.get("inversion_type", "") + if inversion_type is None: + raise GeoAppsError( + "Key/value 'inversion_type' not found in the input file. " + "Please specify the inversion type in the UI JSON." + ) + + return driver_class_from_name(inversion_type, forward_only=forward_only) + + +def validate_client(client: Client | bool | None) -> Client | bool: + """ + Validate or create a Dask client. + """ + if client is None: + try: + client = get_client() + except ValueError: + client = False + return client + + +def validate_workers(client, workers: list[tuple[str]] | None) -> list[tuple[str]]: + """ + Validate the list of workers. + """ + if client: + available_workers = [(worker,) for worker in client.nthreads()] + else: + return [] + + if workers is None: + return available_workers + + if not isinstance(workers, list) or not all(isinstance(w, tuple) for w in workers): + raise TypeError("Workers must be a list of tuple[str].") + + invalid_workers = [w for w in workers if w not in available_workers] + if invalid_workers: + raise ValueError( + f"The following workers are not available: {invalid_workers}. " + f"Available workers are: {available_workers}." + ) + + return workers + + if __name__ == "__main__": file = Path(sys.argv[1]).resolve() - input_file = load_ui_json_as_dict(file) + + # TODO - Deprecate in favour of run_command to direct module # Need to know the driver class before starting dask - driver_class = InversionDriver.from_input_file(input_file) - driver_class.start_dask_run( - file, - n_workers=input_file.get("n_workers", None), - n_threads=input_file.get("n_threads", None), - save_report=input_file.get("performance_report", False), - ) + input_file = load_ui_json_as_dict(file) + driver_class = from_input_file(input_file) + + driver_class.start_dask_run(file) diff --git a/simpeg_drivers/electricals/direct_current/three_dimensions/driver.py b/simpeg_drivers/electricals/direct_current/three_dimensions/forward.py similarity index 100% rename from simpeg_drivers/electricals/direct_current/three_dimensions/driver.py rename to simpeg_drivers/electricals/direct_current/three_dimensions/forward.py diff --git a/simpeg_drivers/electricals/direct_current/three_dimensions/inversion.py b/simpeg_drivers/electricals/direct_current/three_dimensions/inversion.py new file mode 100644 index 00000000..db554c26 --- /dev/null +++ b/simpeg_drivers/electricals/direct_current/three_dimensions/inversion.py @@ -0,0 +1,30 @@ +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +# Copyright (c) 2023-2026 Mira Geoscience Ltd. ' +# ' +# This file is part of simpeg-drivers package. ' +# ' +# simpeg-drivers is distributed under the terms and conditions of the MIT License ' +# (see LICENSE file at the root of this source code package). ' +# ' +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + + +from __future__ import annotations + +from simpeg_drivers.driver import InversionDriver + +from .options import DC3DForwardOptions, DC3DInversionOptions + + +class DC3DForwardDriver(InversionDriver): + """Direct Current 3D forward driver.""" + + _params_class = DC3DForwardOptions + _validation = None + + +class DC3DInversionDriver(InversionDriver): + """Direct Current 3D inversion driver.""" + + _params_class = DC3DInversionOptions + _validation = None From cfa7e182fd8ab66927e2274daa0f57559b15b951 Mon Sep 17 00:00:00 2001 From: domfournier Date: Thu, 19 Mar 2026 14:41:15 -0700 Subject: [PATCH 04/18] Update uijson's --- .../uijson/apparent_conductivity_inversion.ui.json | 2 -- .../uijson/direct_current_2d_inversion.ui.json | 2 -- .../uijson/direct_current_3d_forward.ui.json | 2 +- .../uijson/direct_current_3d_inversion.ui.json | 4 +--- simpeg_drivers-assets/uijson/fdem1d_forward.ui.json | 2 -- simpeg_drivers-assets/uijson/fdem1d_inversion.ui.json | 2 -- simpeg_drivers-assets/uijson/fdem_forward.ui.json | 2 -- simpeg_drivers-assets/uijson/fdem_inversion.ui.json | 2 -- .../uijson/induced_polarization_3d_forward.ui.json | 2 -- .../uijson/joint_cross_gradient_inversion.ui.json | 2 -- .../uijson/magnetic_vector_inversion.ui.json | 2 -- simpeg_drivers-assets/uijson/magnetotellurics_forward.ui.json | 2 -- .../uijson/magnetotellurics_inversion.ui.json | 2 -- simpeg_drivers-assets/uijson/plate_simulation.ui.json | 1 - simpeg_drivers-assets/uijson/tdem1d_inversion.ui.json | 2 -- simpeg_drivers-assets/uijson/tdem_inversion.ui.json | 2 -- simpeg_drivers-assets/uijson/tipper_forward.ui.json | 2 -- 17 files changed, 2 insertions(+), 33 deletions(-) diff --git a/simpeg_drivers-assets/uijson/apparent_conductivity_inversion.ui.json b/simpeg_drivers-assets/uijson/apparent_conductivity_inversion.ui.json index c0429aa6..e70110da 100644 --- a/simpeg_drivers-assets/uijson/apparent_conductivity_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/apparent_conductivity_inversion.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "apparent conductivity", - "physical_property": "conductivity", "data_object": { "main": true, "group": "Data", diff --git a/simpeg_drivers-assets/uijson/direct_current_2d_inversion.ui.json b/simpeg_drivers-assets/uijson/direct_current_2d_inversion.ui.json index a14e03aa..2ef58b7a 100644 --- a/simpeg_drivers-assets/uijson/direct_current_2d_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/direct_current_2d_inversion.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "direct current 2d", - "physical_property": "conductivity", "data_object": { "main": true, "group": "Data", diff --git a/simpeg_drivers-assets/uijson/direct_current_3d_forward.ui.json b/simpeg_drivers-assets/uijson/direct_current_3d_forward.ui.json index 5dac7658..ce8f6673 100644 --- a/simpeg_drivers-assets/uijson/direct_current_3d_forward.ui.json +++ b/simpeg_drivers-assets/uijson/direct_current_3d_forward.ui.json @@ -4,7 +4,7 @@ "icon": "PotentialElectrode", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.electricals.direct_current.three_dimensions.forward", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/direct_current_3d_inversion.ui.json b/simpeg_drivers-assets/uijson/direct_current_3d_inversion.ui.json index d2312fde..a87752ae 100644 --- a/simpeg_drivers-assets/uijson/direct_current_3d_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/direct_current_3d_inversion.ui.json @@ -4,11 +4,9 @@ "icon": "PotentialElectrode", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.electricals.direct_current.three_dimensions.inversion", "geoh5": "", "monitoring_directory": "", - "inversion_type": "direct current 3d", - "physical_property": "conductivity", "data_object": { "main": true, "group": "Data", diff --git a/simpeg_drivers-assets/uijson/fdem1d_forward.ui.json b/simpeg_drivers-assets/uijson/fdem1d_forward.ui.json index aa9da759..d8c38f83 100644 --- a/simpeg_drivers-assets/uijson/fdem1d_forward.ui.json +++ b/simpeg_drivers-assets/uijson/fdem1d_forward.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "fdem 1d", - "physical_property": "conductivity", "data_object": { "main": true, "group": "Survey", diff --git a/simpeg_drivers-assets/uijson/fdem1d_inversion.ui.json b/simpeg_drivers-assets/uijson/fdem1d_inversion.ui.json index 72f57026..0c40fe26 100644 --- a/simpeg_drivers-assets/uijson/fdem1d_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/fdem1d_inversion.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "fdem 1d", - "physical_property": "conductivity", "data_object": { "main": true, "group": "Data", diff --git a/simpeg_drivers-assets/uijson/fdem_forward.ui.json b/simpeg_drivers-assets/uijson/fdem_forward.ui.json index 41cca911..103c7f1b 100644 --- a/simpeg_drivers-assets/uijson/fdem_forward.ui.json +++ b/simpeg_drivers-assets/uijson/fdem_forward.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "fdem", - "physical_property": "conductivity", "data_object": { "main": true, "group": "Survey", diff --git a/simpeg_drivers-assets/uijson/fdem_inversion.ui.json b/simpeg_drivers-assets/uijson/fdem_inversion.ui.json index 8690f3d6..f42e6a7a 100644 --- a/simpeg_drivers-assets/uijson/fdem_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/fdem_inversion.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "fdem", - "physical_property": "conductivity", "data_object": { "main": true, "group": "Data", diff --git a/simpeg_drivers-assets/uijson/induced_polarization_3d_forward.ui.json b/simpeg_drivers-assets/uijson/induced_polarization_3d_forward.ui.json index 785a7469..d38ef876 100644 --- a/simpeg_drivers-assets/uijson/induced_polarization_3d_forward.ui.json +++ b/simpeg_drivers-assets/uijson/induced_polarization_3d_forward.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "induced polarization 3d", - "physical_property": "chargeability", "data_object": { "main": true, "group": "Survey", diff --git a/simpeg_drivers-assets/uijson/joint_cross_gradient_inversion.ui.json b/simpeg_drivers-assets/uijson/joint_cross_gradient_inversion.ui.json index 7d6efe35..ef25c89c 100644 --- a/simpeg_drivers-assets/uijson/joint_cross_gradient_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/joint_cross_gradient_inversion.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "joint cross gradient", - "physical_property": "", "group_a": { "main": true, "group": "Joint", diff --git a/simpeg_drivers-assets/uijson/magnetic_vector_inversion.ui.json b/simpeg_drivers-assets/uijson/magnetic_vector_inversion.ui.json index 76ee383f..2e370514 100644 --- a/simpeg_drivers-assets/uijson/magnetic_vector_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/magnetic_vector_inversion.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "magnetic vector", - "physical_property": "susceptibility", "inducing_field_declination": { "min": -180.0, "max": 180.0, diff --git a/simpeg_drivers-assets/uijson/magnetotellurics_forward.ui.json b/simpeg_drivers-assets/uijson/magnetotellurics_forward.ui.json index 670ec26e..8bb10908 100644 --- a/simpeg_drivers-assets/uijson/magnetotellurics_forward.ui.json +++ b/simpeg_drivers-assets/uijson/magnetotellurics_forward.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "magnetotellurics", - "physical_property": "conductivity", "data_object": { "main": true, "group": "Survey", diff --git a/simpeg_drivers-assets/uijson/magnetotellurics_inversion.ui.json b/simpeg_drivers-assets/uijson/magnetotellurics_inversion.ui.json index b705e166..42b4ab45 100644 --- a/simpeg_drivers-assets/uijson/magnetotellurics_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/magnetotellurics_inversion.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "magnetotellurics", - "physical_property": "conductivity", "data_object": { "main": true, "group": "Data", diff --git a/simpeg_drivers-assets/uijson/plate_simulation.ui.json b/simpeg_drivers-assets/uijson/plate_simulation.ui.json index ac0ff572..e12231a8 100644 --- a/simpeg_drivers-assets/uijson/plate_simulation.ui.json +++ b/simpeg_drivers-assets/uijson/plate_simulation.ui.json @@ -7,7 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "plate simulation", "simulation": { "main": true, "label": "SimPEG group", diff --git a/simpeg_drivers-assets/uijson/tdem1d_inversion.ui.json b/simpeg_drivers-assets/uijson/tdem1d_inversion.ui.json index 4de73b45..8d53af4e 100644 --- a/simpeg_drivers-assets/uijson/tdem1d_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/tdem1d_inversion.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "tdem 1d", - "physical_property": "conductivity", "data_object": { "main": true, "group": "Data", diff --git a/simpeg_drivers-assets/uijson/tdem_inversion.ui.json b/simpeg_drivers-assets/uijson/tdem_inversion.ui.json index f62eb44c..375361ed 100644 --- a/simpeg_drivers-assets/uijson/tdem_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/tdem_inversion.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "tdem", - "physical_property": "conductivity", "data_object": { "main": true, "group": "Data", diff --git a/simpeg_drivers-assets/uijson/tipper_forward.ui.json b/simpeg_drivers-assets/uijson/tipper_forward.ui.json index 492b467c..7b15db75 100644 --- a/simpeg_drivers-assets/uijson/tipper_forward.ui.json +++ b/simpeg_drivers-assets/uijson/tipper_forward.ui.json @@ -7,8 +7,6 @@ "run_command": "simpeg_drivers.driver", "geoh5": "", "monitoring_directory": "", - "inversion_type": "tipper", - "physical_property": "conductivity", "data_object": { "main": true, "group": "Survey", From 92be12239d83db09d8548782f751e4676fb47a4f Mon Sep 17 00:00:00 2001 From: domfournier Date: Thu, 19 Mar 2026 15:03:47 -0700 Subject: [PATCH 05/18] Split dc forward and inversion drivers --- simpeg_drivers/components/__init__.py | 1 - .../three_dimensions/__init__.py | 6 +++--- .../direct_current/three_dimensions/forward.py | 18 +++++++++--------- .../three_dimensions/inversion.py | 18 +++++++++--------- .../direct_current/three_dimensions/options.py | 8 ++++++-- simpeg_drivers/plate_simulation/options.py | 3 --- tests/models_test.py | 2 +- .../driver_joint_cross_gradient_test.py | 6 ++---- tests/run_tests/driver_joint_surveys_test.py | 2 +- 9 files changed, 31 insertions(+), 33 deletions(-) diff --git a/simpeg_drivers/components/__init__.py b/simpeg_drivers/components/__init__.py index ef79c165..c964c119 100644 --- a/simpeg_drivers/components/__init__.py +++ b/simpeg_drivers/components/__init__.py @@ -18,4 +18,3 @@ from .meshes import InversionMesh from .models import InversionModel, InversionModelCollection from .topography import InversionTopography -from .windows import InversionWindow diff --git a/simpeg_drivers/electricals/direct_current/three_dimensions/__init__.py b/simpeg_drivers/electricals/direct_current/three_dimensions/__init__.py index 77573459..8f111df9 100644 --- a/simpeg_drivers/electricals/direct_current/three_dimensions/__init__.py +++ b/simpeg_drivers/electricals/direct_current/three_dimensions/__init__.py @@ -8,8 +8,8 @@ # ' # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +# pylint: disable=unused-import +from .forward import DC3DForwardDriver +from .inversion import DC3DInversionDriver from .options import DC3DForwardOptions, DC3DInversionOptions - -# pylint: disable=unused-import -# flake8: noqa diff --git a/simpeg_drivers/electricals/direct_current/three_dimensions/forward.py b/simpeg_drivers/electricals/direct_current/three_dimensions/forward.py index db554c26..1eee19e1 100644 --- a/simpeg_drivers/electricals/direct_current/three_dimensions/forward.py +++ b/simpeg_drivers/electricals/direct_current/three_dimensions/forward.py @@ -11,20 +11,20 @@ from __future__ import annotations -from simpeg_drivers.driver import InversionDriver +import sys +from pathlib import Path -from .options import DC3DForwardOptions, DC3DInversionOptions +from simpeg_drivers.driver import ForwardDriver +from .options import DC3DForwardOptions -class DC3DForwardDriver(InversionDriver): + +class DC3DForwardDriver(ForwardDriver): """Direct Current 3D forward driver.""" _params_class = DC3DForwardOptions - _validation = None - -class DC3DInversionDriver(InversionDriver): - """Direct Current 3D inversion driver.""" - _params_class = DC3DInversionOptions - _validation = None +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + DC3DForwardDriver.start_dask_run(file) diff --git a/simpeg_drivers/electricals/direct_current/three_dimensions/inversion.py b/simpeg_drivers/electricals/direct_current/three_dimensions/inversion.py index db554c26..807c5abd 100644 --- a/simpeg_drivers/electricals/direct_current/three_dimensions/inversion.py +++ b/simpeg_drivers/electricals/direct_current/three_dimensions/inversion.py @@ -11,20 +11,20 @@ from __future__ import annotations -from simpeg_drivers.driver import InversionDriver - -from .options import DC3DForwardOptions, DC3DInversionOptions - +import sys +from pathlib import Path -class DC3DForwardDriver(InversionDriver): - """Direct Current 3D forward driver.""" +from simpeg_drivers.driver import InversionDriver - _params_class = DC3DForwardOptions - _validation = None +from .options import DC3DInversionOptions class DC3DInversionDriver(InversionDriver): """Direct Current 3D inversion driver.""" _params_class = DC3DInversionOptions - _validation = None + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + DC3DInversionDriver.start_dask_run(file) diff --git a/simpeg_drivers/electricals/direct_current/three_dimensions/options.py b/simpeg_drivers/electricals/direct_current/three_dimensions/options.py index 1710bb45..728fa663 100644 --- a/simpeg_drivers/electricals/direct_current/three_dimensions/options.py +++ b/simpeg_drivers/electricals/direct_current/three_dimensions/options.py @@ -36,7 +36,9 @@ class DC3DForwardOptions(BaseForwardOptions): default_ui_json: ClassVar[Path] = ( assets_path() / "uijson/direct_current_3d_forward.ui.json" ) - + run_command: str = ( + "simpeg_drivers.electricals.direct_current.three_dimensions.forward" + ) title: str = "Direct Current 3D Forward" physical_property: str = "conductivity" inversion_type: str = "direct current 3d" @@ -58,7 +60,9 @@ class DC3DInversionOptions(BaseInversionOptions): default_ui_json: ClassVar[Path] = ( assets_path() / "uijson/direct_current_3d_inversion.ui.json" ) - + run_command: str = ( + "simpeg_drivers.electricals.direct_current.three_dimensions.inversion" + ) title: str = "Direct Current 3D Inversion" physical_property: str = "conductivity" inversion_type: str = "direct current 3d" diff --git a/simpeg_drivers/plate_simulation/options.py b/simpeg_drivers/plate_simulation/options.py index c3950b29..2a4d3517 100644 --- a/simpeg_drivers/plate_simulation/options.py +++ b/simpeg_drivers/plate_simulation/options.py @@ -144,9 +144,6 @@ def simulation_parameters(self) -> BaseForwardOptions: """ simulation_options = deepcopy(self.simulation.options) simulation_options["geoh5"] = self.geoh5 - simulation_options["forward_only"] = ( - True # TODO remove this when mechanics use ForwardOptions - ) input_file = InputFile(ui_json=simulation_options, validate=False) if input_file.ui_json is None: diff --git a/tests/models_test.py b/tests/models_test.py index 1b5d944d..c5c0a328 100644 --- a/tests/models_test.py +++ b/tests/models_test.py @@ -22,7 +22,7 @@ InversionModel, InversionModelCollection, ) -from simpeg_drivers.electricals.direct_current.three_dimensions.driver import ( +from simpeg_drivers.electricals.direct_current.three_dimensions import ( DC3DForwardDriver, ) from simpeg_drivers.electricals.direct_current.three_dimensions.options import ( diff --git a/tests/run_tests/driver_joint_cross_gradient_test.py b/tests/run_tests/driver_joint_cross_gradient_test.py index 2ad636a6..1ec9b241 100644 --- a/tests/run_tests/driver_joint_cross_gradient_test.py +++ b/tests/run_tests/driver_joint_cross_gradient_test.py @@ -15,12 +15,10 @@ from geoh5py.workspace import Workspace from simpeg_drivers.electricals.direct_current.three_dimensions import ( - DC3DForwardOptions, - DC3DInversionOptions, -) -from simpeg_drivers.electricals.direct_current.three_dimensions.driver import ( DC3DForwardDriver, + DC3DForwardOptions, DC3DInversionDriver, + DC3DInversionOptions, ) from simpeg_drivers.joint.joint_cross_gradient import JointCrossGradientOptions from simpeg_drivers.joint.joint_cross_gradient.driver import JointCrossGradientDriver diff --git a/tests/run_tests/driver_joint_surveys_test.py b/tests/run_tests/driver_joint_surveys_test.py index 9aa403c8..db405174 100644 --- a/tests/run_tests/driver_joint_surveys_test.py +++ b/tests/run_tests/driver_joint_surveys_test.py @@ -15,7 +15,7 @@ from geoh5py.workspace import Workspace from simpeg.directives import SaveModelGeoH5, SavePropertyGroup -from simpeg_drivers.electricals.direct_current.three_dimensions.driver import ( +from simpeg_drivers.electricals.direct_current.three_dimensions.inversion import ( DC3DInversionDriver, ) from simpeg_drivers.electricals.direct_current.three_dimensions.options import ( From 038f26a1a595dc5a833ad0d996b133add10493dc Mon Sep 17 00:00:00 2001 From: domfournier Date: Thu, 19 Mar 2026 16:24:23 -0700 Subject: [PATCH 06/18] Split all remaining drivers --- simpeg_drivers/driver.py | 12 +- simpeg_drivers/electricals/base_2d.py | 4 +- .../direct_current/two_dimensions/__init__.py | 3 +- .../two_dimensions/{driver.py => forward.py} | 15 +- .../two_dimensions/inversion.py | 31 ++++ .../three_dimensions/__init__.py | 3 +- .../three_dimensions/forward.py | 30 ++++ .../{driver.py => inversion.py} | 21 ++- .../two_dimensions/__init__.py | 3 +- .../two_dimensions/{driver.py => forward.py} | 18 +- .../two_dimensions/inversion.py | 31 ++++ .../electromagnetics/base_1d_driver.py | 20 +-- .../frequency_domain/__init__.py | 7 + .../frequency_domain/forward.py | 33 ++++ .../{driver.py => inversion.py} | 22 +-- .../frequency_domain_1d/__init__.py | 7 + .../{driver.py => forward.py} | 18 +- .../frequency_domain_1d/inversion.py | 31 ++++ .../electromagnetics/time_domain/__init__.py | 8 + .../electromagnetics/time_domain/forward.py | 30 ++++ .../time_domain/{driver.py => inversion.py} | 22 +-- .../time_domain_1d/__init__.py | 7 + .../time_domain_1d/{driver.py => forward.py} | 20 +-- .../time_domain_1d/inversion.py | 31 ++++ .../apparent_conductivity/__init__.py | 8 + .../apparent_conductivity/forward.py | 30 ++++ .../{driver.py => inversion.py} | 18 +- .../magnetotellurics/__init__.py | 9 +- .../magnetotellurics/forward.py | 30 ++++ .../{driver.py => inversion.py} | 16 +- .../natural_sources/tipper/__init__.py | 7 +- .../natural_sources/tipper/forward.py | 30 ++++ .../tipper/{driver.py => inversion.py} | 16 +- simpeg_drivers/plate_simulation/driver.py | 12 +- .../plate_simulation/match/driver.py | 18 +- .../potential_fields/gravity/__init__.py | 7 +- .../potential_fields/gravity/forward.py | 30 ++++ .../gravity/{driver.py => inversion.py} | 18 +- .../potential_fields/gravity/uijson.py | 159 ------------------ .../magnetic_scalar/__init__.py | 7 +- .../magnetic_scalar/forward.py | 30 ++++ .../{driver.py => inversion.py} | 20 +-- .../magnetic_vector/__init__.py | 7 +- .../magnetic_vector/forward.py | 30 ++++ .../{driver.py => inversion.py} | 18 +- .../magnetic_vector/options.py | 4 +- 46 files changed, 628 insertions(+), 323 deletions(-) rename simpeg_drivers/electricals/direct_current/two_dimensions/{driver.py => forward.py} (77%) create mode 100644 simpeg_drivers/electricals/direct_current/two_dimensions/inversion.py create mode 100644 simpeg_drivers/electricals/induced_polarization/three_dimensions/forward.py rename simpeg_drivers/electricals/induced_polarization/three_dimensions/{driver.py => inversion.py} (78%) rename simpeg_drivers/electricals/induced_polarization/two_dimensions/{driver.py => forward.py} (77%) create mode 100644 simpeg_drivers/electricals/induced_polarization/two_dimensions/inversion.py create mode 100644 simpeg_drivers/electromagnetics/frequency_domain/forward.py rename simpeg_drivers/electromagnetics/frequency_domain/{driver.py => inversion.py} (77%) rename simpeg_drivers/electromagnetics/frequency_domain_1d/{driver.py => forward.py} (77%) create mode 100644 simpeg_drivers/electromagnetics/frequency_domain_1d/inversion.py create mode 100644 simpeg_drivers/electromagnetics/time_domain/forward.py rename simpeg_drivers/electromagnetics/time_domain/{driver.py => inversion.py} (75%) rename simpeg_drivers/electromagnetics/time_domain_1d/{driver.py => forward.py} (72%) create mode 100644 simpeg_drivers/electromagnetics/time_domain_1d/inversion.py create mode 100644 simpeg_drivers/natural_sources/apparent_conductivity/forward.py rename simpeg_drivers/natural_sources/apparent_conductivity/{driver.py => inversion.py} (79%) create mode 100644 simpeg_drivers/natural_sources/magnetotellurics/forward.py rename simpeg_drivers/natural_sources/magnetotellurics/{driver.py => inversion.py} (84%) create mode 100644 simpeg_drivers/natural_sources/tipper/forward.py rename simpeg_drivers/natural_sources/tipper/{driver.py => inversion.py} (83%) create mode 100644 simpeg_drivers/potential_fields/gravity/forward.py rename simpeg_drivers/potential_fields/gravity/{driver.py => inversion.py} (80%) delete mode 100644 simpeg_drivers/potential_fields/gravity/uijson.py create mode 100644 simpeg_drivers/potential_fields/magnetic_scalar/forward.py rename simpeg_drivers/potential_fields/magnetic_scalar/{driver.py => inversion.py} (76%) create mode 100644 simpeg_drivers/potential_fields/magnetic_vector/forward.py rename simpeg_drivers/potential_fields/magnetic_vector/{driver.py => inversion.py} (74%) diff --git a/simpeg_drivers/driver.py b/simpeg_drivers/driver.py index c1390137..b25fba1b 100644 --- a/simpeg_drivers/driver.py +++ b/simpeg_drivers/driver.py @@ -490,16 +490,20 @@ def run(self): directive.write(1) @classmethod - def start_dask_run(cls, json_path: Path): + def start_dask_run( + cls, json_path: Path, n_workers: int | None = None, n_threads: int | None = None + ): """ Sets Dask config settings. :param json_path: Path to input file (.ui.json) for the application. + :param n_workers: Number of workers to use. + :param n_threads: Number of threads to use. """ ui_json = load_ui_json_as_dict(json_path) - n_workers = (ui_json.get("n_workers", None),) - n_threads = (ui_json.get("n_threads", None),) + n_workers = (ui_json.get("n_workers", n_workers),) + n_threads = (ui_json.get("n_threads", n_threads),) save_report = (ui_json.get("performance_report", False),) distributed_process = ( @@ -927,7 +931,7 @@ def validate_workers(client, workers: list[tuple[str]] | None) -> list[tuple[str if __name__ == "__main__": file = Path(sys.argv[1]).resolve() - # TODO - Deprecate in favour of run_command to direct module + # TODO - Deprecate in favor of run_command to direct module # Need to know the driver class before starting dask input_file = load_ui_json_as_dict(file) driver_class = from_input_file(input_file) diff --git a/simpeg_drivers/electricals/base_2d.py b/simpeg_drivers/electricals/base_2d.py index b840de7b..c2307c05 100644 --- a/simpeg_drivers/electricals/base_2d.py +++ b/simpeg_drivers/electricals/base_2d.py @@ -19,7 +19,7 @@ from pydantic import field_validator, model_validator from simpeg_drivers.components.meshes import InversionMesh -from simpeg_drivers.driver import InversionDriver +from simpeg_drivers.driver import BaseDriver from simpeg_drivers.options import ( CoreOptions, DrapeModelOptions, @@ -125,7 +125,7 @@ def selected_parts(self) -> list[int]: return self._selected_parts -class Base2DDriver(InversionDriver): +class Base2DDriver(BaseDriver): """ Base class for 2D DC and IP forward and inversion drivers. diff --git a/simpeg_drivers/electricals/direct_current/two_dimensions/__init__.py b/simpeg_drivers/electricals/direct_current/two_dimensions/__init__.py index f297c30b..05a1d438 100644 --- a/simpeg_drivers/electricals/direct_current/two_dimensions/__init__.py +++ b/simpeg_drivers/electricals/direct_current/two_dimensions/__init__.py @@ -8,7 +8,8 @@ # ' # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' - +from .forward import DC2DForwardDriver +from .inversion import DC2DInversionDriver from .options import DC2DForwardOptions, DC2DInversionOptions diff --git a/simpeg_drivers/electricals/direct_current/two_dimensions/driver.py b/simpeg_drivers/electricals/direct_current/two_dimensions/forward.py similarity index 77% rename from simpeg_drivers/electricals/direct_current/two_dimensions/driver.py rename to simpeg_drivers/electricals/direct_current/two_dimensions/forward.py index 5642d81a..0ebbe7a2 100644 --- a/simpeg_drivers/electricals/direct_current/two_dimensions/driver.py +++ b/simpeg_drivers/electricals/direct_current/two_dimensions/forward.py @@ -11,18 +11,21 @@ from __future__ import annotations +import sys +from pathlib import Path + +from simpeg_drivers.driver import ForwardDriver from simpeg_drivers.electricals.base_2d import Base2DDriver -from .options import DC2DForwardOptions, DC2DInversionOptions +from .options import DC2DForwardOptions -class DC2DForwardDriver(Base2DDriver): +class DC2DForwardDriver(ForwardDriver, Base2DDriver): """Direct Current 2D forward driver.""" _params_class = DC2DForwardOptions -class DC2DInversionDriver(Base2DDriver): - """Direct Current 2D inversion driver.""" - - _params_class = DC2DInversionOptions +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + DC2DForwardDriver.start_dask_run(file) diff --git a/simpeg_drivers/electricals/direct_current/two_dimensions/inversion.py b/simpeg_drivers/electricals/direct_current/two_dimensions/inversion.py new file mode 100644 index 00000000..e6d339c7 --- /dev/null +++ b/simpeg_drivers/electricals/direct_current/two_dimensions/inversion.py @@ -0,0 +1,31 @@ +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +# Copyright (c) 2023-2026 Mira Geoscience Ltd. ' +# ' +# This file is part of simpeg-drivers package. ' +# ' +# simpeg-drivers is distributed under the terms and conditions of the MIT License ' +# (see LICENSE file at the root of this source code package). ' +# ' +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + + +from __future__ import annotations + +import sys +from pathlib import Path + +from simpeg_drivers.driver import InversionDriver +from simpeg_drivers.electricals.base_2d import Base2DDriver + +from .options import DC2DInversionOptions + + +class DC2DInversionDriver(InversionDriver, Base2DDriver): + """Direct Current 2D inversion driver.""" + + _params_class = DC2DInversionOptions + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + DC2DInversionDriver.start_dask_run(file) diff --git a/simpeg_drivers/electricals/induced_polarization/three_dimensions/__init__.py b/simpeg_drivers/electricals/induced_polarization/three_dimensions/__init__.py index 902b81ca..e1a7af85 100644 --- a/simpeg_drivers/electricals/induced_polarization/three_dimensions/__init__.py +++ b/simpeg_drivers/electricals/induced_polarization/three_dimensions/__init__.py @@ -8,7 +8,8 @@ # ' # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' - +from .forward import IP3DForwardDriver +from .inversion import IP3DInversionDriver from .options import ( IP3DForwardOptions, IP3DInversionOptions, diff --git a/simpeg_drivers/electricals/induced_polarization/three_dimensions/forward.py b/simpeg_drivers/electricals/induced_polarization/three_dimensions/forward.py new file mode 100644 index 00000000..57469334 --- /dev/null +++ b/simpeg_drivers/electricals/induced_polarization/three_dimensions/forward.py @@ -0,0 +1,30 @@ +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +# Copyright (c) 2023-2026 Mira Geoscience Ltd. ' +# ' +# This file is part of simpeg-drivers package. ' +# ' +# simpeg-drivers is distributed under the terms and conditions of the MIT License ' +# (see LICENSE file at the root of this source code package). ' +# ' +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + + +from __future__ import annotations + +import sys +from pathlib import Path + +from simpeg_drivers.driver import ForwardDriver + +from .options import IP3DForwardOptions + + +class IP3DForwardDriver(ForwardDriver): + """Direct Current 2D forward driver.""" + + _params_class = IP3DForwardOptions + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + IP3DForwardDriver.start_dask_run(file) diff --git a/simpeg_drivers/electricals/induced_polarization/three_dimensions/driver.py b/simpeg_drivers/electricals/induced_polarization/three_dimensions/inversion.py similarity index 78% rename from simpeg_drivers/electricals/induced_polarization/three_dimensions/driver.py rename to simpeg_drivers/electricals/induced_polarization/three_dimensions/inversion.py index b5a652d6..bd6563d4 100644 --- a/simpeg_drivers/electricals/induced_polarization/three_dimensions/driver.py +++ b/simpeg_drivers/electricals/induced_polarization/three_dimensions/inversion.py @@ -11,21 +11,20 @@ from __future__ import annotations -from simpeg_drivers.driver import InversionDriver - -from .options import ( - IP3DForwardOptions, - IP3DInversionOptions, -) - +import sys +from pathlib import Path -class IP3DForwardDriver(InversionDriver): - """Induced Polarization 3D forward driver.""" +from simpeg_drivers.driver import InversionDriver - _params_class = IP3DForwardOptions +from .options import IP3DInversionOptions class IP3DInversionDriver(InversionDriver): - """Induced Polarization 3D inversion driver.""" + """Direct Current 2D inversion driver.""" _params_class = IP3DInversionOptions + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + IP3DInversionDriver.start_dask_run(file) diff --git a/simpeg_drivers/electricals/induced_polarization/two_dimensions/__init__.py b/simpeg_drivers/electricals/induced_polarization/two_dimensions/__init__.py index 2a785f43..3b341585 100644 --- a/simpeg_drivers/electricals/induced_polarization/two_dimensions/__init__.py +++ b/simpeg_drivers/electricals/induced_polarization/two_dimensions/__init__.py @@ -8,7 +8,8 @@ # ' # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' - +from .forward import IP2DForwardDriver +from .inversion import IP2DInversionDriver from .options import ( IP2DForwardOptions, IP2DInversionOptions, diff --git a/simpeg_drivers/electricals/induced_polarization/two_dimensions/driver.py b/simpeg_drivers/electricals/induced_polarization/two_dimensions/forward.py similarity index 77% rename from simpeg_drivers/electricals/induced_polarization/two_dimensions/driver.py rename to simpeg_drivers/electricals/induced_polarization/two_dimensions/forward.py index b1322e92..97a540c8 100644 --- a/simpeg_drivers/electricals/induced_polarization/two_dimensions/driver.py +++ b/simpeg_drivers/electricals/induced_polarization/two_dimensions/forward.py @@ -11,21 +11,21 @@ from __future__ import annotations +import sys +from pathlib import Path + +from simpeg_drivers.driver import ForwardDriver from simpeg_drivers.electricals.base_2d import Base2DDriver -from .options import ( - IP2DForwardOptions, - IP2DInversionOptions, -) +from .options import IP2DForwardOptions -class IP2DForwardDriver(Base2DDriver): +class IP2DForwardDriver(ForwardDriver, Base2DDriver): """Induced Polarization 2D forward driver.""" _params_class = IP2DForwardOptions -class IP2DInversionDriver(Base2DDriver): - """Induced Polarization 2D inversion driver.""" - - _params_class = IP2DInversionOptions +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + IP2DForwardDriver.start_dask_run(file) diff --git a/simpeg_drivers/electricals/induced_polarization/two_dimensions/inversion.py b/simpeg_drivers/electricals/induced_polarization/two_dimensions/inversion.py new file mode 100644 index 00000000..baa40e49 --- /dev/null +++ b/simpeg_drivers/electricals/induced_polarization/two_dimensions/inversion.py @@ -0,0 +1,31 @@ +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +# Copyright (c) 2023-2026 Mira Geoscience Ltd. ' +# ' +# This file is part of simpeg-drivers package. ' +# ' +# simpeg-drivers is distributed under the terms and conditions of the MIT License ' +# (see LICENSE file at the root of this source code package). ' +# ' +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + + +from __future__ import annotations + +import sys +from pathlib import Path + +from simpeg_drivers.driver import InversionDriver +from simpeg_drivers.electricals.base_2d import Base2DDriver + +from .options import IP2DInversionOptions + + +class IP2DInversionDriver(InversionDriver, Base2DDriver): + """Induced Polarization 2D inversion driver.""" + + _params_class = IP2DInversionOptions + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + IP2DInversionDriver.start_dask_run(file) diff --git a/simpeg_drivers/electromagnetics/base_1d_driver.py b/simpeg_drivers/electromagnetics/base_1d_driver.py index 12730f0b..adcc01db 100644 --- a/simpeg_drivers/electromagnetics/base_1d_driver.py +++ b/simpeg_drivers/electromagnetics/base_1d_driver.py @@ -18,6 +18,7 @@ import numpy as np from discretize import TensorMesh from discretize.utils import mesh_utils +from geoapps_utils.run import load_ui_json_as_dict from geoapps_utils.utils.locations import topo_drape_elevation from geoh5py import Workspace from geoh5py.shared.merging.drape_model import DrapeModelMerger @@ -25,14 +26,14 @@ from simpeg_drivers.components.factories import SimulationFactory from simpeg_drivers.components.meshes import InversionMesh -from simpeg_drivers.driver import InversionDriver +from simpeg_drivers.driver import BaseDriver from simpeg_drivers.utils.utils import xyz_2_drape_model logger = getLogger(__name__) -class Base1DDriver(InversionDriver): +class Base1DDriver(BaseDriver): """Base 1D driver for electromagnetic simulations.""" _params_class = None @@ -142,14 +143,15 @@ def workers(self): @classmethod def start_dask_run( - cls, - json_path: Path, - n_workers: int | None = None, - n_threads: int | None = None, - save_report: bool = True, + cls, json_path: Path, n_workers: int | None = None, n_threads: int | None = None ): """Overload configurations of BaseDriver Dask config settings.""" # Force distributed on 1D problems + ui_json = load_ui_json_as_dict(json_path) + + n_workers = (ui_json.get("n_workers", None),) + n_threads = (ui_json.get("n_threads", None),) + if n_workers is None: cpu_count = multiprocessing.cpu_count() @@ -160,6 +162,4 @@ def start_dask_run( n_workers = cpu_count // n_threads - super().start_dask_run( - json_path, n_workers=n_workers, n_threads=n_threads, save_report=save_report - ) + super().start_dask_run(json_path, n_workers=n_workers, n_threads=n_threads) diff --git a/simpeg_drivers/electromagnetics/frequency_domain/__init__.py b/simpeg_drivers/electromagnetics/frequency_domain/__init__.py index df32b204..ce3a31d1 100644 --- a/simpeg_drivers/electromagnetics/frequency_domain/__init__.py +++ b/simpeg_drivers/electromagnetics/frequency_domain/__init__.py @@ -7,3 +7,10 @@ # (see LICENSE file at the root of this source code package). ' # ' # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +from .forward import FDEMForwardDriver +from .inversion import FDEMInversionDriver +from .options import ( + FDEMForwardOptions, + FDEMInversionOptions, +) diff --git a/simpeg_drivers/electromagnetics/frequency_domain/forward.py b/simpeg_drivers/electromagnetics/frequency_domain/forward.py new file mode 100644 index 00000000..f5b07edb --- /dev/null +++ b/simpeg_drivers/electromagnetics/frequency_domain/forward.py @@ -0,0 +1,33 @@ +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +# Copyright (c) 2023-2026 Mira Geoscience Ltd. ' +# ' +# This file is part of simpeg-drivers package. ' +# ' +# simpeg-drivers is distributed under the terms and conditions of the MIT License ' +# (see LICENSE file at the root of this source code package). ' +# ' +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + + +from __future__ import annotations + +import sys +from pathlib import Path + +from simpeg_drivers.driver import ForwardDriver + +from .options import FDEMForwardOptions + + +class FDEMForwardDriver(ForwardDriver): + """Frequency Domain Electromagnetic forward driver.""" + + _params_class = FDEMForwardOptions + + def __init__(self, params: FDEMForwardOptions): + super().__init__(params) + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + FDEMForwardDriver.start_dask_run(file) diff --git a/simpeg_drivers/electromagnetics/frequency_domain/driver.py b/simpeg_drivers/electromagnetics/frequency_domain/inversion.py similarity index 77% rename from simpeg_drivers/electromagnetics/frequency_domain/driver.py rename to simpeg_drivers/electromagnetics/frequency_domain/inversion.py index 30808eb2..96ff4cf7 100644 --- a/simpeg_drivers/electromagnetics/frequency_domain/driver.py +++ b/simpeg_drivers/electromagnetics/frequency_domain/inversion.py @@ -11,24 +11,20 @@ from __future__ import annotations -from simpeg_drivers.driver import InversionDriver - -from .options import ( - FDEMForwardOptions, - FDEMInversionOptions, -) - - -class FDEMForwardDriver(InversionDriver): - """Frequency Domain Electromagnetic forward driver.""" +import sys +from pathlib import Path - _params_class = FDEMForwardOptions +from simpeg_drivers.driver import InversionDriver - def __init__(self, params: FDEMForwardOptions): - super().__init__(params) +from .options import FDEMInversionOptions class FDEMInversionDriver(InversionDriver): """Frequency Domain Electromagnetic inversion driver.""" _params_class = FDEMInversionOptions + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + FDEMInversionDriver.start_dask_run(file) diff --git a/simpeg_drivers/electromagnetics/frequency_domain_1d/__init__.py b/simpeg_drivers/electromagnetics/frequency_domain_1d/__init__.py index df32b204..3165311d 100644 --- a/simpeg_drivers/electromagnetics/frequency_domain_1d/__init__.py +++ b/simpeg_drivers/electromagnetics/frequency_domain_1d/__init__.py @@ -7,3 +7,10 @@ # (see LICENSE file at the root of this source code package). ' # ' # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +from .forward import FDEM1DForwardDriver +from .inversion import FDEM1DInversionDriver +from .options import ( + FDEM1DForwardOptions, + FDEM1DInversionOptions, +) diff --git a/simpeg_drivers/electromagnetics/frequency_domain_1d/driver.py b/simpeg_drivers/electromagnetics/frequency_domain_1d/forward.py similarity index 77% rename from simpeg_drivers/electromagnetics/frequency_domain_1d/driver.py rename to simpeg_drivers/electromagnetics/frequency_domain_1d/forward.py index 4b3d25ac..35c51ea3 100644 --- a/simpeg_drivers/electromagnetics/frequency_domain_1d/driver.py +++ b/simpeg_drivers/electromagnetics/frequency_domain_1d/forward.py @@ -11,21 +11,21 @@ from __future__ import annotations +import sys +from pathlib import Path + +from simpeg_drivers.driver import ForwardDriver from simpeg_drivers.electromagnetics.base_1d_driver import Base1DDriver -from .options import ( - FDEM1DForwardOptions, - FDEM1DInversionOptions, -) +from .options import FDEM1DForwardOptions -class FDEM1DForwardDriver(Base1DDriver): +class FDEM1DForwardDriver(ForwardDriver, Base1DDriver): """Frequency Domain 1D Electromagnetic forward driver.""" _params_class = FDEM1DForwardOptions -class FDEM1DInversionDriver(Base1DDriver): - """Frequency Domain 1D Electromagnetic inversion driver.""" - - _params_class = FDEM1DInversionOptions +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + FDEM1DForwardDriver.start_dask_run(file) diff --git a/simpeg_drivers/electromagnetics/frequency_domain_1d/inversion.py b/simpeg_drivers/electromagnetics/frequency_domain_1d/inversion.py new file mode 100644 index 00000000..4222f895 --- /dev/null +++ b/simpeg_drivers/electromagnetics/frequency_domain_1d/inversion.py @@ -0,0 +1,31 @@ +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +# Copyright (c) 2023-2026 Mira Geoscience Ltd. ' +# ' +# This file is part of simpeg-drivers package. ' +# ' +# simpeg-drivers is distributed under the terms and conditions of the MIT License ' +# (see LICENSE file at the root of this source code package). ' +# ' +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + + +from __future__ import annotations + +import sys +from pathlib import Path + +from simpeg_drivers.driver import InversionDriver +from simpeg_drivers.electromagnetics.base_1d_driver import Base1DDriver + +from .options import FDEM1DInversionOptions + + +class FDEM1DInversionDriver(InversionDriver, Base1DDriver): + """Frequency Domain 1D Electromagnetic inversion driver.""" + + _params_class = FDEM1DInversionOptions + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + FDEM1DInversionDriver.start_dask_run(file) diff --git a/simpeg_drivers/electromagnetics/time_domain/__init__.py b/simpeg_drivers/electromagnetics/time_domain/__init__.py index df32b204..b830c49c 100644 --- a/simpeg_drivers/electromagnetics/time_domain/__init__.py +++ b/simpeg_drivers/electromagnetics/time_domain/__init__.py @@ -7,3 +7,11 @@ # (see LICENSE file at the root of this source code package). ' # ' # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + + +from .forward import TDEMForwardDriver +from .inversion import TDEMInversionDriver +from .options import ( + TDEMForwardOptions, + TDEMInversionOptions, +) diff --git a/simpeg_drivers/electromagnetics/time_domain/forward.py b/simpeg_drivers/electromagnetics/time_domain/forward.py new file mode 100644 index 00000000..f3376f29 --- /dev/null +++ b/simpeg_drivers/electromagnetics/time_domain/forward.py @@ -0,0 +1,30 @@ +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +# Copyright (c) 2023-2026 Mira Geoscience Ltd. ' +# ' +# This file is part of simpeg-drivers package. ' +# ' +# simpeg-drivers is distributed under the terms and conditions of the MIT License ' +# (see LICENSE file at the root of this source code package). ' +# ' +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + + +from __future__ import annotations + +import sys +from pathlib import Path + +from simpeg_drivers.driver import ForwardDriver + +from .options import TDEMForwardOptions + + +class TDEMForwardDriver(ForwardDriver): + """Time Domain Electromagnetic forward driver.""" + + _params_class = TDEMForwardOptions + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + TDEMForwardDriver.start_dask_run(file) diff --git a/simpeg_drivers/electromagnetics/time_domain/driver.py b/simpeg_drivers/electromagnetics/time_domain/inversion.py similarity index 75% rename from simpeg_drivers/electromagnetics/time_domain/driver.py rename to simpeg_drivers/electromagnetics/time_domain/inversion.py index 51e3ce3d..4cf61a61 100644 --- a/simpeg_drivers/electromagnetics/time_domain/driver.py +++ b/simpeg_drivers/electromagnetics/time_domain/inversion.py @@ -11,26 +11,20 @@ from __future__ import annotations -import numpy as np -from geoh5py.objects.surveys.electromagnetics.ground_tem import ( - LargeLoopGroundTEMReceivers, -) +import sys +from pathlib import Path from simpeg_drivers.driver import InversionDriver -from .options import ( - TDEMForwardOptions, - TDEMInversionOptions, -) - - -class TDEMForwardDriver(InversionDriver): - """Time Domain Electromagnetic forward driver.""" - - _params_class = TDEMForwardOptions +from .options import TDEMInversionOptions class TDEMInversionDriver(InversionDriver): """Time Domain Electromagnetic inversion driver.""" _params_class = TDEMInversionOptions + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + TDEMInversionDriver.start_dask_run(file) diff --git a/simpeg_drivers/electromagnetics/time_domain_1d/__init__.py b/simpeg_drivers/electromagnetics/time_domain_1d/__init__.py index df32b204..b3a59549 100644 --- a/simpeg_drivers/electromagnetics/time_domain_1d/__init__.py +++ b/simpeg_drivers/electromagnetics/time_domain_1d/__init__.py @@ -7,3 +7,10 @@ # (see LICENSE file at the root of this source code package). ' # ' # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +from .forward import TDEM1DForwardDriver +from .inversion import TDEM1DInversionDriver +from .options import ( + TDEM1DForwardOptions, + TDEM1DInversionOptions, +) diff --git a/simpeg_drivers/electromagnetics/time_domain_1d/driver.py b/simpeg_drivers/electromagnetics/time_domain_1d/forward.py similarity index 72% rename from simpeg_drivers/electromagnetics/time_domain_1d/driver.py rename to simpeg_drivers/electromagnetics/time_domain_1d/forward.py index e44da689..0c7b02b4 100644 --- a/simpeg_drivers/electromagnetics/time_domain_1d/driver.py +++ b/simpeg_drivers/electromagnetics/time_domain_1d/forward.py @@ -11,21 +11,21 @@ from __future__ import annotations +import sys +from pathlib import Path + +from simpeg_drivers.driver import ForwardDriver from simpeg_drivers.electromagnetics.base_1d_driver import Base1DDriver -from .options import ( - TDEM1DForwardOptions, - TDEM1DInversionOptions, -) +from .options import TDEM1DForwardOptions -class TDEM1DForwardDriver(Base1DDriver): - """Time Domain 1D Electromagnetic forward driver.""" +class TDEM1DForwardDriver(ForwardDriver, Base1DDriver): + """Frequency Domain 1D Electromagnetic forward driver.""" _params_class = TDEM1DForwardOptions -class TDEM1DInversionDriver(Base1DDriver): - """Time Domain 1D Electromagnetic inversion driver.""" - - _params_class = TDEM1DInversionOptions +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + TDEM1DForwardDriver.start_dask_run(file) diff --git a/simpeg_drivers/electromagnetics/time_domain_1d/inversion.py b/simpeg_drivers/electromagnetics/time_domain_1d/inversion.py new file mode 100644 index 00000000..bbc7d518 --- /dev/null +++ b/simpeg_drivers/electromagnetics/time_domain_1d/inversion.py @@ -0,0 +1,31 @@ +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +# Copyright (c) 2023-2026 Mira Geoscience Ltd. ' +# ' +# This file is part of simpeg-drivers package. ' +# ' +# simpeg-drivers is distributed under the terms and conditions of the MIT License ' +# (see LICENSE file at the root of this source code package). ' +# ' +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + + +from __future__ import annotations + +import sys +from pathlib import Path + +from simpeg_drivers.driver import InversionDriver +from simpeg_drivers.electromagnetics.base_1d_driver import Base1DDriver + +from .options import TDEM1DInversionOptions + + +class TDEM1DInversionDriver(InversionDriver, Base1DDriver): + """Frequency Domain 1D Electromagnetic inversion driver.""" + + _params_class = TDEM1DInversionOptions + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + TDEM1DInversionDriver.start_dask_run(file) diff --git a/simpeg_drivers/natural_sources/apparent_conductivity/__init__.py b/simpeg_drivers/natural_sources/apparent_conductivity/__init__.py index df32b204..77c30777 100644 --- a/simpeg_drivers/natural_sources/apparent_conductivity/__init__.py +++ b/simpeg_drivers/natural_sources/apparent_conductivity/__init__.py @@ -7,3 +7,11 @@ # (see LICENSE file at the root of this source code package). ' # ' # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + + +from .forward import AppConForwardDriver +from .inversion import AppConInversionDriver +from .options import ( + AppConForwardOptions, + AppConInversionOptions, +) diff --git a/simpeg_drivers/natural_sources/apparent_conductivity/forward.py b/simpeg_drivers/natural_sources/apparent_conductivity/forward.py new file mode 100644 index 00000000..b4550c72 --- /dev/null +++ b/simpeg_drivers/natural_sources/apparent_conductivity/forward.py @@ -0,0 +1,30 @@ +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +# Copyright (c) 2023-2026 Mira Geoscience Ltd. ' +# ' +# This file is part of simpeg-drivers package. ' +# ' +# simpeg-drivers is distributed under the terms and conditions of the MIT License ' +# (see LICENSE file at the root of this source code package). ' +# ' +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + + +from __future__ import annotations + +import sys +from pathlib import Path + +from simpeg_drivers.driver import ForwardDriver + +from .options import AppConForwardOptions + + +class AppConForwardDriver(ForwardDriver): + """Apparent Conductivity forward driver.""" + + _params_class = AppConForwardOptions + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + AppConForwardDriver.start_dask_run(file) diff --git a/simpeg_drivers/natural_sources/apparent_conductivity/driver.py b/simpeg_drivers/natural_sources/apparent_conductivity/inversion.py similarity index 79% rename from simpeg_drivers/natural_sources/apparent_conductivity/driver.py rename to simpeg_drivers/natural_sources/apparent_conductivity/inversion.py index 0235484d..9fb1ff99 100644 --- a/simpeg_drivers/natural_sources/apparent_conductivity/driver.py +++ b/simpeg_drivers/natural_sources/apparent_conductivity/inversion.py @@ -11,18 +11,20 @@ from __future__ import annotations -from simpeg_drivers.driver import InversionDriver - -from .options import AppConForwardOptions, AppConInversionOptions - +import sys +from pathlib import Path -class AppConForwardDriver(InversionDriver): - """AppCon forward driver.""" +from simpeg_drivers.driver import InversionDriver - _params_class = AppConForwardOptions +from .options import AppConInversionOptions class AppConInversionDriver(InversionDriver): - """AppCon inversion driver.""" + """Apparent Conductivity inversion driver.""" _params_class = AppConInversionOptions + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + AppConInversionDriver.start_dask_run(file) diff --git a/simpeg_drivers/natural_sources/magnetotellurics/__init__.py b/simpeg_drivers/natural_sources/magnetotellurics/__init__.py index 755971ec..d073e8c5 100644 --- a/simpeg_drivers/natural_sources/magnetotellurics/__init__.py +++ b/simpeg_drivers/natural_sources/magnetotellurics/__init__.py @@ -8,8 +8,11 @@ # ' # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' - -from .options import MTForwardOptions, MTInversionOptions +from .forward import MTForwardDriver +from .inversion import MTInversionDriver +from .options import ( + MTForwardOptions, + MTInversionOptions, +) # pylint: disable=unused-import -# flake8: noqa diff --git a/simpeg_drivers/natural_sources/magnetotellurics/forward.py b/simpeg_drivers/natural_sources/magnetotellurics/forward.py new file mode 100644 index 00000000..eec4117a --- /dev/null +++ b/simpeg_drivers/natural_sources/magnetotellurics/forward.py @@ -0,0 +1,30 @@ +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +# Copyright (c) 2023-2026 Mira Geoscience Ltd. ' +# ' +# This file is part of simpeg-drivers package. ' +# ' +# simpeg-drivers is distributed under the terms and conditions of the MIT License ' +# (see LICENSE file at the root of this source code package). ' +# ' +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + + +from __future__ import annotations + +import sys +from pathlib import Path + +from simpeg_drivers.driver import ForwardDriver + +from .options import MTForwardOptions + + +class MTForwardDriver(ForwardDriver): + """Magnetotellurics forward driver.""" + + _params_class = MTForwardOptions + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + MTForwardDriver.start_dask_run(file) diff --git a/simpeg_drivers/natural_sources/magnetotellurics/driver.py b/simpeg_drivers/natural_sources/magnetotellurics/inversion.py similarity index 84% rename from simpeg_drivers/natural_sources/magnetotellurics/driver.py rename to simpeg_drivers/natural_sources/magnetotellurics/inversion.py index 9368c348..9c438efe 100644 --- a/simpeg_drivers/natural_sources/magnetotellurics/driver.py +++ b/simpeg_drivers/natural_sources/magnetotellurics/inversion.py @@ -11,18 +11,20 @@ from __future__ import annotations -from simpeg_drivers.driver import InversionDriver - -from .options import MTForwardOptions, MTInversionOptions - +import sys +from pathlib import Path -class MTForwardDriver(InversionDriver): - """Magnetotellurics forward driver.""" +from simpeg_drivers.driver import InversionDriver - _params_class = MTForwardOptions +from .options import MTInversionOptions class MTInversionDriver(InversionDriver): """Magnetotellurics inversion driver.""" _params_class = MTInversionOptions + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + MTInversionDriver.start_dask_run(file) diff --git a/simpeg_drivers/natural_sources/tipper/__init__.py b/simpeg_drivers/natural_sources/tipper/__init__.py index 8dfa91e1..042988b4 100644 --- a/simpeg_drivers/natural_sources/tipper/__init__.py +++ b/simpeg_drivers/natural_sources/tipper/__init__.py @@ -9,7 +9,12 @@ # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' -from .options import TipperForwardOptions, TipperInversionOptions +from .forward import TipperForwardDriver +from .inversion import TipperInversionDriver +from .options import ( + TipperForwardOptions, + TipperInversionOptions, +) # pylint: disable=unused-import # flake8: noqa diff --git a/simpeg_drivers/natural_sources/tipper/forward.py b/simpeg_drivers/natural_sources/tipper/forward.py new file mode 100644 index 00000000..3040c357 --- /dev/null +++ b/simpeg_drivers/natural_sources/tipper/forward.py @@ -0,0 +1,30 @@ +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +# Copyright (c) 2023-2026 Mira Geoscience Ltd. ' +# ' +# This file is part of simpeg-drivers package. ' +# ' +# simpeg-drivers is distributed under the terms and conditions of the MIT License ' +# (see LICENSE file at the root of this source code package). ' +# ' +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + + +from __future__ import annotations + +import sys +from pathlib import Path + +from simpeg_drivers.driver import ForwardDriver + +from .options import TipperForwardOptions + + +class TipperForwardDriver(ForwardDriver): + """Tipper forward driver.""" + + _params_class = TipperForwardOptions + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + TipperForwardDriver.start_dask_run(file) diff --git a/simpeg_drivers/natural_sources/tipper/driver.py b/simpeg_drivers/natural_sources/tipper/inversion.py similarity index 83% rename from simpeg_drivers/natural_sources/tipper/driver.py rename to simpeg_drivers/natural_sources/tipper/inversion.py index d065c7dc..9127918a 100644 --- a/simpeg_drivers/natural_sources/tipper/driver.py +++ b/simpeg_drivers/natural_sources/tipper/inversion.py @@ -11,18 +11,20 @@ from __future__ import annotations -from simpeg_drivers.driver import InversionDriver - -from .options import TipperForwardOptions, TipperInversionOptions - +import sys +from pathlib import Path -class TipperForwardDriver(InversionDriver): - """Tipper forward driver.""" +from simpeg_drivers.driver import InversionDriver - _params_class = TipperForwardOptions +from .options import TipperInversionOptions class TipperInversionDriver(InversionDriver): """Tipper inversion driver.""" _params_class = TipperInversionOptions + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + TipperInversionDriver.start_dask_run(file) diff --git a/simpeg_drivers/plate_simulation/driver.py b/simpeg_drivers/plate_simulation/driver.py index 0ba111bf..87331571 100644 --- a/simpeg_drivers/plate_simulation/driver.py +++ b/simpeg_drivers/plate_simulation/driver.py @@ -23,7 +23,7 @@ from geoh5py.shared.utils import fetch_active_workspace, stringify from grid_apps.octree_creation.driver import OctreeDriver -from simpeg_drivers.driver import BaseDriver, InversionDriver +from simpeg_drivers.driver import BaseDriver, InversionDriver, driver_class_from_name from simpeg_drivers.options import BaseForwardOptions, ModelTypeEnum from simpeg_drivers.plate_simulation.models.events import Anomaly, Erosion, Overburden from simpeg_drivers.plate_simulation.models.parametric import Plate @@ -61,10 +61,16 @@ def __init__( self._simulation_parameters: BaseForwardOptions | None = None self._simulation_driver: InversionDriver | None = None + def simpeg_run(self): + """""" + + def start_message(self): + """""" + logger.info("running the simulation...") + def run(self) -> InversionDriver: """Create octree mesh, fill model, and simulate.""" - logger.info("running the simulation...") with fetch_active_workspace(self.params.geoh5, mode="r+"): self.simulation_driver.run() self.update_monitoring_directory(self.out_group) @@ -111,7 +117,7 @@ def simulation_driver(self) -> InversionDriver: ) self.simulation_parameters.out_group = None - driver_class = InversionDriver.driver_class_from_name( + driver_class = driver_class_from_name( self.simulation_parameters.inversion_type, forward_only=True ) self._simulation_driver = driver_class( diff --git a/simpeg_drivers/plate_simulation/match/driver.py b/simpeg_drivers/plate_simulation/match/driver.py index 471224f8..a6f31229 100644 --- a/simpeg_drivers/plate_simulation/match/driver.py +++ b/simpeg_drivers/plate_simulation/match/driver.py @@ -332,9 +332,13 @@ def start_dask_run( json_path: Path, n_workers: int | None = None, n_threads: int | None = None, - save_report: bool = True, ): """Overload configurations of BaseDriver Dask config settings.""" + ui_json = load_ui_json_as_dict(json_path) + + n_workers = (ui_json.get("n_workers", None),) + n_threads = (ui_json.get("n_threads", None),) + if n_workers is None: cpu_count = multiprocessing.cpu_count() @@ -345,9 +349,7 @@ def start_dask_run( n_workers = cpu_count // n_threads - super().start_dask_run( - json_path, n_workers=n_workers, n_threads=n_threads, save_report=save_report - ) + super().start_dask_run(json_path, n_workers=n_workers, n_threads=n_threads) def run_scores(self, spatial_projection, data) -> tuple[np.ndarray, np.ndarray]: """ @@ -514,10 +516,4 @@ def batch_files_score( if __name__ == "__main__": file = Path(sys.argv[1]).resolve() - input_file = load_ui_json_as_dict(file) - PlateMatchDriver.start_dask_run( - file, - n_workers=input_file.get("n_workers", None), - n_threads=input_file.get("n_threads", None), - save_report=input_file.get("performance_report", False), - ) + PlateMatchDriver.start_dask_run(file) diff --git a/simpeg_drivers/potential_fields/gravity/__init__.py b/simpeg_drivers/potential_fields/gravity/__init__.py index 3089c723..283f132f 100644 --- a/simpeg_drivers/potential_fields/gravity/__init__.py +++ b/simpeg_drivers/potential_fields/gravity/__init__.py @@ -9,7 +9,12 @@ # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' -from .options import GravityForwardOptions, GravityInversionOptions +from .forward import GravityForwardDriver +from .inversion import GravityInversionDriver +from .options import ( + GravityForwardOptions, + GravityInversionOptions, +) # pylint: disable=unused-import # flake8: noqa diff --git a/simpeg_drivers/potential_fields/gravity/forward.py b/simpeg_drivers/potential_fields/gravity/forward.py new file mode 100644 index 00000000..cfcf33af --- /dev/null +++ b/simpeg_drivers/potential_fields/gravity/forward.py @@ -0,0 +1,30 @@ +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +# Copyright (c) 2023-2026 Mira Geoscience Ltd. ' +# ' +# This file is part of simpeg-drivers package. ' +# ' +# simpeg-drivers is distributed under the terms and conditions of the MIT License ' +# (see LICENSE file at the root of this source code package). ' +# ' +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + + +from __future__ import annotations + +import sys +from pathlib import Path + +from simpeg_drivers.driver import ForwardDriver + +from .options import GravityForwardOptions + + +class GravityForwardDriver(ForwardDriver): + """Gravity forward driver.""" + + _params_class = GravityForwardOptions + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + GravityForwardDriver.start_dask_run(file) diff --git a/simpeg_drivers/potential_fields/gravity/driver.py b/simpeg_drivers/potential_fields/gravity/inversion.py similarity index 80% rename from simpeg_drivers/potential_fields/gravity/driver.py rename to simpeg_drivers/potential_fields/gravity/inversion.py index c0fc7cb6..2c381f37 100644 --- a/simpeg_drivers/potential_fields/gravity/driver.py +++ b/simpeg_drivers/potential_fields/gravity/inversion.py @@ -11,20 +11,20 @@ from __future__ import annotations -from simpeg_drivers.driver import InversionDriver -from simpeg_drivers.potential_fields.gravity.options import ( - GravityForwardOptions, - GravityInversionOptions, -) - +import sys +from pathlib import Path -class GravityForwardDriver(InversionDriver): - """Gravity forward driver.""" +from simpeg_drivers.driver import InversionDriver - _params_class = GravityForwardOptions +from .options import GravityInversionOptions class GravityInversionDriver(InversionDriver): """Gravity inversion driver.""" _params_class = GravityInversionOptions + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + GravityInversionDriver.start_dask_run(file) diff --git a/simpeg_drivers/potential_fields/gravity/uijson.py b/simpeg_drivers/potential_fields/gravity/uijson.py deleted file mode 100644 index 201ab814..00000000 --- a/simpeg_drivers/potential_fields/gravity/uijson.py +++ /dev/null @@ -1,159 +0,0 @@ -# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' -# Copyright (c) 2023-2026 Mira Geoscience Ltd. ' -# ' -# This file is part of simpeg-drivers package. ' -# ' -# simpeg-drivers is distributed under the terms and conditions of the MIT License ' -# (see LICENSE file at the root of this source code package). ' -# ' -# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' - -from pathlib import Path -from typing import ClassVar - -from geoh5py.ui_json.annotations import Deprecated -from geoh5py.ui_json.forms import ( - BoolForm, - ChoiceForm, - DataForm, - DataOrValueForm, - FloatForm, - GroupForm, - IntegerForm, - ObjectForm, -) -from pydantic import AliasChoices, Field - -from simpeg_drivers import assets_path -from simpeg_drivers.uijson import SimPEGDriversUIJson - - -class GravityForwardUIJson(SimPEGDriversUIJson): - """Gravity Forward UIJson.""" - - default_ui_json: ClassVar[Path] = assets_path() / "uijson/gravity_forward.ui.json" - - inversion_type: str - forward_only: bool - data_object: ObjectForm - gz_channel_bool: BoolForm - gx_channel_bool: BoolForm - gy_channel_bool: BoolForm - guv_channel_bool: BoolForm - gxy_channel_bool: BoolForm - gxx_channel_bool: BoolForm - gyy_channel_bool: BoolForm - gzz_channel_bool: BoolForm - gxz_channel_bool: BoolForm - gyz_channel_bool: BoolForm - mesh: ObjectForm - starting_model: DataOrValueForm - topography_object: ObjectForm - topography: DataForm - active_model: DataForm - save_sensitivities: BoolForm - parallelized: BoolForm - tile_spatial: DataForm - max_chunk_size: IntegerForm - out_group: GroupForm - generate_sweep: BoolForm - distributed_workers: str - z_from_topo: Deprecated | None = None - receivers_radar_drape: Deprecated | None = None - receivers_offset_z: Deprecated | None = None - gps_receivers_offset: Deprecated | None = None - output_tile_files: Deprecated | None = None - chunk_by_rows: Deprecated | None = None - parallelized: Deprecated | None = None - n_cpu: Deprecated | None = None - ga_group: Deprecated | None = None - - -class GravityInversionUIJson(SimPEGDriversUIJson): - """Gravity Inversion UIJson.""" - - default_ui_json: ClassVar[Path] = assets_path() / "uijson/gravity_inversion.ui.json" - - inversion_type: str - forward_only: bool - data_object: ObjectForm - gz_channel: DataForm - gz_uncertainty: DataOrValueForm - gx_channel: DataForm - gx_uncertainty: DataOrValueForm - gy_channel: DataForm - gy_uncertainty: DataOrValueForm - guv_channel: DataForm - guv_uncertainty: DataOrValueForm - gxy_channel: DataForm - gxy_uncertainty: DataOrValueForm - gxx_channel: DataForm - gxx_uncertainty: DataOrValueForm - gyy_channel: DataForm - gyy_uncertainty: DataOrValueForm - gzz_channel: DataForm - gzz_uncertainty: DataOrValueForm - gxz_channel: DataForm - gxz_uncertainty: DataOrValueForm - gyz_channel: DataForm - gyz_uncertainty: DataOrValueForm - mesh: ObjectForm - starting_model: DataOrValueForm - reference_model: DataOrValueForm - lower_bound: DataOrValueForm - upper_bound: DataOrValueForm - topography_object: ObjectForm - topography: DataForm - active_model: DataForm - alpha_s: DataOrValueForm - length_scale_x: DataOrValueForm - length_scale_y: DataOrValueForm - length_scale_z: DataOrValueForm - gradient_rotation: DataForm - s_norm: DataOrValueForm - x_norm: DataOrValueForm - y_norm: DataOrValueForm - z_norm: DataOrValueForm - gradient_type: ChoiceForm - max_irls_iterations: IntegerForm - starting_chi_factor: FloatForm - beta_tol: FloatForm - percentile: IntegerForm = Field( - validation_alias=AliasChoices("percentile", "prctile") - ) - chi_factor: FloatForm - auto_scale_tiles: BoolForm - initial_beta_ratio: FloatForm - initial_beta: FloatForm - cooling_factor: FloatForm = Field( - validation_alias=AliasChoices("cooling_factor", "coolingFactor") - ) - cooling_rate: IntegerForm = Field( - validation_alias=AliasChoices("cooling_rate", "coolingRate") - ) - epsilon_cooling_factor: float = Field( - validation_alias=AliasChoices("epsilon_cooling_factor", "coolEpsFact") - ) - max_global_iterations: IntegerForm - max_line_search_iterations: IntegerForm - max_cg_iterations: IntegerForm - tol_cg: FloatForm - f_min_change: FloatForm - sens_wts_threshold: FloatForm - every_iteration_bool: BoolForm - save_sensitivities: BoolForm - n_cpu: IntegerForm - tile_spatial: DataOrValueForm - store_sensitivities: ChoiceForm - max_chunk_size: IntegerForm - - out_group: GroupForm - generate_sweep: BoolForm - distributed_workers: str - gradient_type: Deprecated | None = None - output_tile_files: Deprecated | None = None - inversion_style: Deprecated | None = None - max_ram: Deprecated | None = None - chunk_by_rows: Deprecated | None = None - parallelized: Deprecated | None = None - ga_group: Deprecated | None = None diff --git a/simpeg_drivers/potential_fields/magnetic_scalar/__init__.py b/simpeg_drivers/potential_fields/magnetic_scalar/__init__.py index 0e01c01e..57f656ac 100644 --- a/simpeg_drivers/potential_fields/magnetic_scalar/__init__.py +++ b/simpeg_drivers/potential_fields/magnetic_scalar/__init__.py @@ -9,7 +9,12 @@ # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' -from .options import MagneticForwardOptions, MagneticInversionOptions +from .forward import MagneticForwardDriver +from .inversion import MagneticInversionDriver +from .options import ( + MagneticForwardOptions, + MagneticInversionOptions, +) # pylint: disable=unused-import # flake8: noqa diff --git a/simpeg_drivers/potential_fields/magnetic_scalar/forward.py b/simpeg_drivers/potential_fields/magnetic_scalar/forward.py new file mode 100644 index 00000000..40930f83 --- /dev/null +++ b/simpeg_drivers/potential_fields/magnetic_scalar/forward.py @@ -0,0 +1,30 @@ +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +# Copyright (c) 2023-2026 Mira Geoscience Ltd. ' +# ' +# This file is part of simpeg-drivers package. ' +# ' +# simpeg-drivers is distributed under the terms and conditions of the MIT License ' +# (see LICENSE file at the root of this source code package). ' +# ' +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + + +from __future__ import annotations + +import sys +from pathlib import Path + +from simpeg_drivers.driver import ForwardDriver + +from .options import MagneticForwardOptions + + +class MagneticForwardDriver(ForwardDriver): + """Magnetic susceptibility forward driver.""" + + _params_class = MagneticForwardOptions + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + MagneticForwardDriver.start_dask_run(file) diff --git a/simpeg_drivers/potential_fields/magnetic_scalar/driver.py b/simpeg_drivers/potential_fields/magnetic_scalar/inversion.py similarity index 76% rename from simpeg_drivers/potential_fields/magnetic_scalar/driver.py rename to simpeg_drivers/potential_fields/magnetic_scalar/inversion.py index 094f25be..4c9e45a1 100644 --- a/simpeg_drivers/potential_fields/magnetic_scalar/driver.py +++ b/simpeg_drivers/potential_fields/magnetic_scalar/inversion.py @@ -11,20 +11,20 @@ from __future__ import annotations -from simpeg_drivers.driver import InversionDriver -from simpeg_drivers.potential_fields.magnetic_scalar.options import ( - MagneticForwardOptions, - MagneticInversionOptions, -) - +import sys +from pathlib import Path -class MagneticForwardDriver(InversionDriver): - """Magnetic forward driver.""" +from simpeg_drivers.driver import InversionDriver - _params_class = MagneticForwardOptions +from .options import MagneticInversionOptions class MagneticInversionDriver(InversionDriver): - """Magnetic inversion driver.""" + """Magnetic susceptibility inversion driver.""" _params_class = MagneticInversionOptions + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + MagneticInversionDriver.start_dask_run(file) diff --git a/simpeg_drivers/potential_fields/magnetic_vector/__init__.py b/simpeg_drivers/potential_fields/magnetic_vector/__init__.py index 2d53b438..3535b3c6 100644 --- a/simpeg_drivers/potential_fields/magnetic_vector/__init__.py +++ b/simpeg_drivers/potential_fields/magnetic_vector/__init__.py @@ -9,7 +9,12 @@ # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' -from .options import MVIForwardOptions, MVIInversionOptions +from .forward import MagneticVectorForwardDriver +from .inversion import MagneticVectorInversionDriver +from .options import ( + MagneticVectorForwardOptions, + MagneticVectorInversionOptions, +) # pylint: disable=unused-import # flake8: noqa diff --git a/simpeg_drivers/potential_fields/magnetic_vector/forward.py b/simpeg_drivers/potential_fields/magnetic_vector/forward.py new file mode 100644 index 00000000..7bffaeb6 --- /dev/null +++ b/simpeg_drivers/potential_fields/magnetic_vector/forward.py @@ -0,0 +1,30 @@ +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +# Copyright (c) 2023-2026 Mira Geoscience Ltd. ' +# ' +# This file is part of simpeg-drivers package. ' +# ' +# simpeg-drivers is distributed under the terms and conditions of the MIT License ' +# (see LICENSE file at the root of this source code package). ' +# ' +# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + + +from __future__ import annotations + +import sys +from pathlib import Path + +from simpeg_drivers.driver import ForwardDriver + +from .options import MagneticVectorForwardOptions + + +class MagneticVectorForwardDriver(ForwardDriver): + """Magnetic Vector forward driver.""" + + _params_class = MagneticVectorForwardOptions + + +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + MagneticVectorForwardDriver.start_dask_run(file) diff --git a/simpeg_drivers/potential_fields/magnetic_vector/driver.py b/simpeg_drivers/potential_fields/magnetic_vector/inversion.py similarity index 74% rename from simpeg_drivers/potential_fields/magnetic_vector/driver.py rename to simpeg_drivers/potential_fields/magnetic_vector/inversion.py index cd2ea5fb..bb106219 100644 --- a/simpeg_drivers/potential_fields/magnetic_vector/driver.py +++ b/simpeg_drivers/potential_fields/magnetic_vector/inversion.py @@ -11,20 +11,20 @@ from __future__ import annotations -from simpeg import maps +import sys +from pathlib import Path from simpeg_drivers.driver import InversionDriver -from .options import MVIForwardOptions, MVIInversionOptions +from .options import MagneticVectorInversionOptions -class MVIForwardDriver(InversionDriver): - """Magnetic Vector forward driver.""" - - _params_class = MVIForwardOptions +class MagneticVectorInversionDriver(InversionDriver): + """Magnetic Vector inversion driver.""" + _params_class = MagneticVectorInversionOptions -class MVIInversionDriver(InversionDriver): - """Magnetic Vector inversion driver.""" - _params_class = MVIInversionOptions +if __name__ == "__main__": + file = Path(sys.argv[1]).resolve() + MagneticVectorInversionDriver.start_dask_run(file) diff --git a/simpeg_drivers/potential_fields/magnetic_vector/options.py b/simpeg_drivers/potential_fields/magnetic_vector/options.py index b9ed8aac..3b25c574 100644 --- a/simpeg_drivers/potential_fields/magnetic_vector/options.py +++ b/simpeg_drivers/potential_fields/magnetic_vector/options.py @@ -38,7 +38,7 @@ class VectorModelOptions(ModelOptions): reference_declination: float | FloatData | None = None -class MVIForwardOptions(BaseForwardOptions): +class MagneticVectorForwardOptions(BaseForwardOptions): """ Magnetic Vector forward options. @@ -79,7 +79,7 @@ class MVIForwardOptions(BaseForwardOptions): models: VectorModelOptions -class MVIInversionOptions(BaseInversionOptions): +class MagneticVectorInversionOptions(BaseInversionOptions): """ Magnetic Vector Inversion options. From 5cd8df2e041d82ae9d27af889845438f2325ef38 Mon Sep 17 00:00:00 2001 From: domfournier Date: Fri, 20 Mar 2026 09:31:32 -0700 Subject: [PATCH 07/18] Fix imports in tests --- .../direct_current/two_dimensions/__init__.py | 3 -- .../two_dimensions/__init__.py | 3 -- simpeg_drivers/potential_fields/__init__.py | 14 ---------- .../magnetic_scalar/__init__.py | 3 -- .../run_tests/driver_airborne_fem_1d_test.py | 7 ++--- tests/run_tests/driver_airborne_fem_test.py | 7 ++--- .../run_tests/driver_airborne_tem_1d_test.py | 7 ++--- tests/run_tests/driver_airborne_tem_test.py | 6 ++-- tests/run_tests/driver_app_con_test.py | 7 ++--- .../driver_dc_2d_rotated_gradients_test.py | 6 ++-- tests/run_tests/driver_dc_2d_test.py | 6 ++-- tests/run_tests/driver_dc_test.py | 8 ++---- tests/run_tests/driver_grav_test.py | 9 ++---- tests/run_tests/driver_ground_tem_test.py | 6 ++-- tests/run_tests/driver_ip_2d_test.py | 6 ++-- tests/run_tests/driver_ip_test.py | 6 ++-- .../driver_joint_cross_gradient_test.py | 28 +++++++++---------- .../driver_joint_pgi_homogeneous_test.py | 22 +++++++-------- tests/run_tests/driver_joint_surveys_test.py | 16 ++++++----- tests/run_tests/driver_mag_automesh_test.py | 6 ++-- tests/run_tests/driver_mag_test.py | 8 ++---- tests/run_tests/driver_mt_test.py | 6 ++-- tests/run_tests/driver_mvi_test.py | 24 ++++++++-------- .../driver_rotated_gradients_test.py | 8 ++---- tests/run_tests/driver_tile_estimator_test.py | 5 ++-- tests/run_tests/driver_tipper_test.py | 7 ++--- .../oriented_airborne_tem_receiver_test.py | 4 +-- tests/run_tests/oriented_fem_receiver_test.py | 4 +-- tests/run_tests/sensitivity_cutoff_test.py | 6 ++-- 29 files changed, 89 insertions(+), 159 deletions(-) diff --git a/simpeg_drivers/electricals/direct_current/two_dimensions/__init__.py b/simpeg_drivers/electricals/direct_current/two_dimensions/__init__.py index 05a1d438..4f52f47e 100644 --- a/simpeg_drivers/electricals/direct_current/two_dimensions/__init__.py +++ b/simpeg_drivers/electricals/direct_current/two_dimensions/__init__.py @@ -11,6 +11,3 @@ from .forward import DC2DForwardDriver from .inversion import DC2DInversionDriver from .options import DC2DForwardOptions, DC2DInversionOptions - - -__all__ = ["DC2DForwardOptions", "DC2DInversionOptions"] diff --git a/simpeg_drivers/electricals/induced_polarization/two_dimensions/__init__.py b/simpeg_drivers/electricals/induced_polarization/two_dimensions/__init__.py index 3b341585..aebc0e66 100644 --- a/simpeg_drivers/electricals/induced_polarization/two_dimensions/__init__.py +++ b/simpeg_drivers/electricals/induced_polarization/two_dimensions/__init__.py @@ -14,6 +14,3 @@ IP2DForwardOptions, IP2DInversionOptions, ) - -# pylint: disable=unused-import -# flake8: noqa diff --git a/simpeg_drivers/potential_fields/__init__.py b/simpeg_drivers/potential_fields/__init__.py index 9c3c245a..df32b204 100644 --- a/simpeg_drivers/potential_fields/__init__.py +++ b/simpeg_drivers/potential_fields/__init__.py @@ -7,17 +7,3 @@ # (see LICENSE file at the root of this source code package). ' # ' # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' - - -from .gravity.options import GravityForwardOptions, GravityInversionOptions -from .magnetic_scalar.options import ( - MagneticForwardOptions, - MagneticInversionOptions, -) -from .magnetic_vector.options import ( - MVIForwardOptions, - MVIInversionOptions, -) - -# pylint: disable=unused-import -# flake8: noqa diff --git a/simpeg_drivers/potential_fields/magnetic_scalar/__init__.py b/simpeg_drivers/potential_fields/magnetic_scalar/__init__.py index 57f656ac..37ba59bf 100644 --- a/simpeg_drivers/potential_fields/magnetic_scalar/__init__.py +++ b/simpeg_drivers/potential_fields/magnetic_scalar/__init__.py @@ -15,6 +15,3 @@ MagneticForwardOptions, MagneticInversionOptions, ) - -# pylint: disable=unused-import -# flake8: noqa diff --git a/tests/run_tests/driver_airborne_fem_1d_test.py b/tests/run_tests/driver_airborne_fem_1d_test.py index da501fa6..0e180cd2 100644 --- a/tests/run_tests/driver_airborne_fem_1d_test.py +++ b/tests/run_tests/driver_airborne_fem_1d_test.py @@ -16,14 +16,11 @@ import numpy as np from geoh5py import Workspace -from geoh5py.groups import SimPEGGroup -from simpeg_drivers.electromagnetics.frequency_domain_1d.driver import ( +from simpeg_drivers.electromagnetics.frequency_domain_1d import ( FDEM1DForwardDriver, - FDEM1DInversionDriver, -) -from simpeg_drivers.electromagnetics.frequency_domain_1d.options import ( FDEM1DForwardOptions, + FDEM1DInversionDriver, FDEM1DInversionOptions, ) from simpeg_drivers.utils.synthetics.driver import ( diff --git a/tests/run_tests/driver_airborne_fem_test.py b/tests/run_tests/driver_airborne_fem_test.py index d985e426..174a1357 100644 --- a/tests/run_tests/driver_airborne_fem_test.py +++ b/tests/run_tests/driver_airborne_fem_test.py @@ -18,14 +18,11 @@ import numpy as np from geoapps_utils.modelling.plates import PlateModel from geoh5py import Workspace -from geoh5py.groups import SimPEGGroup -from simpeg_drivers.electromagnetics.frequency_domain.driver import ( +from simpeg_drivers.electromagnetics.frequency_domain import ( FDEMForwardDriver, - FDEMInversionDriver, -) -from simpeg_drivers.electromagnetics.frequency_domain.options import ( FDEMForwardOptions, + FDEMInversionDriver, FDEMInversionOptions, ) from simpeg_drivers.utils.synthetics.driver import ( diff --git a/tests/run_tests/driver_airborne_tem_1d_test.py b/tests/run_tests/driver_airborne_tem_1d_test.py index a4c1878b..a907966a 100644 --- a/tests/run_tests/driver_airborne_tem_1d_test.py +++ b/tests/run_tests/driver_airborne_tem_1d_test.py @@ -13,15 +13,12 @@ from pathlib import Path import numpy as np -from geoh5py.groups import SimPEGGroup from geoh5py.workspace import Workspace -from simpeg_drivers.electromagnetics.time_domain_1d.driver import ( +from simpeg_drivers.electromagnetics.time_domain_1d import ( TDEM1DForwardDriver, - TDEM1DInversionDriver, -) -from simpeg_drivers.electromagnetics.time_domain_1d.options import ( TDEM1DForwardOptions, + TDEM1DInversionDriver, TDEM1DInversionOptions, ) from simpeg_drivers.utils.synthetics.driver import ( diff --git a/tests/run_tests/driver_airborne_tem_test.py b/tests/run_tests/driver_airborne_tem_test.py index f8bf4cba..64e74406 100644 --- a/tests/run_tests/driver_airborne_tem_test.py +++ b/tests/run_tests/driver_airborne_tem_test.py @@ -17,12 +17,10 @@ from geoh5py.workspace import Workspace from pytest import raises -from simpeg_drivers.electromagnetics.time_domain.driver import ( +from simpeg_drivers.electromagnetics.time_domain import ( TDEMForwardDriver, - TDEMInversionDriver, -) -from simpeg_drivers.electromagnetics.time_domain.options import ( TDEMForwardOptions, + TDEMInversionDriver, TDEMInversionOptions, ) from simpeg_drivers.utils.synthetics.driver import ( diff --git a/tests/run_tests/driver_app_con_test.py b/tests/run_tests/driver_app_con_test.py index 7fdd7ac3..ce67bfad 100644 --- a/tests/run_tests/driver_app_con_test.py +++ b/tests/run_tests/driver_app_con_test.py @@ -14,15 +14,12 @@ import numpy as np from geoapps_utils.modelling.plates import PlateModel -from geoh5py.groups import SimPEGGroup from geoh5py.workspace import Workspace -from simpeg_drivers.natural_sources.apparent_conductivity.driver import ( +from simpeg_drivers.natural_sources.apparent_conductivity import ( AppConForwardDriver, - AppConInversionDriver, -) -from simpeg_drivers.natural_sources.apparent_conductivity.options import ( AppConForwardOptions, + AppConInversionDriver, AppConInversionOptions, ) from simpeg_drivers.utils.synthetics.driver import ( diff --git a/tests/run_tests/driver_dc_2d_rotated_gradients_test.py b/tests/run_tests/driver_dc_2d_rotated_gradients_test.py index 3333ebde..13f03ec9 100644 --- a/tests/run_tests/driver_dc_2d_rotated_gradients_test.py +++ b/tests/run_tests/driver_dc_2d_rotated_gradients_test.py @@ -18,12 +18,10 @@ from geoh5py.groups import PropertyGroup from geoh5py.workspace import Workspace -from simpeg_drivers.electricals.direct_current.two_dimensions.driver import ( +from simpeg_drivers.electricals.direct_current.two_dimensions import ( DC2DForwardDriver, - DC2DInversionDriver, -) -from simpeg_drivers.electricals.direct_current.two_dimensions.options import ( DC2DForwardOptions, + DC2DInversionDriver, DC2DInversionOptions, ) from simpeg_drivers.options import ( diff --git a/tests/run_tests/driver_dc_2d_test.py b/tests/run_tests/driver_dc_2d_test.py index d561b61f..77fd0151 100644 --- a/tests/run_tests/driver_dc_2d_test.py +++ b/tests/run_tests/driver_dc_2d_test.py @@ -17,12 +17,10 @@ from geoapps_utils.modelling.plates import PlateModel from geoh5py.workspace import Workspace -from simpeg_drivers.electricals.direct_current.two_dimensions.driver import ( +from simpeg_drivers.electricals.direct_current.two_dimensions import ( DC2DForwardDriver, - DC2DInversionDriver, -) -from simpeg_drivers.electricals.direct_current.two_dimensions.options import ( DC2DForwardOptions, + DC2DInversionDriver, DC2DInversionOptions, ) from simpeg_drivers.options import ( diff --git a/tests/run_tests/driver_dc_test.py b/tests/run_tests/driver_dc_test.py index ac358c32..ad2f115b 100644 --- a/tests/run_tests/driver_dc_test.py +++ b/tests/run_tests/driver_dc_test.py @@ -15,12 +15,10 @@ import numpy as np from geoh5py.workspace import Workspace -from simpeg_drivers.electricals.direct_current.three_dimensions.driver import ( +from simpeg_drivers.electricals.direct_current.three_dimensions import ( DC3DForwardDriver, - DC3DInversionDriver, -) -from simpeg_drivers.electricals.direct_current.three_dimensions.options import ( DC3DForwardOptions, + DC3DInversionDriver, DC3DInversionOptions, ) from simpeg_drivers.utils.synthetics.driver import ( @@ -167,7 +165,7 @@ def test_dc_single_line_fwr_run( ) fwr_driver = DC3DForwardDriver(params) - assert np.all(fwr_driver.window.window["size"] > 0) + assert fwr_driver.inversion_mesh.mesh.n_cells == 13855 if __name__ == "__main__": diff --git a/tests/run_tests/driver_grav_test.py b/tests/run_tests/driver_grav_test.py index e6ffbfe5..bc3174dd 100644 --- a/tests/run_tests/driver_grav_test.py +++ b/tests/run_tests/driver_grav_test.py @@ -15,17 +15,14 @@ import numpy as np from geoapps_utils.utils.importing import GeoAppsError -from geoapps_utils.utils.locations import gaussian from geoh5py.workspace import Workspace from pytest import raises -from simpeg_drivers.potential_fields import ( - GravityForwardOptions, - GravityInversionOptions, -) -from simpeg_drivers.potential_fields.gravity.driver import ( +from simpeg_drivers.potential_fields.gravity import ( GravityForwardDriver, + GravityForwardOptions, GravityInversionDriver, + GravityInversionOptions, ) from simpeg_drivers.utils.synthetics.driver import SyntheticsComponents from simpeg_drivers.utils.synthetics.options import ( diff --git a/tests/run_tests/driver_ground_tem_test.py b/tests/run_tests/driver_ground_tem_test.py index 26b3b9e4..c70fcaaa 100644 --- a/tests/run_tests/driver_ground_tem_test.py +++ b/tests/run_tests/driver_ground_tem_test.py @@ -18,12 +18,10 @@ from geoh5py.workspace import Workspace from pymatsolver.direct import Mumps -from simpeg_drivers.electromagnetics.time_domain.driver import ( +from simpeg_drivers.electromagnetics.time_domain import ( TDEMForwardDriver, - TDEMInversionDriver, -) -from simpeg_drivers.electromagnetics.time_domain.options import ( TDEMForwardOptions, + TDEMInversionDriver, TDEMInversionOptions, ) from simpeg_drivers.utils.synthetics.driver import ( diff --git a/tests/run_tests/driver_ip_2d_test.py b/tests/run_tests/driver_ip_2d_test.py index 74dde327..30639ed3 100644 --- a/tests/run_tests/driver_ip_2d_test.py +++ b/tests/run_tests/driver_ip_2d_test.py @@ -17,12 +17,10 @@ from geoh5py.workspace import Workspace from simpeg_drivers.electricals.induced_polarization.two_dimensions import ( - IP2DForwardOptions, - IP2DInversionOptions, -) -from simpeg_drivers.electricals.induced_polarization.two_dimensions.driver import ( IP2DForwardDriver, + IP2DForwardOptions, IP2DInversionDriver, + IP2DInversionOptions, ) from simpeg_drivers.utils.synthetics.driver import ( SyntheticsComponents, diff --git a/tests/run_tests/driver_ip_test.py b/tests/run_tests/driver_ip_test.py index 466371ed..ae6f7035 100644 --- a/tests/run_tests/driver_ip_test.py +++ b/tests/run_tests/driver_ip_test.py @@ -15,12 +15,10 @@ from geoh5py.workspace import Workspace from simpeg_drivers.electricals.induced_polarization.three_dimensions import ( - IP3DForwardOptions, - IP3DInversionOptions, -) -from simpeg_drivers.electricals.induced_polarization.three_dimensions.driver import ( IP3DForwardDriver, + IP3DForwardOptions, IP3DInversionDriver, + IP3DInversionOptions, ) from simpeg_drivers.utils.synthetics.driver import ( SyntheticsComponents, diff --git a/tests/run_tests/driver_joint_cross_gradient_test.py b/tests/run_tests/driver_joint_cross_gradient_test.py index 1ec9b241..363db6cd 100644 --- a/tests/run_tests/driver_joint_cross_gradient_test.py +++ b/tests/run_tests/driver_joint_cross_gradient_test.py @@ -22,19 +22,17 @@ ) from simpeg_drivers.joint.joint_cross_gradient import JointCrossGradientOptions from simpeg_drivers.joint.joint_cross_gradient.driver import JointCrossGradientDriver -from simpeg_drivers.potential_fields import ( - GravityForwardOptions, - GravityInversionOptions, - MVIForwardOptions, - MVIInversionOptions, -) -from simpeg_drivers.potential_fields.gravity.driver import ( +from simpeg_drivers.potential_fields.gravity import ( GravityForwardDriver, + GravityForwardOptions, GravityInversionDriver, + GravityInversionOptions, ) -from simpeg_drivers.potential_fields.magnetic_vector.driver import ( - MVIForwardDriver, - MVIInversionDriver, +from simpeg_drivers.potential_fields.magnetic_vector import ( + MagneticVectorForwardDriver, + MagneticVectorForwardOptions, + MagneticVectorInversionDriver, + MagneticVectorInversionOptions, ) from simpeg_drivers.utils.synthetics.driver import ( SyntheticsComponents, @@ -99,7 +97,7 @@ def test_joint_cross_gradient_fwr_run( active=SyntheticsActiveCellsOptions(name="active B"), ) components = SyntheticsComponents(geoh5, options=opts) - params = MVIForwardOptions.build( + params = MagneticVectorForwardOptions.build( geoh5=geoh5, mesh=components.mesh, topography_object=components.topography, @@ -109,7 +107,7 @@ def test_joint_cross_gradient_fwr_run( data_object=components.survey, starting_model=components.model, ) - fwr_driver_b = MVIForwardDriver(params) + fwr_driver_b = MagneticVectorForwardDriver(params) with geoh5.open(): opts = SyntheticsComponentsOptions( @@ -231,7 +229,7 @@ def test_joint_cross_gradient_inv_run( ) drivers.append(DC3DInversionDriver(params)) else: - params = MVIInversionOptions.build( + params = MagneticVectorInversionOptions.build( geoh5=geoh5, mesh=mesh, alpha_s=1.0, @@ -247,7 +245,7 @@ def test_joint_cross_gradient_inv_run( tile_spatial=2, auto_scale_tiles=False, ) - drivers.append(MVIInversionDriver(params)) + drivers.append(MagneticVectorInversionDriver(params)) # Run the inverse joint_params = JointCrossGradientOptions.build( @@ -281,7 +279,7 @@ def test_joint_cross_gradient_inv_run( driver.run() # Mix of scaling on misfits and tiles. - # Expecting that gravity tiles are independently scaled, but MVI tiles take + # Expecting that gravity tiles are independently scaled, but MagneticVector tiles take # the scaling from its total misfit. np.testing.assert_allclose( driver.directives.scale_misfits.scalings, diff --git a/tests/run_tests/driver_joint_pgi_homogeneous_test.py b/tests/run_tests/driver_joint_pgi_homogeneous_test.py index 111eddb5..ca69ddd9 100644 --- a/tests/run_tests/driver_joint_pgi_homogeneous_test.py +++ b/tests/run_tests/driver_joint_pgi_homogeneous_test.py @@ -19,21 +19,19 @@ from simpeg_drivers.joint.joint_petrophysics.driver import JointPetrophysicsDriver from simpeg_drivers.joint.joint_petrophysics.options import JointPetrophysicsOptions -from simpeg_drivers.potential_fields import ( - GravityForwardOptions, - GravityInversionOptions, - MagneticInversionOptions, - MVIForwardOptions, -) -from simpeg_drivers.potential_fields.gravity.driver import ( +from simpeg_drivers.potential_fields.gravity import ( GravityForwardDriver, + GravityForwardOptions, GravityInversionDriver, + GravityInversionOptions, ) -from simpeg_drivers.potential_fields.magnetic_scalar.driver import ( +from simpeg_drivers.potential_fields.magnetic_scalar import ( MagneticInversionDriver, + MagneticInversionOptions, ) -from simpeg_drivers.potential_fields.magnetic_vector.driver import ( - MVIForwardDriver, +from simpeg_drivers.potential_fields.magnetic_vector import ( + MagneticVectorForwardDriver, + MagneticVectorForwardOptions, ) from simpeg_drivers.utils.synthetics.driver import ( SyntheticsComponents, @@ -109,7 +107,7 @@ def test_homogeneous_fwr_run( ind = components.mesh.centroids[:, 0] > -2 components.model.values[ind] = 0.01 - params = MVIForwardOptions.build( + params = MagneticVectorForwardOptions.build( geoh5=geoh5, mesh=components.mesh, topography_object=components.topography, @@ -119,7 +117,7 @@ def test_homogeneous_fwr_run( data_object=components.survey, starting_model=components.model, ) - fwr_driver_b = MVIForwardDriver(params) + fwr_driver_b = MagneticVectorForwardDriver(params) fwr_driver_a.run() fwr_driver_b.run() diff --git a/tests/run_tests/driver_joint_surveys_test.py b/tests/run_tests/driver_joint_surveys_test.py index db405174..e8f9dd16 100644 --- a/tests/run_tests/driver_joint_surveys_test.py +++ b/tests/run_tests/driver_joint_surveys_test.py @@ -21,18 +21,20 @@ from simpeg_drivers.electricals.direct_current.three_dimensions.options import ( DC3DInversionOptions, ) -from simpeg_drivers.electromagnetics.time_domain.driver import TDEMInversionDriver +from simpeg_drivers.electromagnetics.time_domain import TDEMInversionDriver from simpeg_drivers.electromagnetics.time_domain.options import TDEMInversionOptions from simpeg_drivers.joint.joint_surveys import JointSurveysOptions from simpeg_drivers.joint.joint_surveys.driver import JointSurveyDriver from simpeg_drivers.options import ActiveCellsOptions -from simpeg_drivers.potential_fields import ( +from simpeg_drivers.potential_fields.gravity import ( GravityForwardOptions, + GravityInversionDriver, GravityInversionOptions, ) -from simpeg_drivers.potential_fields.gravity.driver import GravityInversionDriver -from simpeg_drivers.potential_fields.magnetic_vector.driver import MVIInversionDriver -from simpeg_drivers.potential_fields.magnetic_vector.options import MVIInversionOptions +from simpeg_drivers.potential_fields.magnetic_vector import ( + MagneticVectorInversionDriver, + MagneticVectorInversionOptions, +) from simpeg_drivers.utils.synthetics.driver import ( SyntheticsComponents, ) @@ -243,7 +245,7 @@ def test_joint_surveys_mvi_run(tmp_path, anomaly=0.05): else: inc_mod = None - params = MVIInversionOptions.build( + params = MagneticVectorInversionOptions.build( geoh5=geoh5, mesh=components.mesh, topography_object=components.topography, @@ -257,7 +259,7 @@ def test_joint_surveys_mvi_run(tmp_path, anomaly=0.05): starting_inclination=inc_mod, reference_model=0.0, ) - drivers.append(MVIInversionDriver(params)) + drivers.append(MagneticVectorInversionDriver(params)) # Run the inverse joint_params = JointSurveysOptions.build( diff --git a/tests/run_tests/driver_mag_automesh_test.py b/tests/run_tests/driver_mag_automesh_test.py index 70f662c7..494da8bb 100644 --- a/tests/run_tests/driver_mag_automesh_test.py +++ b/tests/run_tests/driver_mag_automesh_test.py @@ -15,11 +15,9 @@ import numpy as np from geoh5py import Workspace -from simpeg_drivers.potential_fields import ( - MagneticForwardOptions, -) -from simpeg_drivers.potential_fields.magnetic_scalar.driver import ( +from simpeg_drivers.potential_fields.magnetic_scalar import ( MagneticForwardDriver, + MagneticForwardOptions, ) from simpeg_drivers.utils.synthetics.driver import SyntheticsComponents from simpeg_drivers.utils.synthetics.options import ( diff --git a/tests/run_tests/driver_mag_test.py b/tests/run_tests/driver_mag_test.py index 4795597d..d9e65e1a 100644 --- a/tests/run_tests/driver_mag_test.py +++ b/tests/run_tests/driver_mag_test.py @@ -16,13 +16,11 @@ from dask.distributed import LocalCluster, performance_report from geoh5py.workspace import Workspace -from simpeg_drivers.potential_fields import ( - MagneticForwardOptions, - MagneticInversionOptions, -) -from simpeg_drivers.potential_fields.magnetic_scalar.driver import ( +from simpeg_drivers.potential_fields.magnetic_scalar import ( MagneticForwardDriver, + MagneticForwardOptions, MagneticInversionDriver, + MagneticInversionOptions, ) from simpeg_drivers.utils.synthetics.driver import ( SyntheticsComponents, diff --git a/tests/run_tests/driver_mt_test.py b/tests/run_tests/driver_mt_test.py index 1de06e1a..92f6f8ba 100644 --- a/tests/run_tests/driver_mt_test.py +++ b/tests/run_tests/driver_mt_test.py @@ -17,12 +17,10 @@ import numpy as np from geoh5py.workspace import Workspace -from simpeg_drivers.natural_sources.magnetotellurics.driver import ( +from simpeg_drivers.natural_sources.magnetotellurics import ( MTForwardDriver, - MTInversionDriver, -) -from simpeg_drivers.natural_sources.magnetotellurics.options import ( MTForwardOptions, + MTInversionDriver, MTInversionOptions, ) from simpeg_drivers.utils.synthetics.driver import ( diff --git a/tests/run_tests/driver_mvi_test.py b/tests/run_tests/driver_mvi_test.py index cfce3e57..be3c40af 100644 --- a/tests/run_tests/driver_mvi_test.py +++ b/tests/run_tests/driver_mvi_test.py @@ -23,13 +23,11 @@ from simpeg.utils.mat_utils import cartesian2amplitude_dip_azimuth from simpeg_drivers.components.factories import DirectivesFactory -from simpeg_drivers.potential_fields import ( - MVIForwardOptions, - MVIInversionOptions, -) -from simpeg_drivers.potential_fields.magnetic_vector.driver import ( - MVIForwardDriver, - MVIInversionDriver, +from simpeg_drivers.potential_fields.magnetic_vector import ( + MagneticVectorForwardDriver, + MagneticVectorForwardOptions, + MagneticVectorInversionDriver, + MagneticVectorInversionOptions, ) from simpeg_drivers.utils.synthetics.driver import ( SyntheticsComponents, @@ -72,7 +70,7 @@ def test_magnetic_vector_fwr_run( ) geoh5.remove_entity(components.survey) inducing_field = (50000.0, 90.0, 0.0) - params = MVIForwardOptions.build( + params = MagneticVectorForwardOptions.build( forward_only=True, geoh5=geoh5, mesh=components.mesh, @@ -85,7 +83,7 @@ def test_magnetic_vector_fwr_run( starting_inclination=45, starting_declination=270, ) - fwr_driver = MVIForwardDriver(params) + fwr_driver = MagneticVectorForwardDriver(params) fwr_driver.run() @@ -125,7 +123,7 @@ def test_magnetic_vector_run( ) # Run the inverse with caplog.at_level(logging.WARNING) if caplog else contextlib.nullcontext(): - params = MVIInversionOptions.build( + params = MagneticVectorInversionOptions.build( geoh5=geoh5, mesh=mesh, topography_object=topography, @@ -151,7 +149,7 @@ def test_magnetic_vector_run( if caplog: assert "Deprecated field 'lower_bound' will be ignored." in caplog.text - driver = MVIInversionDriver(params) + driver = MagneticVectorInversionDriver(params) assert np.all(driver.models.lower_bound == -upper_bound) driver.run() @@ -203,7 +201,7 @@ def test_magnetic_vector_reference( {"tmi": {"values": np.random.randn(components.survey.n_vertices)}} ) inducing_field = (50000.0, 90.0, 0.0) - params = MVIInversionOptions.build( + params = MagneticVectorInversionOptions.build( geoh5=geoh5, mesh=components.mesh, topography_object=components.topography, @@ -218,7 +216,7 @@ def test_magnetic_vector_reference( reference_inclination=30, reference_declination=0, ) - driver = MVIInversionDriver(params) + driver = MagneticVectorInversionDriver(params) directives = DirectivesFactory(driver) assert np.all(directives.vector_inversion_directive.reference_angles) diff --git a/tests/run_tests/driver_rotated_gradients_test.py b/tests/run_tests/driver_rotated_gradients_test.py index 1a2426a7..8d757cf5 100644 --- a/tests/run_tests/driver_rotated_gradients_test.py +++ b/tests/run_tests/driver_rotated_gradients_test.py @@ -18,13 +18,11 @@ from geoh5py.groups.property_group import PropertyGroup from geoh5py.workspace import Workspace -from simpeg_drivers.potential_fields import ( - GravityForwardOptions, - GravityInversionOptions, -) -from simpeg_drivers.potential_fields.gravity.driver import ( +from simpeg_drivers.potential_fields.gravity import ( GravityForwardDriver, + GravityForwardOptions, GravityInversionDriver, + GravityInversionOptions, ) from simpeg_drivers.utils.synthetics.driver import ( SyntheticsComponents, diff --git a/tests/run_tests/driver_tile_estimator_test.py b/tests/run_tests/driver_tile_estimator_test.py index fa831637..dfe8b560 100644 --- a/tests/run_tests/driver_tile_estimator_test.py +++ b/tests/run_tests/driver_tile_estimator_test.py @@ -13,11 +13,10 @@ from pathlib import Path import numpy as np -from geoh5py import Workspace -from simpeg_drivers.potential_fields import MagneticInversionOptions -from simpeg_drivers.potential_fields.magnetic_scalar.driver import ( +from simpeg_drivers.potential_fields.magnetic_scalar import ( MagneticInversionDriver, + MagneticInversionOptions, ) from simpeg_drivers.utils.synthetics.driver import SyntheticsComponents from simpeg_drivers.utils.synthetics.options import ( diff --git a/tests/run_tests/driver_tipper_test.py b/tests/run_tests/driver_tipper_test.py index 3fa28b4a..816b3d84 100644 --- a/tests/run_tests/driver_tipper_test.py +++ b/tests/run_tests/driver_tipper_test.py @@ -13,16 +13,13 @@ from pathlib import Path import numpy as np -from geoh5py.groups import SimPEGGroup from geoh5py.workspace import Workspace from simpeg_drivers.natural_sources.tipper import ( - TipperForwardOptions, - TipperInversionOptions, -) -from simpeg_drivers.natural_sources.tipper.driver import ( TipperForwardDriver, + TipperForwardOptions, TipperInversionDriver, + TipperInversionOptions, ) from simpeg_drivers.utils.synthetics.driver import ( SyntheticsComponents, diff --git a/tests/run_tests/oriented_airborne_tem_receiver_test.py b/tests/run_tests/oriented_airborne_tem_receiver_test.py index 78530c6c..585ab3d1 100644 --- a/tests/run_tests/oriented_airborne_tem_receiver_test.py +++ b/tests/run_tests/oriented_airborne_tem_receiver_test.py @@ -22,10 +22,8 @@ from geoh5py.objects import AirborneTEMReceivers from geoh5py.shared.utils import fetch_active_workspace -from simpeg_drivers.electromagnetics.time_domain.driver import ( +from simpeg_drivers.electromagnetics.time_domain import ( TDEMForwardDriver, -) -from simpeg_drivers.electromagnetics.time_domain.options import ( TDEMForwardOptions, ) from simpeg_drivers.utils.synthetics.driver import ( diff --git a/tests/run_tests/oriented_fem_receiver_test.py b/tests/run_tests/oriented_fem_receiver_test.py index 89bec0d2..f2163543 100644 --- a/tests/run_tests/oriented_fem_receiver_test.py +++ b/tests/run_tests/oriented_fem_receiver_test.py @@ -22,10 +22,8 @@ from geoh5py.objects import AirborneFEMReceivers from geoh5py.shared.utils import fetch_active_workspace -from simpeg_drivers.electromagnetics.frequency_domain.driver import ( +from simpeg_drivers.electromagnetics.frequency_domain import ( FDEMForwardDriver, -) -from simpeg_drivers.electromagnetics.frequency_domain.options import ( FDEMForwardOptions, ) from simpeg_drivers.utils.synthetics.driver import ( diff --git a/tests/run_tests/sensitivity_cutoff_test.py b/tests/run_tests/sensitivity_cutoff_test.py index 68a91ff9..da695c6a 100644 --- a/tests/run_tests/sensitivity_cutoff_test.py +++ b/tests/run_tests/sensitivity_cutoff_test.py @@ -22,8 +22,10 @@ from simpeg_drivers.depth_of_investigation.sensitivity_cutoff.options import ( SensitivityCutoffOptions, ) -from simpeg_drivers.potential_fields import GravityInversionOptions -from simpeg_drivers.potential_fields.gravity.driver import GravityInversionDriver +from simpeg_drivers.potential_fields.gravity import ( + GravityInversionDriver, + GravityInversionOptions, +) from simpeg_drivers.utils.synthetics.driver import SyntheticsComponents from simpeg_drivers.utils.synthetics.options import ( MeshOptions, From 8c55aebaaacf78056f3881bd480c52f0ab66e89e Mon Sep 17 00:00:00 2001 From: domfournier Date: Fri, 20 Mar 2026 12:18:54 -0700 Subject: [PATCH 08/18] Fix DRIVER_MAP. Remove re-implmenetation of run in joint --- .../uijson/plate_simulation.ui.json | 2 +- simpeg_drivers/__init__.py | 50 ++++++------ .../factories/directives_factory.py | 7 +- simpeg_drivers/driver.py | 61 +++++---------- .../electromagnetics/base_1d_driver.py | 36 ++------- simpeg_drivers/joint/driver.py | 31 -------- simpeg_drivers/plate_simulation/driver.py | 56 +++++--------- .../plate_simulation/match/driver.py | 77 ++++++++++--------- simpeg_drivers/plate_simulation/options.py | 6 +- .../plate_simulation/sweep/driver.py | 49 ++++++++---- simpeg_drivers/utils/utils.py | 54 +++++++++++++ tests/data_test.py | 16 ++-- tests/driver_test.py | 7 +- tests/locations_test.py | 8 +- tests/meshes_test.py | 13 ++-- tests/models_test.py | 20 ++--- tests/plate_simulation/runtest/driver_test.py | 1 - tests/plate_simulation/runtest/match_test.py | 6 +- tests/run_tests/driver_joint_surveys_test.py | 5 +- tests/topography_test.py | 6 +- tests/uijson_test.py | 48 +----------- 21 files changed, 254 insertions(+), 305 deletions(-) diff --git a/simpeg_drivers-assets/uijson/plate_simulation.ui.json b/simpeg_drivers-assets/uijson/plate_simulation.ui.json index e12231a8..47fe0a05 100644 --- a/simpeg_drivers-assets/uijson/plate_simulation.ui.json +++ b/simpeg_drivers-assets/uijson/plate_simulation.ui.json @@ -4,7 +4,7 @@ "icon": "maxwellplate", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/plate-simulation/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.plate_simulation.driver", "geoh5": "", "monitoring_directory": "", "simulation": { diff --git a/simpeg_drivers/__init__.py b/simpeg_drivers/__init__.py index 3cc0ed27..5c015262 100644 --- a/simpeg_drivers/__init__.py +++ b/simpeg_drivers/__init__.py @@ -51,137 +51,137 @@ def assets_path() -> Path: DRIVER_MAP = { "apparent conductivity": ( - "simpeg_drivers.natural_sources.apparent_conductivity.driver", + "simpeg_drivers.natural_sources.apparent_conductivity", {"forward": "AppConForwardDriver", "inversion": "AppConInversionDriver"}, ), "direct current 3d": ( - "simpeg_drivers.electricals.direct_current.three_dimensions.driver", + "simpeg_drivers.electricals.direct_current.three_dimensions", { "forward": "DC3DForwardDriver", "inversion": "DC3DInversionDriver", }, ), "direct current 2d": ( - "simpeg_drivers.electricals.direct_current.two_dimensions.driver", + "simpeg_drivers.electricals.direct_current.two_dimensions", { "forward": "DC2DForwardDriver", "inversion": "DC2DInversionDriver", }, ), "direct current pseudo 3d": ( - "simpeg_drivers.electricals.direct_current.two_dimensions.driver", + "simpeg_drivers.electricals.direct_current.two_dimensions", { "forward": "DC2DForwardDriver", "inversion": "DC2DInversionDriver", }, ), "fdem": ( - "simpeg_drivers.electromagnetics.frequency_domain.driver", + "simpeg_drivers.electromagnetics.frequency_domain", { "forward": "FDEMForwardDriver", "inversion": "FDEMInversionDriver", }, ), "fem": ( - "simpeg_drivers.electromagnetics.frequency_domain.driver", + "simpeg_drivers.electromagnetics.frequency_domain", { "forward": "FDEMForwardDriver", "inversion": "FDEMInversionDriver", }, ), "fdem 1d": ( - "simpeg_drivers.electromagnetics.frequency_domain_1d.driver", + "simpeg_drivers.electromagnetics.frequency_domain_1d", { "forward": "FDEM1DForwardDriver", "inversion": "FDEM1DInversionDriver", }, ), "gravity": ( - "simpeg_drivers.potential_fields.gravity.driver", + "simpeg_drivers.potential_fields.gravity", {"forward": "GravityForwardDriver", "inversion": "GravityInversionDriver"}, ), "induced polarization 3d": ( - "simpeg_drivers.electricals.induced_polarization.three_dimensions.driver", + "simpeg_drivers.electricals.induced_polarization.three_dimensions", { "forward": "IP3DForwardDriver", "inversion": "IP3DInversionDriver", }, ), "induced polarization 2d": ( - "simpeg_drivers.electricals.induced_polarization.two_dimensions.driver", + "simpeg_drivers.electricals.induced_polarization.two_dimensions", { "forward": "IP2DForwardDriver", "inversion": "IP2DInversionDriver", }, ), "induced polarization pseudo 3d": ( - "simpeg_drivers.electricals.induced_polarization.two_dimensions.driver", + "simpeg_drivers.electricals.induced_polarization.two_dimensions", { "forward": "IP2DForwardDriver", "inversion": "IP2DInversionDriver", }, ), "joint cross gradient": ( - "simpeg_drivers.joint.joint_cross_gradient.driver", + "simpeg_drivers.joint.joint_cross_gradient", {"inversion": "JointCrossGradientDriver"}, ), "joint petrophysics": ( - "simpeg_drivers.joint.joint_petrophysics.driver", + "simpeg_drivers.joint.joint_petrophysics", {"inversion": "JointPetrophysicsDriver"}, ), "joint surveys": ( - "simpeg_drivers.joint.joint_surveys.driver", + "simpeg_drivers.joint.joint_surveys", {"inversion": "JointSurveyDriver"}, ), "magnetic scalar": ( - "simpeg_drivers.potential_fields.magnetic_scalar.driver", + "simpeg_drivers.potential_fields.magnetic_scalar", { "forward": "MagneticForwardDriver", "inversion": "MagneticInversionDriver", }, ), "magnetic vector": ( - "simpeg_drivers.potential_fields.magnetic_vector.driver", + "simpeg_drivers.potential_fields.magnetic_vector", { - "forward": "MVIForwardDriver", - "inversion": "MVIInversionDriver", + "forward": "MagneticVectorForwardDriver", + "inversion": "MagneticVectorInversionDriver", }, ), "magnetotellurics": ( - "simpeg_drivers.natural_sources.magnetotellurics.driver", + "simpeg_drivers.natural_sources.magnetotellurics", { "forward": "MTForwardDriver", "inversion": "MTInversionDriver", }, ), "tdem": ( - "simpeg_drivers.electromagnetics.time_domain.driver", + "simpeg_drivers.electromagnetics.time_domain", { "forward": "TDEMForwardDriver", "inversion": "TDEMInversionDriver", }, ), "tdem 1d": ( - "simpeg_drivers.electromagnetics.time_domain_1d.driver", + "simpeg_drivers.electromagnetics.time_domain_1d", { "forward": "TDEM1DForwardDriver", "inversion": "TDEM1DInversionDriver", }, ), "tipper": ( - "simpeg_drivers.natural_sources.tipper.driver", + "simpeg_drivers.natural_sources.tipper", {"forward": "TipperForwardDriver", "inversion": "TipperInversionDriver"}, ), "plate simulation": ( - "simpeg_drivers.plate_simulation.driver", + "simpeg_drivers.plate_simulation", {"forward": "PlateSimulationDriver"}, ), "plate sweep": ( - "simpeg_drivers.plate_simulation.sweep.driver", + "simpeg_drivers.plate_simulation.sweep", {"forward": "PlateSweepDriver"}, ), "plate match": ( - "simpeg_drivers.plate_simulation.match.driver", + "simpeg_drivers.plate_simulation.match", {"forward": "PlateMatchDriver"}, ), } diff --git a/simpeg_drivers/components/factories/directives_factory.py b/simpeg_drivers/components/factories/directives_factory.py index 113c2f6d..94834769 100644 --- a/simpeg_drivers/components/factories/directives_factory.py +++ b/simpeg_drivers/components/factories/directives_factory.py @@ -383,7 +383,7 @@ def assemble_arguments( global_misfit=None, name=None, ): - return [inversion_object.entity] + return [inversion_object.entity] if inversion_object else [] class SaveModelGeoh5Factory(SaveGeoh5Factory): @@ -506,7 +506,10 @@ def assemble_keyword_arguments( self, inversion_object=None, name=None, - ): + ) -> dict: + if not inversion_object: + return {} + receivers = inversion_object.entity channels = [ float(val) if val else None diff --git a/simpeg_drivers/driver.py b/simpeg_drivers/driver.py index b25fba1b..62b1a977 100644 --- a/simpeg_drivers/driver.py +++ b/simpeg_drivers/driver.py @@ -25,20 +25,16 @@ from pathlib import Path from time import time -from typing_extensions import Self - import numpy as np from dask.distributed import get_client, Client, LocalCluster, performance_report from geoapps_utils.base import Driver, Options from geoapps_utils.run import load_ui_json_as_dict from geoapps_utils.utils.importing import GeoAppsError -from geoapps_utils.param_sweeps.driver import SweepParams from geoh5py.groups import SimPEGGroup from geoh5py.objects import FEMSurvey from geoh5py.shared.utils import fetch_active_workspace -from geoh5py.ui_json import InputFile from simpeg import ( dask, @@ -78,6 +74,7 @@ from simpeg_drivers.joint.options import BaseJointOptions from simpeg_drivers.utils.nested import tile_locations from simpeg_drivers.utils.regularization import cell_neighbors, set_rotated_operators +from simpeg_drivers.utils.utils import validate_out_group mlogger = logging.getLogger("distributed") mlogger.setLevel(logging.WARNING) @@ -113,7 +110,7 @@ def __init__( self._mappings: list[maps.IdentityMap] | None = None self.tiles: dict[str, list[np.ndarray]] - self.out_group = self.validate_out_group(self.params.out_group) + self.out_group = validate_out_group(self.params) self._client: Client | bool = validate_client(client) if getattr(self.params, "store_sensitivities", None) == "disk" and self.client: @@ -464,8 +461,11 @@ def start_message(self): def run(self): """Run inversion from params""" - sys.stdout = self.logger - self.logger.start() + + if self.logger: + sys.stdout = self.logger + self.logger.start() + with fetch_active_workspace(self.workspace, mode="r+"): if Path(self.params.input_file.path_name).is_file(): self.out_group.add_file(self.params.input_file.path_name) @@ -481,13 +481,13 @@ def run(self): "or increase the number of tiles." ) from error - self.logger.end() - sys.stdout = self.logger.terminal + if self.logger: + self.logger.end() + sys.stdout = self.logger.terminal - with fetch_active_workspace(self.workspace, mode="r+"): - for directive in self.directives.save_directives: - if isinstance(directive, directives.SaveLogFilesGeoH5): - directive.write(1) + if self.directives.save_iteration_log_files: + with fetch_active_workspace(self.workspace, mode="r+"): + self.directives.save_iteration_log_files.write(1) @classmethod def start_dask_run( @@ -506,19 +506,15 @@ def start_dask_run( n_threads = (ui_json.get("n_threads", n_threads),) save_report = (ui_json.get("performance_report", False),) - distributed_process = ( - n_workers is not None and n_workers > 1 - ) or n_threads is not None - - cluster = ( - LocalCluster( + if (n_workers is not None and n_workers > 1) or n_threads is not None: + cluster = LocalCluster( processes=True, n_workers=n_workers, threads_per_worker=n_threads, ) - if distributed_process - else None - ) + else: + cluster = None + profiler = cProfile.Profile() profiler.enable() @@ -546,24 +542,6 @@ def start_dask_run( ps.sort_stats("cumulative") ps.print_stats() - def validate_out_group(self, out_group: SimPEGGroup | None) -> SimPEGGroup: - """ - Validate or create a SimPEGGroup to store results. - - :param out_group: Output group from selection. - """ - if isinstance(out_group, SimPEGGroup): - return out_group - - with fetch_active_workspace(self.params.geoh5, mode="r+"): - out_group = SimPEGGroup.create( - self.params.geoh5, - name=self.params.title, - ) - out_group.entity_type.name = self.params.title - - return out_group - @property def workers(self) -> list[tuple[str]]: """List of workers stored as a list of tuples.""" @@ -599,7 +577,8 @@ def simpeg_run(self): ).write(0) def start_message(self): - self.logger.write("Running the forward simulation ...\n") + if self.logger: + self.logger.write("Running the forward simulation ...\n") class InversionDriver(BaseDriver): diff --git a/simpeg_drivers/electromagnetics/base_1d_driver.py b/simpeg_drivers/electromagnetics/base_1d_driver.py index adcc01db..0e19e2d6 100644 --- a/simpeg_drivers/electromagnetics/base_1d_driver.py +++ b/simpeg_drivers/electromagnetics/base_1d_driver.py @@ -11,14 +11,12 @@ from __future__ import annotations -import multiprocessing from logging import getLogger from pathlib import Path import numpy as np from discretize import TensorMesh from discretize.utils import mesh_utils -from geoapps_utils.run import load_ui_json_as_dict from geoapps_utils.utils.locations import topo_drape_elevation from geoh5py import Workspace from geoh5py.shared.merging.drape_model import DrapeModelMerger @@ -27,7 +25,10 @@ from simpeg_drivers.components.factories import SimulationFactory from simpeg_drivers.components.meshes import InversionMesh from simpeg_drivers.driver import BaseDriver -from simpeg_drivers.utils.utils import xyz_2_drape_model +from simpeg_drivers.utils.utils import ( + get_default_parallelization_params, + xyz_2_drape_model, +) logger = getLogger(__name__) @@ -128,38 +129,11 @@ def simulation(self): return self._simulation - @property - def workers(self): - """List of workers""" - if self._workers is None: - if self.client: - self._workers = [ - (worker.worker_address,) - for worker in self.client.cluster.workers.values() - ] - else: - self._workers = np.arange(multiprocessing.cpu_count()).tolist() - return self._workers - @classmethod def start_dask_run( cls, json_path: Path, n_workers: int | None = None, n_threads: int | None = None ): """Overload configurations of BaseDriver Dask config settings.""" - # Force distributed on 1D problems - ui_json = load_ui_json_as_dict(json_path) - - n_workers = (ui_json.get("n_workers", None),) - n_threads = (ui_json.get("n_threads", None),) - - if n_workers is None: - cpu_count = multiprocessing.cpu_count() - - if cpu_count < 16: - n_threads = n_threads or 2 - else: - n_threads = n_threads or 4 - - n_workers = cpu_count // n_threads + n_workers, n_threads = get_default_parallelization_params(json_path) super().start_dask_run(json_path, n_workers=n_workers, n_threads=n_threads) diff --git a/simpeg_drivers/joint/driver.py b/simpeg_drivers/joint/driver.py index cf1214e9..6d02ecd4 100644 --- a/simpeg_drivers/joint/driver.py +++ b/simpeg_drivers/joint/driver.py @@ -13,9 +13,7 @@ from __future__ import annotations -import sys from logging import getLogger -from pathlib import Path import numpy as np import simpeg.dask.objective_function as dask_objective_function @@ -231,35 +229,6 @@ def n_values(self): return self._n_values - def run(self): - """Run inversion from params""" - if self.logger: - sys.stdout = self.logger - self.logger.start() - - if Path(self.params.input_file.path_name).is_file(): - with fetch_active_workspace(self.workspace, mode="r+"): - self.out_group.add_file(self.params.input_file.path_name) - - if self.params.forward_only: - print("Running the forward simulation ...") - predicted = self.inverse_problem.get_dpred( - self.models.starting_model, compute_J=False - ) - - for sub, driver in zip(predicted, self.drivers, strict=True): - SaveDataGeoh5Factory(driver.params).build( - inversion_object=driver.inversion_data, - ).write(0, sub) - else: - # Run the inversion - self.start_inversion_message() - self.inversion.run(self.models.starting_model) - if self.logger: - self.logger.end() - sys.stdout = self.logger.terminal - self._update_log() - def validate_create_mesh(self): """Function to validate and create the inversion mesh.""" diff --git a/simpeg_drivers/plate_simulation/driver.py b/simpeg_drivers/plate_simulation/driver.py index 87331571..f55b2a23 100644 --- a/simpeg_drivers/plate_simulation/driver.py +++ b/simpeg_drivers/plate_simulation/driver.py @@ -15,26 +15,31 @@ import numpy as np from dask.distributed import Client -from geoapps_utils.base import get_logger +from geoapps_utils.base import Driver, get_logger from geoapps_utils.utils.transformations import azimuth_to_unit_vector from geoh5py.data import FloatData, ReferencedData -from geoh5py.groups import SimPEGGroup from geoh5py.objects import Octree, Points, Surface -from geoh5py.shared.utils import fetch_active_workspace, stringify +from geoh5py.shared.utils import fetch_active_workspace from grid_apps.octree_creation.driver import OctreeDriver -from simpeg_drivers.driver import BaseDriver, InversionDriver, driver_class_from_name +from simpeg_drivers.driver import ( + InversionDriver, + driver_class_from_name, + validate_client, + validate_workers, +) from simpeg_drivers.options import BaseForwardOptions, ModelTypeEnum from simpeg_drivers.plate_simulation.models.events import Anomaly, Erosion, Overburden from simpeg_drivers.plate_simulation.models.parametric import Plate from simpeg_drivers.plate_simulation.models.series import DikeSwarm, Geology from simpeg_drivers.plate_simulation.options import PlateSimulationOptions +from simpeg_drivers.utils.utils import validate_out_group logger = get_logger(__name__, propagate=False) -class PlateSimulationDriver(BaseDriver): +class PlateSimulationDriver(Driver): """ Driver for simulating background + plate + overburden model. @@ -52,21 +57,17 @@ def __init__( client: Client | bool | None = None, workers: list[tuple[str]] | None = None, ): - super().__init__(params, client=client, workers=workers) + super().__init__(params) + self._out_group = validate_out_group(self.params) self._plates: list[Plate] | None = None self._survey: Points | None = None self._mesh: Octree | None = None self._model: FloatData | None = None self._simulation_parameters: BaseForwardOptions | None = None self._simulation_driver: InversionDriver | None = None - - def simpeg_run(self): - """""" - - def start_message(self): - """""" - logger.info("running the simulation...") + self._client: Client | bool = validate_client(client) + self._workers: list[tuple[str]] = validate_workers(self._client, workers) def run(self) -> InversionDriver: """Create octree mesh, fill model, and simulate.""" @@ -80,27 +81,6 @@ def run(self) -> InversionDriver: return self.simulation_driver - def validate_out_group(self, out_group: SimPEGGroup | None) -> SimPEGGroup: - """ - Validate or create a SimPEGGroup to store results. - - :param out_group: Output group from selection. - """ - if isinstance(out_group, SimPEGGroup): - return out_group - - with fetch_active_workspace(self.params.geoh5, mode="r+"): - out_group = SimPEGGroup.create( - self.params.geoh5, - name="Plate Simulation", - ) - out_group.entity_type.name = "Plate Simulation" - self.params = self.params.model_copy(update={"out_group": out_group}) - out_group.options = stringify(self.params.input_file.ui_json) - out_group.metadata = None - - return out_group - @property def simulation_driver(self) -> InversionDriver: if self._simulation_driver is None: @@ -121,7 +101,9 @@ def simulation_driver(self) -> InversionDriver: self.simulation_parameters.inversion_type, forward_only=True ) self._simulation_driver = driver_class( - self.simulation_parameters, client=self.client, workers=self.workers + self.simulation_parameters, + client=self._client, + workers=self._workers, ) self._simulation_driver.out_group.parent = self.out_group @@ -297,6 +279,8 @@ def replicate( return plates +PlateSimulationDriver.start_dask_run = InversionDriver.start_dask_run + if __name__ == "__main__": file = Path(sys.argv[1]) - PlateSimulationDriver.start(file) + PlateSimulationDriver.start_dask_run(file) diff --git a/simpeg_drivers/plate_simulation/match/driver.py b/simpeg_drivers/plate_simulation/match/driver.py index a6f31229..03b27248 100644 --- a/simpeg_drivers/plate_simulation/match/driver.py +++ b/simpeg_drivers/plate_simulation/match/driver.py @@ -10,20 +10,19 @@ from __future__ import annotations -import multiprocessing import sys from pathlib import Path from typing import Self import numpy as np -from dask.distributed import Future, progress -from geoapps_utils.run import load_ui_json_as_dict +from dask.distributed import Client, Future, progress +from geoapps_utils.base import Driver from geoapps_utils.utils.importing import GeoAppsError from geoapps_utils.utils.locations import topo_drape_elevation from geoapps_utils.utils.logger import get_logger from geoapps_utils.utils.numerical import inverse_weighted_operator from geoapps_utils.utils.plotting import symlog -from geoapps_utils.utils.transformations import cartesian_to_polar, rotate_xyz +from geoapps_utils.utils.transformations import cartesian_to_polar from geoh5py import Workspace from geoh5py.groups import PropertyGroup, SimPEGGroup from geoh5py.objects import AirborneTEMReceivers, MaxwellPlate, Surface @@ -33,24 +32,35 @@ from scipy.sparse import csr_matrix from scipy.spatial import cKDTree -from simpeg_drivers.driver import BaseDriver +from simpeg_drivers.driver import BaseDriver, validate_client, validate_workers from simpeg_drivers.electromagnetics.time_domain.options import CONVERSION from simpeg_drivers.plate_simulation.match.options import PlateMatchOptions from simpeg_drivers.plate_simulation.options import ModelOptions, PlateSimulationOptions +from simpeg_drivers.utils.utils import ( + get_default_parallelization_params, + validate_out_group, +) logger = get_logger(name=__name__, level_name=False, propagate=False, add_name=False) -class PlateMatchDriver(BaseDriver): +class PlateMatchDriver(Driver): """Sets up and manages workers to run all combinations of swept parameters.""" _params_class = PlateMatchOptions def __init__( - self, params: PlateMatchOptions, workers: list[tuple[str]] | None = None + self, + params: PlateMatchOptions, + client: Client | bool | None = None, + workers: list[tuple[str]] | None = None, ): - super().__init__(params, workers=workers) + super().__init__(params) + + self._out_group = validate_out_group(self.params) + self._client: Client | bool = validate_client(client) + self._workers: list[tuple[str]] = validate_workers(self._client, workers) self._drape_heights = self._get_drape_heights() self._template = self.get_template() @@ -132,6 +142,16 @@ def spatial_mask_and_projection( ) return indices, spatial_projection + def simpeg_run(self): + """ + Run call to simpeg. + """ + + def start_message(self): + """ + Starting message displayed by the logger. + """ + @classmethod def start(cls, filepath: str | Path, mode="r+", **_) -> Self: """Start the parameter matching from a ui.json file.""" @@ -326,31 +346,6 @@ def run(self): return out - @classmethod - def start_dask_run( - cls, - json_path: Path, - n_workers: int | None = None, - n_threads: int | None = None, - ): - """Overload configurations of BaseDriver Dask config settings.""" - ui_json = load_ui_json_as_dict(json_path) - - n_workers = (ui_json.get("n_workers", None),) - n_threads = (ui_json.get("n_threads", None),) - - if n_workers is None: - cpu_count = multiprocessing.cpu_count() - - if cpu_count < 16: - n_threads = n_threads or 2 - else: - n_threads = n_threads or 4 - - n_workers = cpu_count // n_threads - - super().start_dask_run(json_path, n_workers=n_workers, n_threads=n_threads) - def run_scores(self, spatial_projection, data) -> tuple[np.ndarray, np.ndarray]: """ Run the scoring function for all simulation files in parallel using Dask. @@ -361,7 +356,7 @@ def run_scores(self, spatial_projection, data) -> tuple[np.ndarray, np.ndarray]: :return: Tuple of scores and corresponding center indices for each simulation file. """ file_split = np.array_split( - self.params.simulation_files, np.maximum(1, len(self.workers) * 10) + self.params.simulation_files, np.maximum(1, len(self._workers) * 10) ) tasks = [] for file_batch in file_split: @@ -373,21 +368,24 @@ def run_scores(self, spatial_projection, data) -> tuple[np.ndarray, np.ndarray]: ) tasks.append( - self.client.submit(batch_files_score, *args) - if self.client + self._client.submit(batch_files_score, *args) + if self._client else batch_files_score(*args) ) # Display progress bar if isinstance(tasks[0], Future): progress(tasks) - tasks = self.client.gather(tasks) + tasks = self._client.gather(tasks) scores, centers = np.vstack(tasks).T return scores, centers +PlateMatchDriver.start_dask_run = BaseDriver.start_dask_run + + def is_up_dip(data: np.ndarray) -> bool: """ Prepare data for scoring by checking for multiple channels and normalizing. @@ -516,4 +514,7 @@ def batch_files_score( if __name__ == "__main__": file = Path(sys.argv[1]).resolve() - PlateMatchDriver.start_dask_run(file) + + n_workers, n_threads = get_default_parallelization_params(file) + + PlateMatchDriver.start_dask_run(file, n_workers=n_workers, n_threads=n_threads) diff --git a/simpeg_drivers/plate_simulation/options.py b/simpeg_drivers/plate_simulation/options.py index 2a4d3517..792383e1 100644 --- a/simpeg_drivers/plate_simulation/options.py +++ b/simpeg_drivers/plate_simulation/options.py @@ -38,8 +38,8 @@ from simpeg_drivers.natural_sources.tipper.options import TipperForwardOptions from simpeg_drivers.options import BaseForwardOptions from simpeg_drivers.potential_fields.gravity.options import GravityForwardOptions -from simpeg_drivers.potential_fields.magnetic_vector.options import ( - MVIForwardOptions, +from simpeg_drivers.potential_fields.magnetic_vector import ( + MagneticVectorForwardOptions, ) from .models.options import ModelOptions @@ -52,7 +52,7 @@ "fem": FDEMForwardOptions, "magnetotellurics": MTForwardOptions, "direct current 3d": DC3DForwardOptions, - "magnetic vector": MVIForwardOptions, + "magnetic vector": MagneticVectorForwardOptions, "tipper": TipperForwardOptions, } diff --git a/simpeg_drivers/plate_simulation/sweep/driver.py b/simpeg_drivers/plate_simulation/sweep/driver.py index 04e22c77..76018108 100644 --- a/simpeg_drivers/plate_simulation/sweep/driver.py +++ b/simpeg_drivers/plate_simulation/sweep/driver.py @@ -17,6 +17,8 @@ from typing import Self import numpy as np +from dask.distributed import Client +from geoapps_utils.base import Driver from geoapps_utils.utils.importing import GeoAppsError from geoapps_utils.utils.logger import get_logger from geoh5py import Workspace @@ -30,26 +32,44 @@ from h5py import File from pandas import DataFrame -from simpeg_drivers.driver import BaseDriver +from simpeg_drivers.driver import BaseDriver, validate_client, validate_workers from simpeg_drivers.plate_simulation.driver import PlateSimulationDriver from simpeg_drivers.plate_simulation.options import PlateSimulationOptions from simpeg_drivers.plate_simulation.sweep.options import SweepOptions from simpeg_drivers.plate_simulation.sweep.uijson import PlateSweepUIJson +from simpeg_drivers.utils.utils import validate_out_group logger = get_logger(name=__name__, level_name=False, propagate=False, add_name=False) # TODO: Can we make this generic (PlateSweepDriver -> SweepDriver)? -class PlateSweepDriver(BaseDriver): +class PlateSweepDriver(Driver): """Sets up and manages workers to run all combinations of swepts parameters.""" _params_class = SweepOptions - def __init__(self, params: SweepOptions, workers: list[tuple[str]] | None = None): - super().__init__(params, workers=workers) + def __init__( + self, + params: SweepOptions, + client: Client | bool | None = None, + workers: list[tuple[str]] | None = None, + ): + super().__init__(params) - self.out_group = self.validate_out_group(self.params.out_group) + self._out_group = validate_out_group(self.params) + self._client: Client | bool = validate_client(client) + self._workers: list[tuple[str]] = validate_workers(self._client, workers) + + def simpeg_run(self): + """ + Run call to simpeg. + """ + + def start_message(self): + """ + Starting message displayed by the logger. + """ @classmethod def start(cls, filepath: str | Path, mode="r", **_) -> Self: @@ -83,10 +103,10 @@ def run(self): self.params.template.options["title"], ) - use_futures = self.client + use_futures = self._client if use_futures and trials: - blocks = np.array_split(trials, len(self.workers)) + blocks = np.array_split(trials, len(self._workers)) else: blocks = trials @@ -94,13 +114,13 @@ def run(self): for ind, block in enumerate(blocks): if use_futures: futures.append( - self.client.submit( + self._client.submit( run_block, block, self.params.geoh5.h5file, self.params.workdir, - self.workers[ind], - workers=self.workers[ind], + self._workers[ind], + workers=self._workers[ind], ) ) @@ -112,7 +132,7 @@ def run(self): ) if use_futures: - self.client.gather(futures) + self._client.gather(futures) if self.params.generate_summary: summary = generate_summary(self.params.workdir.iterdir()) @@ -152,7 +172,7 @@ def run_trial( group for group in workspace.groups if isinstance(group, SimPEGGroup | UIJsonGroup) - and "plate simulation" == group.options.get("inversion_type") + and "plate_simulation.driver" in group.options.get("run_command") ) opt_dict = workspace.promote(flatten(plate_simulation.options)) @@ -173,6 +193,9 @@ def run_trial( return None +PlateSweepDriver.start_dask_run = BaseDriver.start_dask_run + + def forms_to_values(data: dict) -> dict: """ Convert a dictionary of forms to a dictionary of values, where the value is a number. @@ -235,4 +258,4 @@ def run_block( if __name__ == "__main__": file = Path(sys.argv[1]) - PlateSweepDriver.start(file) + PlateSweepDriver.start_dask_run(file) diff --git a/simpeg_drivers/utils/utils.py b/simpeg_drivers/utils/utils.py index 3d200bde..1c2bea4b 100644 --- a/simpeg_drivers/utils/utils.py +++ b/simpeg_drivers/utils/utils.py @@ -11,13 +11,17 @@ from __future__ import annotations +import multiprocessing from collections.abc import Sequence from copy import deepcopy +from pathlib import Path from typing import TYPE_CHECKING import numpy as np from discretize import TensorMesh, TreeMesh from discretize.utils import mesh_utils +from geoapps_utils.base import Options +from geoapps_utils.run import load_ui_json_as_dict from geoapps_utils.utils.locations import mask_under_horizon from geoapps_utils.utils.numerical import running_mean, traveling_salesman from geoh5py import Workspace @@ -30,6 +34,7 @@ ) from geoh5py.objects.surveys.electromagnetics.base import LargeLoopGroundEMSurvey from geoh5py.shared import INTEGER_NDV +from geoh5py.shared.utils import fetch_active_workspace, stringify from geoh5py.ui_json import InputFile from grid_apps.utils import octree_2_treemesh from scipy.interpolate import interp1d @@ -661,3 +666,52 @@ def compute_alongline_distance(points: np.ndarray, ordered: bool = True) -> np.n distances = np.c_[distances, points[:, 2:]] return distances + + +def get_default_parallelization_params(json_path: Path) -> tuple[int, int]: + """ + Get parallelization parameters from a ui_json file. + + If the number of workers is unset, it is estimated from the number of CPU cores. + + :param json_path: Path to ui_json file. + :returns: Tuple of parallelization parameters. + """ + ui_json = load_ui_json_as_dict(json_path) + + n_workers = (ui_json.get("n_workers", None),) + n_threads = (ui_json.get("n_threads", None),) + + if n_workers is None: + cpu_count = multiprocessing.cpu_count() + + if cpu_count < 16: + n_threads = n_threads or 2 + else: + n_threads = n_threads or 4 + + n_workers = cpu_count // n_threads + + return n_workers, n_threads + + +def validate_out_group(options: Options) -> SimPEGGroup: + """ + Validate or create a SimPEGGroup to store results. + + :param out_group: Output group from selection. + """ + if isinstance(options.out_group, SimPEGGroup): + return options.out_group + + with fetch_active_workspace(options.geoh5, mode="r+"): + out_group = SimPEGGroup.create( + options.geoh5, + name=options.title, + ) + out_group.entity_type.name = options.title + options = options.model_copy(update={"out_group": out_group}) + out_group.options = stringify(options.input_file.ui_json) + out_group.metadata = None + + return out_group diff --git a/tests/data_test.py b/tests/data_test.py index 1c4ad44b..6bd9bc15 100644 --- a/tests/data_test.py +++ b/tests/data_test.py @@ -25,11 +25,9 @@ DC3DForwardOptions, ) from simpeg_drivers.options import ActiveCellsOptions -from simpeg_drivers.potential_fields.magnetic_vector.driver import ( - MVIInversionDriver, -) -from simpeg_drivers.potential_fields.magnetic_vector.options import ( - MVIInversionOptions, +from simpeg_drivers.potential_fields.magnetic_vector import ( + MagneticVectorInversionDriver, + MagneticVectorInversionOptions, ) from simpeg_drivers.utils.synthetics.driver import SyntheticsComponents from simpeg_drivers.utils.synthetics.options import ( @@ -41,7 +39,7 @@ from tests.utils.targets import get_workspace -def get_mvi_params(tmp_path: Path, **kwargs) -> MVIInversionOptions: +def get_mvi_params(tmp_path: Path, **kwargs) -> MagneticVectorInversionOptions: with get_workspace(tmp_path / "inversion_test.ui.geoh5") as geoh5: opts = SyntheticsComponentsOptions( method="magnetic_vector", @@ -55,7 +53,7 @@ def get_mvi_params(tmp_path: Path, **kwargs) -> MVIInversionOptions: tmi_channel = components.survey.add_data( {"tmi": {"values": np.random.rand(components.survey.n_vertices)}} ) - params = MVIInversionOptions.build( + params = MagneticVectorInversionOptions.build( geoh5=geoh5, data_object=components.survey, tmi_channel=tmi_channel, @@ -128,7 +126,7 @@ def test_survey_data(tmp_path: Path): active_cells = ActiveCellsOptions( topography_object=test_topo_object, topography=topo ) - params = MVIInversionOptions.build( + params = MagneticVectorInversionOptions.build( geoh5=workspace, data_object=test_data_object, active_cells=active_cells, @@ -146,7 +144,7 @@ def test_survey_data(tmp_path: Path): inducing_field_declination=30.0, ) - driver = MVIInversionDriver(params) + driver = MagneticVectorInversionDriver(params) assert driver.inversion is not None diff --git a/tests/driver_test.py b/tests/driver_test.py index 808fcdbd..c4488b35 100644 --- a/tests/driver_test.py +++ b/tests/driver_test.py @@ -11,10 +11,11 @@ from pathlib import Path import numpy as np -from geoh5py import Workspace -from simpeg_drivers.potential_fields import GravityInversionOptions -from simpeg_drivers.potential_fields.gravity.driver import GravityInversionDriver +from simpeg_drivers.potential_fields.gravity import ( + GravityInversionDriver, + GravityInversionOptions, +) from simpeg_drivers.utils.synthetics.driver import SyntheticsComponents from simpeg_drivers.utils.synthetics.options import ( MeshOptions, diff --git a/tests/locations_test.py b/tests/locations_test.py index 81e34642..45fe8a68 100644 --- a/tests/locations_test.py +++ b/tests/locations_test.py @@ -18,7 +18,9 @@ from geoh5py.objects import Curve, Grid2D, Points from simpeg_drivers.components.locations import InversionLocations -from simpeg_drivers.potential_fields import MVIInversionOptions +from simpeg_drivers.potential_fields.magnetic_vector import ( + MagneticVectorInversionOptions, +) from simpeg_drivers.utils.nested import tile_locations from simpeg_drivers.utils.synthetics.driver import SyntheticsComponents from simpeg_drivers.utils.synthetics.options import ( @@ -30,7 +32,7 @@ from tests.utils.targets import get_workspace -def get_mvi_params(tmp_path: Path) -> MVIInversionOptions: +def get_mvi_params(tmp_path: Path) -> MagneticVectorInversionOptions: opts = SyntheticsComponentsOptions( method="magnetic_vector", survey=SurveyOptions(n_lines=2, n_stations=2), @@ -42,7 +44,7 @@ def get_mvi_params(tmp_path: Path) -> MVIInversionOptions: tmi_channel = components.survey.add_data( {"tmi": {"values": np.random.rand(components.survey.n_vertices)}} ) - params = MVIInversionOptions.build( + params = MagneticVectorInversionOptions.build( geoh5=geoh5, data_object=components.survey, tmi_channel=tmi_channel, diff --git a/tests/meshes_test.py b/tests/meshes_test.py index 60da407e..f2a39511 100644 --- a/tests/meshes_test.py +++ b/tests/meshes_test.py @@ -20,9 +20,10 @@ from grid_apps.utils import treemesh_2_octree from simpeg_drivers.components import InversionMesh -from simpeg_drivers.options import ActiveCellsOptions -from simpeg_drivers.potential_fields import MVIInversionOptions -from simpeg_drivers.potential_fields.magnetic_vector.driver import MVIInversionDriver +from simpeg_drivers.potential_fields.magnetic_vector import ( + MagneticVectorInversionDriver, + MagneticVectorInversionOptions, +) from simpeg_drivers.utils.synthetics.driver import SyntheticsComponents from simpeg_drivers.utils.synthetics.options import ( MeshOptions, @@ -33,7 +34,7 @@ from tests.utils.targets import get_workspace -def get_mvi_params(tmp_path: Path, updates=None) -> MVIInversionOptions: +def get_mvi_params(tmp_path: Path, updates=None) -> MagneticVectorInversionOptions: opts = SyntheticsComponentsOptions( method="magnetic_vector", survey=SurveyOptions(n_stations=4, n_lines=4), @@ -68,7 +69,7 @@ def get_mvi_params(tmp_path: Path, updates=None) -> MVIInversionOptions: } if updates is not None: kwargs.update(updates) - params = MVIInversionOptions.build(**kwargs) + params = MagneticVectorInversionOptions.build(**kwargs) return params @@ -240,4 +241,4 @@ def test_handle_grid2d(tmp_path): updates = {"mesh": None, "topography_object": topo, "topography": elev} params = get_mvi_params(tmp_path, updates=updates) - MVIInversionDriver(params) # Doesn't crash + MagneticVectorInversionDriver(params) # Doesn't crash diff --git a/tests/models_test.py b/tests/models_test.py index c5c0a328..ee7597da 100644 --- a/tests/models_test.py +++ b/tests/models_test.py @@ -29,9 +29,9 @@ DC3DForwardOptions, ) from simpeg_drivers.options import ActiveCellsOptions -from simpeg_drivers.potential_fields import MVIInversionOptions -from simpeg_drivers.potential_fields.magnetic_vector.driver import ( - MVIInversionDriver, +from simpeg_drivers.potential_fields.magnetic_vector import ( + MagneticVectorInversionDriver, + MagneticVectorInversionOptions, ) from simpeg_drivers.utils.synthetics.driver import SyntheticsComponents from simpeg_drivers.utils.synthetics.options import ( @@ -43,7 +43,7 @@ from tests.utils.targets import get_workspace -def get_mvi_params(tmp_path: Path) -> MVIInversionOptions: +def get_mvi_params(tmp_path: Path) -> MagneticVectorInversionOptions: opts = SyntheticsComponentsOptions( method="magnetic_vector", survey=SurveyOptions(n_stations=2, n_lines=2), @@ -67,7 +67,7 @@ def get_mvi_params(tmp_path: Path) -> MVIInversionOptions: elevation = components.topography.add_data( {"elevation": {"values": components.topography.vertices[:, 2]}} ) - params = MVIInversionOptions.build( + params = MagneticVectorInversionOptions.build( geoh5=geoh5, data_object=components.survey, tmi_channel=tmi_channel, @@ -88,7 +88,7 @@ def get_mvi_params(tmp_path: Path) -> MVIInversionOptions: return params -def get_dc_params(tmp_path: Path) -> MVIInversionOptions: +def get_dc_params(tmp_path: Path) -> MagneticVectorInversionOptions: opts = SyntheticsComponentsOptions( method="direct_current", survey=SurveyOptions(n_stations=4, n_lines=2), @@ -124,7 +124,7 @@ def test_zero_reference_model(tmp_path: Path): params = get_mvi_params(tmp_path) geoh5 = params.geoh5 with geoh5.open(): - driver = MVIInversionDriver(params) + driver = MagneticVectorInversionDriver(params) _ = InversionModel(driver, "reference_model") incl = np.unique(geoh5.get_entity("reference_inclination")[0].values) decl = np.unique(geoh5.get_entity("reference_declination")[0].values) @@ -137,7 +137,7 @@ def test_zero_reference_model(tmp_path: Path): def test_collection(tmp_path: Path): params = get_mvi_params(tmp_path) with params.geoh5.open(): - driver = MVIInversionDriver(params) + driver = MagneticVectorInversionDriver(params) models = InversionModelCollection(driver) models.remove_air(driver.models.active_cells) starting = InversionModel(driver, "starting_model") @@ -153,7 +153,7 @@ def test_collection(tmp_path: Path): def test_initialize(tmp_path: Path): params = get_mvi_params(tmp_path) with params.geoh5.open(): - driver = MVIInversionDriver(params) + driver = MagneticVectorInversionDriver(params) starting_model = InversionModel(driver, "starting_model") assert len(starting_model.model) == driver.inversion_mesh.n_cells assert len(np.unique(starting_model.model)) == 1 @@ -164,7 +164,7 @@ def test_model_from_object(tmp_path: Path): params = get_mvi_params(tmp_path) geoh5 = params.geoh5 with geoh5.open(): - driver = MVIInversionDriver(params) + driver = MagneticVectorInversionDriver(params) inversion_mesh = InversionMesh(geoh5, params) cc = inversion_mesh.mesh.cell_centers diff --git a/tests/plate_simulation/runtest/driver_test.py b/tests/plate_simulation/runtest/driver_test.py index 18f968c0..9eae3291 100644 --- a/tests/plate_simulation/runtest/driver_test.py +++ b/tests/plate_simulation/runtest/driver_test.py @@ -8,7 +8,6 @@ # ' # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' -from geoh5py import Workspace from geoh5py.groups import SimPEGGroup from geoh5py.ui_json import InputFile diff --git a/tests/plate_simulation/runtest/match_test.py b/tests/plate_simulation/runtest/match_test.py index 45a8d221..d122ebce 100644 --- a/tests/plate_simulation/runtest/match_test.py +++ b/tests/plate_simulation/runtest/match_test.py @@ -21,8 +21,10 @@ from scipy import signal from simpeg_drivers import assets_path -from simpeg_drivers.electromagnetics.time_domain.driver import TDEMForwardDriver -from simpeg_drivers.electromagnetics.time_domain.options import TDEMForwardOptions +from simpeg_drivers.electromagnetics.time_domain import ( + TDEMForwardDriver, + TDEMForwardOptions, +) from simpeg_drivers.plate_simulation.driver import PlateSimulationDriver from simpeg_drivers.plate_simulation.match.driver import PlateMatchDriver, fetch_survey from simpeg_drivers.plate_simulation.match.options import PlateMatchOptions diff --git a/tests/run_tests/driver_joint_surveys_test.py b/tests/run_tests/driver_joint_surveys_test.py index e8f9dd16..8dedff90 100644 --- a/tests/run_tests/driver_joint_surveys_test.py +++ b/tests/run_tests/driver_joint_surveys_test.py @@ -27,6 +27,7 @@ from simpeg_drivers.joint.joint_surveys.driver import JointSurveyDriver from simpeg_drivers.options import ActiveCellsOptions from simpeg_drivers.potential_fields.gravity import ( + GravityForwardDriver, GravityForwardOptions, GravityInversionDriver, GravityInversionOptions, @@ -80,7 +81,7 @@ def test_joint_surveys_fwr_run( data_object=components.survey, starting_model=components.model, ) - fwr_driver_a = GravityInversionDriver(params) + fwr_driver_a = GravityForwardDriver(params) with fwr_driver_a.out_group.workspace.open(): fwr_driver_a.out_group.name = "Gravity Forward [0]" @@ -107,7 +108,7 @@ def test_joint_surveys_fwr_run( data_object=components.survey, starting_model=components.model, ) - fwr_driver_b = GravityInversionDriver(params) + fwr_driver_b = GravityForwardDriver(params) with fwr_driver_b.out_group.workspace.open(): # Force co-location of meshes diff --git a/tests/topography_test.py b/tests/topography_test.py index 25302fdd..90b68c9e 100644 --- a/tests/topography_test.py +++ b/tests/topography_test.py @@ -17,7 +17,9 @@ from simpeg_drivers.components import InversionData, InversionMesh, InversionTopography from simpeg_drivers.options import ActiveCellsOptions -from simpeg_drivers.potential_fields import MVIInversionOptions +from simpeg_drivers.potential_fields.magnetic_vector import ( + MagneticVectorInversionOptions, +) from simpeg_drivers.utils.synthetics.driver import SyntheticsComponents from simpeg_drivers.utils.synthetics.options import ( MeshOptions, @@ -46,7 +48,7 @@ def test_get_locations(tmp_path: Path): elevation = components.topography.add_data( {"elevation": {"values": components.topography.vertices[:, 2]}} ) - params = MVIInversionOptions.build( + params = MagneticVectorInversionOptions.build( geoh5=geoh5, mesh=components.mesh, data_object=components.survey, diff --git a/tests/uijson_test.py b/tests/uijson_test.py index c1084d5f..ee99b003 100644 --- a/tests/uijson_test.py +++ b/tests/uijson_test.py @@ -23,10 +23,8 @@ from pydantic import AliasChoices, Field import simpeg_drivers -from simpeg_drivers.driver import InversionDriver +from simpeg_drivers.driver import from_input_file from simpeg_drivers.options import Deprecations, IRLSOptions -from simpeg_drivers.potential_fields.gravity.options import GravityInversionOptions -from simpeg_drivers.potential_fields.gravity.uijson import GravityInversionUIJson from simpeg_drivers.uijson import SimPEGDriversUIJson from simpeg_drivers.utils.synthetics.driver import SyntheticsComponents from simpeg_drivers.utils.synthetics.options import ( @@ -36,7 +34,6 @@ SurveyOptions, SyntheticsComponentsOptions, ) -from tests.utils.targets import get_workspace logger = logging.getLogger(__name__) @@ -247,47 +244,6 @@ class MyUIJson(SimPEGDriversUIJson): assert "myParam" not in uijson.model_dump() -def test_gravity_uijson(tmp_path): - import warnings - - warnings.filterwarnings("error") - opts = SyntheticsComponentsOptions( - method="gravity", model=ModelOptions(anomaly=0.75) - ) - with get_workspace(tmp_path / "inversion_test.ui.geoh5") as geoh5: - components = SyntheticsComponents(geoh5, options=opts) - gz_channel = components.survey.add_data( - {"gz": {"values": np.ones(components.survey.n_vertices)}} - ) - gz_uncerts = components.survey.add_data( - {"gz_unc": {"values": np.ones(components.survey.n_vertices)}} - ) - - opts = GravityInversionOptions.build( - version="old news", - geoh5=geoh5, - data_object=components.survey, - gz_channel=gz_channel, - gz_uncertainty=gz_uncerts, - mesh=components.mesh, - starting_model=components.model, - topography_object=components.topography, - ) - params_uijson_path = tmp_path / "from_params.ui.json" - opts.write_ui_json(params_uijson_path) - - uijson = GravityInversionUIJson.read(params_uijson_path) - uijson_path = tmp_path / "from_uijson.ui.json" - uijson.write(uijson_path) - with open(params_uijson_path, encoding="utf-8") as f: - params_data = json.load(f) - assert Version(params_data["version"]) == Version(_current_version().public) - with open(uijson_path, encoding="utf-8") as f: - uijson_data = json.load(f) - - assert uijson_data == params_data - - CHANNEL_NAME = { "direct current pseudo 3d": "potential", "direct current 3d": "potential", @@ -390,7 +346,7 @@ def test_legacy_uijson(tmp_path: Path, caplog): ifile.data[CHANNEL_NAME[inversion_type] + "_channel"] = channel ifile.data[CHANNEL_NAME[inversion_type] + "_uncertainty"] = channel - driver = InversionDriver.from_input_file(ifile.data) + driver = from_input_file(ifile.data) with caplog.at_level(logging.WARNING): params = driver._params_class.build(ifile) # pylint: disable=protected-access From bafd9f65ba515bbc20094d6d91c73d1853ff189d Mon Sep 17 00:00:00 2001 From: domfournier Date: Fri, 20 Mar 2026 13:11:03 -0700 Subject: [PATCH 09/18] Updare run_commands in uijson --- .../uijson/apparent_conductivity_forward.ui.json | 2 +- .../uijson/apparent_conductivity_inversion.ui.json | 2 +- simpeg_drivers-assets/uijson/direct_current_2d_forward.ui.json | 2 +- .../uijson/direct_current_2d_inversion.ui.json | 2 +- simpeg_drivers-assets/uijson/fdem1d_forward.ui.json | 2 +- simpeg_drivers-assets/uijson/fdem1d_inversion.ui.json | 2 +- simpeg_drivers-assets/uijson/fdem_forward.ui.json | 2 +- simpeg_drivers-assets/uijson/fdem_inversion.ui.json | 2 +- simpeg_drivers-assets/uijson/gravity_forward.ui.json | 2 +- simpeg_drivers-assets/uijson/gravity_inversion.ui.json | 2 +- .../uijson/induced_polarization_2d_forward.ui.json | 2 +- .../uijson/induced_polarization_2d_inversion.ui.json | 2 +- .../uijson/induced_polarization_3d_forward.ui.json | 2 +- .../uijson/induced_polarization_3d_inversion.ui.json | 2 +- .../uijson/joint_cross_gradient_inversion.ui.json | 2 +- .../uijson/joint_petrophysics_inversion.ui.json | 2 +- simpeg_drivers-assets/uijson/joint_surveys_inversion.ui.json | 2 +- simpeg_drivers-assets/uijson/magnetic_scalar_forward.ui.json | 2 +- simpeg_drivers-assets/uijson/magnetic_scalar_inversion.ui.json | 2 +- simpeg_drivers-assets/uijson/magnetic_vector_forward.ui.json | 2 +- simpeg_drivers-assets/uijson/magnetic_vector_inversion.ui.json | 2 +- simpeg_drivers-assets/uijson/magnetotellurics_forward.ui.json | 2 +- simpeg_drivers-assets/uijson/magnetotellurics_inversion.ui.json | 2 +- simpeg_drivers-assets/uijson/plate_sweep.ui.json | 2 +- simpeg_drivers-assets/uijson/tdem1d_forward.ui.json | 2 +- simpeg_drivers-assets/uijson/tdem1d_inversion.ui.json | 2 +- simpeg_drivers-assets/uijson/tdem_forward.ui.json | 2 +- simpeg_drivers-assets/uijson/tdem_inversion.ui.json | 2 +- simpeg_drivers-assets/uijson/tipper_forward.ui.json | 2 +- simpeg_drivers-assets/uijson/tipper_inversion.ui.json | 2 +- 30 files changed, 30 insertions(+), 30 deletions(-) diff --git a/simpeg_drivers-assets/uijson/apparent_conductivity_forward.ui.json b/simpeg_drivers-assets/uijson/apparent_conductivity_forward.ui.json index 040a319c..0007c916 100644 --- a/simpeg_drivers-assets/uijson/apparent_conductivity_forward.ui.json +++ b/simpeg_drivers-assets/uijson/apparent_conductivity_forward.ui.json @@ -4,7 +4,7 @@ "icon": "surveyztem", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.natural_sources.apparent_conductivity.forward", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/apparent_conductivity_inversion.ui.json b/simpeg_drivers-assets/uijson/apparent_conductivity_inversion.ui.json index e70110da..145a3cd4 100644 --- a/simpeg_drivers-assets/uijson/apparent_conductivity_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/apparent_conductivity_inversion.ui.json @@ -4,7 +4,7 @@ "icon": "surveyztem", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.natural_sources.apparent_conductivity.inversion", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/direct_current_2d_forward.ui.json b/simpeg_drivers-assets/uijson/direct_current_2d_forward.ui.json index 59c96f0d..c06ffe1e 100644 --- a/simpeg_drivers-assets/uijson/direct_current_2d_forward.ui.json +++ b/simpeg_drivers-assets/uijson/direct_current_2d_forward.ui.json @@ -4,7 +4,7 @@ "icon": "PotentialElectrode", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.electricals.direct_current.two_dimensions.forward", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/direct_current_2d_inversion.ui.json b/simpeg_drivers-assets/uijson/direct_current_2d_inversion.ui.json index 2ef58b7a..83f9d62f 100644 --- a/simpeg_drivers-assets/uijson/direct_current_2d_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/direct_current_2d_inversion.ui.json @@ -4,7 +4,7 @@ "icon": "PotentialElectrode", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.electricals.direct_current.two_dimensions.inversion", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/fdem1d_forward.ui.json b/simpeg_drivers-assets/uijson/fdem1d_forward.ui.json index d8c38f83..11512518 100644 --- a/simpeg_drivers-assets/uijson/fdem1d_forward.ui.json +++ b/simpeg_drivers-assets/uijson/fdem1d_forward.ui.json @@ -4,7 +4,7 @@ "icon": "surveyairborneem", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.electromagnetics.frequency_domain_1d.forward", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/fdem1d_inversion.ui.json b/simpeg_drivers-assets/uijson/fdem1d_inversion.ui.json index 0c40fe26..2aad0a3e 100644 --- a/simpeg_drivers-assets/uijson/fdem1d_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/fdem1d_inversion.ui.json @@ -4,7 +4,7 @@ "icon": "surveyairborneem", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.electromagnetics.frequency_domain_1d.inversion", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/fdem_forward.ui.json b/simpeg_drivers-assets/uijson/fdem_forward.ui.json index 103c7f1b..a60b92c8 100644 --- a/simpeg_drivers-assets/uijson/fdem_forward.ui.json +++ b/simpeg_drivers-assets/uijson/fdem_forward.ui.json @@ -4,7 +4,7 @@ "icon": "surveyairborneem", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.electromagnetics.frequency_domain.forward", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/fdem_inversion.ui.json b/simpeg_drivers-assets/uijson/fdem_inversion.ui.json index f42e6a7a..b7cd0624 100644 --- a/simpeg_drivers-assets/uijson/fdem_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/fdem_inversion.ui.json @@ -4,7 +4,7 @@ "icon": "surveyairborneem", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.electromagnetics.frequency_domain.inversion", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/gravity_forward.ui.json b/simpeg_drivers-assets/uijson/gravity_forward.ui.json index dd5918d9..b844d141 100644 --- a/simpeg_drivers-assets/uijson/gravity_forward.ui.json +++ b/simpeg_drivers-assets/uijson/gravity_forward.ui.json @@ -4,7 +4,7 @@ "icon": "surveyairbornegravity", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.potential_fields.gravity.forward", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/gravity_inversion.ui.json b/simpeg_drivers-assets/uijson/gravity_inversion.ui.json index a2fd3e1a..37e94675 100644 --- a/simpeg_drivers-assets/uijson/gravity_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/gravity_inversion.ui.json @@ -4,7 +4,7 @@ "icon": "surveyairbornegravity", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.potential_fields.gravity.inversion", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/induced_polarization_2d_forward.ui.json b/simpeg_drivers-assets/uijson/induced_polarization_2d_forward.ui.json index 9a9ef4de..0bb4a1da 100644 --- a/simpeg_drivers-assets/uijson/induced_polarization_2d_forward.ui.json +++ b/simpeg_drivers-assets/uijson/induced_polarization_2d_forward.ui.json @@ -4,7 +4,7 @@ "icon": "PotentialElectrode", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.electricals.induced_polarization.two_dimensions.forward", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/induced_polarization_2d_inversion.ui.json b/simpeg_drivers-assets/uijson/induced_polarization_2d_inversion.ui.json index 1e3d6d3d..051734a3 100644 --- a/simpeg_drivers-assets/uijson/induced_polarization_2d_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/induced_polarization_2d_inversion.ui.json @@ -4,7 +4,7 @@ "icon": "PotentialElectrode", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.electricals.induced_polarization.two_dimensions.inversion", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/induced_polarization_3d_forward.ui.json b/simpeg_drivers-assets/uijson/induced_polarization_3d_forward.ui.json index d38ef876..d4da081f 100644 --- a/simpeg_drivers-assets/uijson/induced_polarization_3d_forward.ui.json +++ b/simpeg_drivers-assets/uijson/induced_polarization_3d_forward.ui.json @@ -4,7 +4,7 @@ "icon": "PotentialElectrode", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.electricals.induced_polarization.three_dimensions.forward", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/induced_polarization_3d_inversion.ui.json b/simpeg_drivers-assets/uijson/induced_polarization_3d_inversion.ui.json index e355d2fa..9ef7b3f8 100644 --- a/simpeg_drivers-assets/uijson/induced_polarization_3d_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/induced_polarization_3d_inversion.ui.json @@ -4,7 +4,7 @@ "icon": "PotentialElectrode", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.electricals.induced_polarization.three_dimensions.inversion", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/joint_cross_gradient_inversion.ui.json b/simpeg_drivers-assets/uijson/joint_cross_gradient_inversion.ui.json index ef25c89c..8712350a 100644 --- a/simpeg_drivers-assets/uijson/joint_cross_gradient_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/joint_cross_gradient_inversion.ui.json @@ -4,7 +4,7 @@ "icon": "function", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.joint.joint_cross_gradient.driver", "geoh5": "", "monitoring_directory": "", "group_a": { diff --git a/simpeg_drivers-assets/uijson/joint_petrophysics_inversion.ui.json b/simpeg_drivers-assets/uijson/joint_petrophysics_inversion.ui.json index f1dfade0..b9377ddf 100644 --- a/simpeg_drivers-assets/uijson/joint_petrophysics_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/joint_petrophysics_inversion.ui.json @@ -4,7 +4,7 @@ "icon": "referencedata", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.joint.joint_petrophysics.driver", "geoh5": "", "monitoring_directory": "", "group_a": { diff --git a/simpeg_drivers-assets/uijson/joint_surveys_inversion.ui.json b/simpeg_drivers-assets/uijson/joint_surveys_inversion.ui.json index 4d361e11..2a11c104 100644 --- a/simpeg_drivers-assets/uijson/joint_surveys_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/joint_surveys_inversion.ui.json @@ -4,7 +4,7 @@ "icon": "model", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.joint.joint_surveys.driver", "geoh5": "", "monitoring_directory": "", "group_a": { diff --git a/simpeg_drivers-assets/uijson/magnetic_scalar_forward.ui.json b/simpeg_drivers-assets/uijson/magnetic_scalar_forward.ui.json index 83c2b862..c4b5d03b 100644 --- a/simpeg_drivers-assets/uijson/magnetic_scalar_forward.ui.json +++ b/simpeg_drivers-assets/uijson/magnetic_scalar_forward.ui.json @@ -4,7 +4,7 @@ "icon": "surveyairbornemagnetics", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.potential_fields.magnetic_scalar.forward", "geoh5": "", "monitoring_directory": "", "inducing_field_declination": { diff --git a/simpeg_drivers-assets/uijson/magnetic_scalar_inversion.ui.json b/simpeg_drivers-assets/uijson/magnetic_scalar_inversion.ui.json index 64c7f43e..f025304d 100644 --- a/simpeg_drivers-assets/uijson/magnetic_scalar_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/magnetic_scalar_inversion.ui.json @@ -4,7 +4,7 @@ "icon": "surveyairbornemagnetics", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.potential_fields.magnetic_scalar.inversion", "geoh5": "", "monitoring_directory": "", "inducing_field_declination": { diff --git a/simpeg_drivers-assets/uijson/magnetic_vector_forward.ui.json b/simpeg_drivers-assets/uijson/magnetic_vector_forward.ui.json index cd9e5a05..0020bbdc 100644 --- a/simpeg_drivers-assets/uijson/magnetic_vector_forward.ui.json +++ b/simpeg_drivers-assets/uijson/magnetic_vector_forward.ui.json @@ -4,7 +4,7 @@ "icon": "surveyairbornemagnetics", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.potential_fields.magnetic_vector.forward", "geoh5": "", "monitoring_directory": "", "inducing_field_declination": { diff --git a/simpeg_drivers-assets/uijson/magnetic_vector_inversion.ui.json b/simpeg_drivers-assets/uijson/magnetic_vector_inversion.ui.json index 2e370514..0060ded7 100644 --- a/simpeg_drivers-assets/uijson/magnetic_vector_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/magnetic_vector_inversion.ui.json @@ -4,7 +4,7 @@ "icon": "surveyairbornemagnetics", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.potential_fields.magnetic_vector.inversion", "geoh5": "", "monitoring_directory": "", "inducing_field_declination": { diff --git a/simpeg_drivers-assets/uijson/magnetotellurics_forward.ui.json b/simpeg_drivers-assets/uijson/magnetotellurics_forward.ui.json index 8bb10908..2790747c 100644 --- a/simpeg_drivers-assets/uijson/magnetotellurics_forward.ui.json +++ b/simpeg_drivers-assets/uijson/magnetotellurics_forward.ui.json @@ -4,7 +4,7 @@ "icon": "surveymagnetotellurics", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.natural_sources.magnetotellurics.forward", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/magnetotellurics_inversion.ui.json b/simpeg_drivers-assets/uijson/magnetotellurics_inversion.ui.json index 42b4ab45..e782cb52 100644 --- a/simpeg_drivers-assets/uijson/magnetotellurics_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/magnetotellurics_inversion.ui.json @@ -4,7 +4,7 @@ "icon": "surveymagnetotellurics", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.natural_sources.magnetotellurics.inversion", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/plate_sweep.ui.json b/simpeg_drivers-assets/uijson/plate_sweep.ui.json index c8744500..ffe4c361 100644 --- a/simpeg_drivers-assets/uijson/plate_sweep.ui.json +++ b/simpeg_drivers-assets/uijson/plate_sweep.ui.json @@ -4,7 +4,7 @@ "icon": "maxwellplate", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/plate-simulation/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.plate_simulation.sweep.driver", "geoh5": "", "monitoring_directory": "", "template": { diff --git a/simpeg_drivers-assets/uijson/tdem1d_forward.ui.json b/simpeg_drivers-assets/uijson/tdem1d_forward.ui.json index 1a41a849..ec596baf 100644 --- a/simpeg_drivers-assets/uijson/tdem1d_forward.ui.json +++ b/simpeg_drivers-assets/uijson/tdem1d_forward.ui.json @@ -4,7 +4,7 @@ "icon": "surveyairborneem", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.electromagnetics.time_domain_1d.forward", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/tdem1d_inversion.ui.json b/simpeg_drivers-assets/uijson/tdem1d_inversion.ui.json index 8d53af4e..72c09b74 100644 --- a/simpeg_drivers-assets/uijson/tdem1d_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/tdem1d_inversion.ui.json @@ -4,7 +4,7 @@ "icon": "surveyairborneem", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.electromagnetics.time_domain_1d.inversion", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/tdem_forward.ui.json b/simpeg_drivers-assets/uijson/tdem_forward.ui.json index beeccc0b..287391f8 100644 --- a/simpeg_drivers-assets/uijson/tdem_forward.ui.json +++ b/simpeg_drivers-assets/uijson/tdem_forward.ui.json @@ -4,7 +4,7 @@ "icon": "surveyairborneem", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.electromagnetics.time_domain.forward", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/tdem_inversion.ui.json b/simpeg_drivers-assets/uijson/tdem_inversion.ui.json index 375361ed..18e93a52 100644 --- a/simpeg_drivers-assets/uijson/tdem_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/tdem_inversion.ui.json @@ -4,7 +4,7 @@ "icon": "surveyairborneem", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.electromagnetics.time_domain.inversion", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/tipper_forward.ui.json b/simpeg_drivers-assets/uijson/tipper_forward.ui.json index 7b15db75..7794a830 100644 --- a/simpeg_drivers-assets/uijson/tipper_forward.ui.json +++ b/simpeg_drivers-assets/uijson/tipper_forward.ui.json @@ -4,7 +4,7 @@ "icon": "surveyztem", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.natural_sources.tipper.forward", "geoh5": "", "monitoring_directory": "", "data_object": { diff --git a/simpeg_drivers-assets/uijson/tipper_inversion.ui.json b/simpeg_drivers-assets/uijson/tipper_inversion.ui.json index 88508275..9c85c829 100644 --- a/simpeg_drivers-assets/uijson/tipper_inversion.ui.json +++ b/simpeg_drivers-assets/uijson/tipper_inversion.ui.json @@ -4,7 +4,7 @@ "icon": "surveyztem", "documentation": "https://mirageoscience-simpeg-drivers.readthedocs-hosted.com/en/latest/", "conda_environment": "simpeg_drivers", - "run_command": "simpeg_drivers.driver", + "run_command": "simpeg_drivers.natural_sources.tipper.inversion", "geoh5": "", "monitoring_directory": "", "data_object": { From f5f038daf0d8fcf4974c115d32badc4b903e014c Mon Sep 17 00:00:00 2001 From: domfournier Date: Fri, 20 Mar 2026 13:24:47 -0700 Subject: [PATCH 10/18] Add run_commands to option classes --- simpeg_drivers/electromagnetics/frequency_domain/options.py | 2 ++ .../electromagnetics/frequency_domain_1d/options.py | 5 +++-- simpeg_drivers/electromagnetics/time_domain/options.py | 3 +++ simpeg_drivers/electromagnetics/time_domain_1d/options.py | 4 ++-- simpeg_drivers/joint/joint_cross_gradient/options.py | 2 +- simpeg_drivers/joint/joint_petrophysics/options.py | 2 +- simpeg_drivers/joint/joint_surveys/options.py | 2 +- .../natural_sources/apparent_conductivity/options.py | 4 ++-- simpeg_drivers/natural_sources/magnetotellurics/options.py | 4 ++-- simpeg_drivers/natural_sources/tipper/options.py | 4 ++-- simpeg_drivers/potential_fields/gravity/options.py | 2 ++ simpeg_drivers/potential_fields/magnetic_scalar/options.py | 2 ++ simpeg_drivers/potential_fields/magnetic_vector/options.py | 4 ++-- 13 files changed, 25 insertions(+), 15 deletions(-) diff --git a/simpeg_drivers/electromagnetics/frequency_domain/options.py b/simpeg_drivers/electromagnetics/frequency_domain/options.py index 942bac8d..d275e626 100644 --- a/simpeg_drivers/electromagnetics/frequency_domain/options.py +++ b/simpeg_drivers/electromagnetics/frequency_domain/options.py @@ -97,6 +97,7 @@ class FDEMForwardOptions(BaseForwardOptions, BaseFDEMOptions): name: ClassVar[str] = "Frequency Domain Electromagnetics Forward" default_ui_json: ClassVar[Path] = assets_path() / "uijson/fdem_forward.ui.json" + run_command: str = "simpeg_drivers.electromagnetics.frequency_domain.forward" title: str = "Frequency-domain EM (FEM) Forward" physical_property: str = "conductivity" inversion_type: str = "fdem" @@ -137,6 +138,7 @@ class FDEMInversionOptions(BaseFDEMOptions, BaseInversionOptions): name: ClassVar[str] = "Frequency Domain Electromagnetics Inversion" default_ui_json: ClassVar[Path] = assets_path() / "uijson/fdem_inversion.ui.json" + run_command: str = "simpeg_drivers.electromagnetics.frequency_domain.inversion" title: str = "Frequency-domain EM (FEM) Inversion" physical_property: str = "conductivity" inversion_type: str = "fdem" diff --git a/simpeg_drivers/electromagnetics/frequency_domain_1d/options.py b/simpeg_drivers/electromagnetics/frequency_domain_1d/options.py index e7b9ebb8..443bdfc5 100644 --- a/simpeg_drivers/electromagnetics/frequency_domain_1d/options.py +++ b/simpeg_drivers/electromagnetics/frequency_domain_1d/options.py @@ -33,13 +33,13 @@ class FDEM1DForwardOptions(BaseForwardOptions, BaseFDEMOptions, Base1DOptions): Frequency Domain Electromagnetic forward options. :param z_real_channel_bool: Z-component data channel boolean. - :param z_imag_channel_bool: X-component data channel boolean. + :param z_imag_channel_bool: Imaginary Z-component data channel boolean. :param drape_model: Drape model options. """ name: ClassVar[str] = "Frequency Domain 1D Electromagnetics Forward" default_ui_json: ClassVar[Path] = assets_path() / "uijson/fdem1d_forward.ui.json" - + run_command: str = "simpeg_drivers.electromagnetics.frequency_domain_1d.forward" title: str = "Frequency-domain EM-1D (FEM-1D) Forward" physical_property: str = "conductivity" inversion_type: str = "fdem 1d" @@ -62,6 +62,7 @@ class FDEM1DInversionOptions(BaseFDEMOptions, BaseInversionOptions, Base1DOption name: ClassVar[str] = "Frequency Domain 1D Electromagnetics Inversion" default_ui_json: ClassVar[Path] = assets_path() / "uijson/fdem1d_inversion.ui.json" + run_command: str = "simpeg_drivers.electromagnetics.frequency_domain_1d.inversion" title: str = "Frequency-domain EM-1D (FEM-1D) Inversion" physical_property: str = "conductivity" inversion_type: str = "fdem 1d" diff --git a/simpeg_drivers/electromagnetics/time_domain/options.py b/simpeg_drivers/electromagnetics/time_domain/options.py index ef52632a..62295127 100644 --- a/simpeg_drivers/electromagnetics/time_domain/options.py +++ b/simpeg_drivers/electromagnetics/time_domain/options.py @@ -83,6 +83,8 @@ class TDEMForwardOptions(BaseTDEMOptions, BaseForwardOptions): name: ClassVar[str] = "Time Domain Electromagnetics Forward" default_ui_json: ClassVar[Path] = assets_path() / "uijson/tdem_forward.ui.json" + run_command: str = "simpeg_drivers.electromagnetics.time_domain.forward" + title: str = "Time-domain EM (TEM) Forward" physical_property: str = "conductivity" inversion_type: str = "tdem" @@ -113,6 +115,7 @@ class TDEMInversionOptions(BaseTDEMOptions, BaseInversionOptions): name: ClassVar[str] = "Time Domain Electromagnetics Inversion" default_ui_json: ClassVar[Path] = assets_path() / "uijson/tdem_inversion.ui.json" + run_command: str = "simpeg_drivers.electromagnetics.time_domain.inversion" title: str = "Time-domain EM (TEM) Inversion" physical_property: str = "conductivity" inversion_type: str = "tdem" diff --git a/simpeg_drivers/electromagnetics/time_domain_1d/options.py b/simpeg_drivers/electromagnetics/time_domain_1d/options.py index 0b3aad4b..9d8348ef 100644 --- a/simpeg_drivers/electromagnetics/time_domain_1d/options.py +++ b/simpeg_drivers/electromagnetics/time_domain_1d/options.py @@ -37,7 +37,7 @@ class TDEM1DForwardOptions(TDEMForwardOptions, Base1DOptions): name: ClassVar[str] = "Time Domain Electromagnetics Forward" default_ui_json: ClassVar[Path] = assets_path() / "uijson/tdem1d_forward.ui.json" - + run_command: str = "simpeg_drivers.electromagnetics.time_domain_1d.forward" title: str = "Time-domain EM-1D (TEM-1D) Forward" inversion_type: str = "tdem 1d" @@ -55,7 +55,7 @@ class TDEM1DInversionOptions(TDEMInversionOptions, Base1DOptions): name: ClassVar[str] = "Time Domain Electromagnetics Inversion" default_ui_json: ClassVar[Path] = assets_path() / "uijson/tdem1d_inversion.ui.json" - + run_command: str = "simpeg_drivers.electromagnetics.time_domain_1d.inversion" title: str = "Time-domain EM-1D (TEM-1D) Inversion" inversion_type: str = "tdem 1d" diff --git a/simpeg_drivers/joint/joint_cross_gradient/options.py b/simpeg_drivers/joint/joint_cross_gradient/options.py index e98a3cf6..f4f39698 100644 --- a/simpeg_drivers/joint/joint_cross_gradient/options.py +++ b/simpeg_drivers/joint/joint_cross_gradient/options.py @@ -36,7 +36,7 @@ class JointCrossGradientOptions(BaseJointOptions): default_ui_json: ClassVar[Path] = ( assets_path() / "uijson/joint_cross_gradient_inversion.ui.json" ) - + run_command: str = "simpeg_drivers.joint.joint_cross_gradient.driver" title: str = "Joint Cross Gradient Inversion" inversion_type: str = "joint cross gradient" diff --git a/simpeg_drivers/joint/joint_petrophysics/options.py b/simpeg_drivers/joint/joint_petrophysics/options.py index 32ea30fe..399abc86 100644 --- a/simpeg_drivers/joint/joint_petrophysics/options.py +++ b/simpeg_drivers/joint/joint_petrophysics/options.py @@ -46,7 +46,7 @@ class JointPetrophysicsOptions(BaseJointOptions): default_ui_json: ClassVar[Path] = ( assets_path() / "uijson/joint_petrophysics_inversion.ui.json" ) - + run_command: str = "simpeg_drivers.joint.joint_petrophysics.driver" title: str = "Joint Petrophysically Guided Inversion (PGI)" inversion_type: str = "joint petrophysics" diff --git a/simpeg_drivers/joint/joint_surveys/options.py b/simpeg_drivers/joint/joint_surveys/options.py index a2dcb787..55c10af9 100644 --- a/simpeg_drivers/joint/joint_surveys/options.py +++ b/simpeg_drivers/joint/joint_surveys/options.py @@ -43,7 +43,7 @@ class JointSurveysOptions(BaseJointOptions): default_ui_json: ClassVar[Path] = ( assets_path() / "uijson/joint_surveys_inversion.ui.json" ) - + run_command: str = "simpeg_drivers.joint.joint_surveys.driver" title: str = "Joint Surveys Inversion" inversion_type: str = "joint surveys" diff --git a/simpeg_drivers/natural_sources/apparent_conductivity/options.py b/simpeg_drivers/natural_sources/apparent_conductivity/options.py index 2cabaea4..4bcc05ff 100644 --- a/simpeg_drivers/natural_sources/apparent_conductivity/options.py +++ b/simpeg_drivers/natural_sources/apparent_conductivity/options.py @@ -36,7 +36,7 @@ class AppConForwardOptions(EMDataMixin, BaseForwardOptions): default_ui_json: ClassVar[Path] = ( assets_path() / "uijson/apparent_conductivity_forward.ui.json" ) - + run_command = "simpeg_drivers.natural_sources.apparent_conductivity.forward" title: str = "Apparent Conductivity Forward" physical_property: str = "conductivity" inversion_type: str = "apparent conductivity" @@ -57,7 +57,7 @@ class AppConInversionOptions(EMDataMixin, BaseInversionOptions): default_ui_json: ClassVar[Path] = ( assets_path() / "uijson/apparent_conductivity_inversion.ui.json" ) - + run_command = "simpeg_drivers.natural_sources.apparent_conductivity.inversion" title: str = "Apparent Conductivity Inversion" physical_property: str = "conductivity" inversion_type: str = "apparent conductivity" diff --git a/simpeg_drivers/natural_sources/magnetotellurics/options.py b/simpeg_drivers/natural_sources/magnetotellurics/options.py index ace35be8..c0a2d3c1 100644 --- a/simpeg_drivers/natural_sources/magnetotellurics/options.py +++ b/simpeg_drivers/natural_sources/magnetotellurics/options.py @@ -47,7 +47,7 @@ class MTForwardOptions(EMDataMixin, BaseForwardOptions): default_ui_json: ClassVar[Path] = ( assets_path() / "uijson/magnetotellurics_forward.ui.json" ) - + run_command = "simpeg_drivers.natural_sources.magnetotellurics.forward" title: str = "Magnetotellurics Forward" physical_property: str = "conductivity" inversion_type: str = "magnetotellurics" @@ -94,7 +94,7 @@ class MTInversionOptions(EMDataMixin, BaseInversionOptions): default_ui_json: ClassVar[Path] = ( assets_path() / "uijson/magnetotellurics_inversion.ui.json" ) - + run_command = "simpeg_drivers.natural_sources.magnetotellurics.inversion" title: str = "Magnetotellurics Inversion" physical_property: str = "conductivity" inversion_type: str = "magnetotellurics" diff --git a/simpeg_drivers/natural_sources/tipper/options.py b/simpeg_drivers/natural_sources/tipper/options.py index d689199a..471248a9 100644 --- a/simpeg_drivers/natural_sources/tipper/options.py +++ b/simpeg_drivers/natural_sources/tipper/options.py @@ -40,7 +40,7 @@ class TipperForwardOptions(EMDataMixin, BaseForwardOptions): name: ClassVar[str] = "Tipper Forward" default_ui_json: ClassVar[Path] = assets_path() / "uijson/tipper_forward.ui.json" - + run_command = "simpeg_drivers.natural_sources.tipper.forward" title: str = "Tipper Forward" physical_property: str = "conductivity" inversion_type: str = "tipper" @@ -70,7 +70,7 @@ class TipperInversionOptions(EMDataMixin, BaseInversionOptions): name: ClassVar[str] = "Tipper Inversion" default_ui_json: ClassVar[Path] = assets_path() / "uijson/tipper_inversion.ui.json" - + run_command = "simpeg_drivers.natural_sources.tipper.inversion" title: str = "Tipper Inversion" physical_property: str = "conductivity" inversion_type: str = "tipper" diff --git a/simpeg_drivers/potential_fields/gravity/options.py b/simpeg_drivers/potential_fields/gravity/options.py index 396a3d09..763607ce 100644 --- a/simpeg_drivers/potential_fields/gravity/options.py +++ b/simpeg_drivers/potential_fields/gravity/options.py @@ -41,6 +41,7 @@ class GravityForwardOptions(BaseForwardOptions): name: ClassVar[str] = "Gravity Forward" default_ui_json: ClassVar[Path] = assets_path() / "uijson/gravity_forward.ui.json" + run_command: str = "simpeg_drivers.potential_fields.gravity.forward" title: str = "Gravity Forward" physical_property: str = "density" @@ -84,6 +85,7 @@ class GravityInversionOptions(BaseInversionOptions): default_ui_json: ClassVar[Path] = assets_path() / "uijson/gravity_inversion.ui.json" name: ClassVar[str] = "Gravity Inversion" + run_command: str = "simpeg_drivers.potential_fields.gravity.inversion" title: str = "Gravity Inversion" physical_property: str = "density" diff --git a/simpeg_drivers/potential_fields/magnetic_scalar/options.py b/simpeg_drivers/potential_fields/magnetic_scalar/options.py index 5d3eae94..1e1839e7 100644 --- a/simpeg_drivers/potential_fields/magnetic_scalar/options.py +++ b/simpeg_drivers/potential_fields/magnetic_scalar/options.py @@ -53,6 +53,7 @@ class MagneticForwardOptions(BaseForwardOptions): default_ui_json: ClassVar[Path] = ( assets_path() / "uijson/magnetic_scalar_forward.ui.json" ) + run_command: str = "simpeg_drivers.potential_fields.magnetic_scalar.forward" title: str = "Magnetic Scalar Forward" physical_property: str = "susceptibility" @@ -108,6 +109,7 @@ class MagneticInversionOptions(BaseInversionOptions): default_ui_json: ClassVar[Path] = ( assets_path() / "uijson/magnetic_scalar_inversion.ui.json" ) + run_command: str = "simpeg_drivers.potential_fields.magnetic_scalar.inversion" title: str = "Magnetic Scalar Inversion" physical_property: str = "susceptibility" diff --git a/simpeg_drivers/potential_fields/magnetic_vector/options.py b/simpeg_drivers/potential_fields/magnetic_vector/options.py index 3b25c574..58e72ae9 100644 --- a/simpeg_drivers/potential_fields/magnetic_vector/options.py +++ b/simpeg_drivers/potential_fields/magnetic_vector/options.py @@ -58,7 +58,7 @@ class MagneticVectorForwardOptions(BaseForwardOptions): default_ui_json: ClassVar[Path] = ( assets_path() / "uijson/magnetic_vector_forward.ui.json" ) - + run_command: str = "simpeg_drivers.potential_fields.magnetic_vector.forward" title: str = "Magnetic Vector Forward" physical_property: str = "susceptibility" inversion_type: str = "magnetic vector" @@ -112,7 +112,7 @@ class MagneticVectorInversionOptions(BaseInversionOptions): default_ui_json: ClassVar[Path] = ( assets_path() / "uijson/magnetic_vector_inversion.ui.json" ) - + run_command: str = "simpeg_drivers.potential_fields.magnetic_vector.inversion" title: str = "Magnetic Vector Inversion" physical_property: str = "susceptibility" inversion_type: str = "magnetic vector" From d0426ef387a53976bb54c96b531c5f6e5079f446 Mon Sep 17 00:00:00 2001 From: domfournier Date: Fri, 20 Mar 2026 13:32:30 -0700 Subject: [PATCH 11/18] Fix type of run_command in Options --- .../natural_sources/apparent_conductivity/options.py | 4 ++-- simpeg_drivers/natural_sources/magnetotellurics/options.py | 4 ++-- simpeg_drivers/natural_sources/tipper/options.py | 4 ++-- simpeg_drivers/plate_simulation/options.py | 4 ++-- simpeg_drivers/plate_simulation/sweep/options.py | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/simpeg_drivers/natural_sources/apparent_conductivity/options.py b/simpeg_drivers/natural_sources/apparent_conductivity/options.py index 4bcc05ff..832f3b67 100644 --- a/simpeg_drivers/natural_sources/apparent_conductivity/options.py +++ b/simpeg_drivers/natural_sources/apparent_conductivity/options.py @@ -36,7 +36,7 @@ class AppConForwardOptions(EMDataMixin, BaseForwardOptions): default_ui_json: ClassVar[Path] = ( assets_path() / "uijson/apparent_conductivity_forward.ui.json" ) - run_command = "simpeg_drivers.natural_sources.apparent_conductivity.forward" + run_command: str = "simpeg_drivers.natural_sources.apparent_conductivity.forward" title: str = "Apparent Conductivity Forward" physical_property: str = "conductivity" inversion_type: str = "apparent conductivity" @@ -57,7 +57,7 @@ class AppConInversionOptions(EMDataMixin, BaseInversionOptions): default_ui_json: ClassVar[Path] = ( assets_path() / "uijson/apparent_conductivity_inversion.ui.json" ) - run_command = "simpeg_drivers.natural_sources.apparent_conductivity.inversion" + run_command: str = "simpeg_drivers.natural_sources.apparent_conductivity.inversion" title: str = "Apparent Conductivity Inversion" physical_property: str = "conductivity" inversion_type: str = "apparent conductivity" diff --git a/simpeg_drivers/natural_sources/magnetotellurics/options.py b/simpeg_drivers/natural_sources/magnetotellurics/options.py index c0a2d3c1..60911bb1 100644 --- a/simpeg_drivers/natural_sources/magnetotellurics/options.py +++ b/simpeg_drivers/natural_sources/magnetotellurics/options.py @@ -47,7 +47,7 @@ class MTForwardOptions(EMDataMixin, BaseForwardOptions): default_ui_json: ClassVar[Path] = ( assets_path() / "uijson/magnetotellurics_forward.ui.json" ) - run_command = "simpeg_drivers.natural_sources.magnetotellurics.forward" + run_command: str = "simpeg_drivers.natural_sources.magnetotellurics.forward" title: str = "Magnetotellurics Forward" physical_property: str = "conductivity" inversion_type: str = "magnetotellurics" @@ -94,7 +94,7 @@ class MTInversionOptions(EMDataMixin, BaseInversionOptions): default_ui_json: ClassVar[Path] = ( assets_path() / "uijson/magnetotellurics_inversion.ui.json" ) - run_command = "simpeg_drivers.natural_sources.magnetotellurics.inversion" + run_command: str = "simpeg_drivers.natural_sources.magnetotellurics.inversion" title: str = "Magnetotellurics Inversion" physical_property: str = "conductivity" inversion_type: str = "magnetotellurics" diff --git a/simpeg_drivers/natural_sources/tipper/options.py b/simpeg_drivers/natural_sources/tipper/options.py index 471248a9..5196b53c 100644 --- a/simpeg_drivers/natural_sources/tipper/options.py +++ b/simpeg_drivers/natural_sources/tipper/options.py @@ -40,7 +40,7 @@ class TipperForwardOptions(EMDataMixin, BaseForwardOptions): name: ClassVar[str] = "Tipper Forward" default_ui_json: ClassVar[Path] = assets_path() / "uijson/tipper_forward.ui.json" - run_command = "simpeg_drivers.natural_sources.tipper.forward" + run_command: str = "simpeg_drivers.natural_sources.tipper.forward" title: str = "Tipper Forward" physical_property: str = "conductivity" inversion_type: str = "tipper" @@ -70,7 +70,7 @@ class TipperInversionOptions(EMDataMixin, BaseInversionOptions): name: ClassVar[str] = "Tipper Inversion" default_ui_json: ClassVar[Path] = assets_path() / "uijson/tipper_inversion.ui.json" - run_command = "simpeg_drivers.natural_sources.tipper.inversion" + run_command: str = "simpeg_drivers.natural_sources.tipper.inversion" title: str = "Tipper Inversion" physical_property: str = "conductivity" inversion_type: str = "tipper" diff --git a/simpeg_drivers/plate_simulation/options.py b/simpeg_drivers/plate_simulation/options.py index 792383e1..f09b1cde 100644 --- a/simpeg_drivers/plate_simulation/options.py +++ b/simpeg_drivers/plate_simulation/options.py @@ -125,8 +125,8 @@ class PlateSimulationOptions(Options): name: ClassVar[str] = "plate_simulation" default_ui_json: ClassVar[Path] = assets_path() / "uijson/plate_simulation.ui.json" - title: ClassVar[str] = "Plate Simulation" - run_command: ClassVar[str] = "simpeg_drivers.plate_simulation.driver" + title: str = "Plate Simulation" + run_command: str = "simpeg_drivers.plate_simulation.driver" out_group: SimPEGGroup | UIJsonGroup | None = None forward_only: bool = True inversion_type: str = "plate simulation" diff --git a/simpeg_drivers/plate_simulation/sweep/options.py b/simpeg_drivers/plate_simulation/sweep/options.py index dc372499..0f2a5295 100644 --- a/simpeg_drivers/plate_simulation/sweep/options.py +++ b/simpeg_drivers/plate_simulation/sweep/options.py @@ -57,8 +57,8 @@ class SweepOptions(Options): name: ClassVar[str] = "plate_sweep" default_ui_json: ClassVar[Path] = assets_path() / "uijson/plate_sweep.ui.json" - title: ClassVar[str] = "Plate Sweep" - run_command: ClassVar[str] = "simpeg_drivers.plate_simulation.sweep.driver" + title: str = "Plate Sweep" + run_command: str = "simpeg_drivers.plate_simulation.sweep.driver" out_group: SimPEGGroup | None = None forward_only: bool = True inversion_type: str = "plate sweep" From 887ad292ec7d19d4519be2aaa582515a77cd3d34 Mon Sep 17 00:00:00 2001 From: domfournier Date: Fri, 20 Mar 2026 14:07:32 -0700 Subject: [PATCH 12/18] Fix weird tuple and unuse options --- simpeg_drivers/driver.py | 6 +++--- .../electromagnetics/frequency_domain_1d/options.py | 1 - simpeg_drivers/options.py | 1 - simpeg_drivers/utils/utils.py | 4 ++-- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/simpeg_drivers/driver.py b/simpeg_drivers/driver.py index 62b1a977..08db1743 100644 --- a/simpeg_drivers/driver.py +++ b/simpeg_drivers/driver.py @@ -502,9 +502,9 @@ def start_dask_run( """ ui_json = load_ui_json_as_dict(json_path) - n_workers = (ui_json.get("n_workers", n_workers),) - n_threads = (ui_json.get("n_threads", n_threads),) - save_report = (ui_json.get("performance_report", False),) + n_workers = ui_json.get("n_workers", n_workers) + n_threads = ui_json.get("n_threads", n_threads) + save_report = ui_json.get("performance_report", False) if (n_workers is not None and n_workers > 1) or n_threads is not None: cluster = LocalCluster( diff --git a/simpeg_drivers/electromagnetics/frequency_domain_1d/options.py b/simpeg_drivers/electromagnetics/frequency_domain_1d/options.py index 443bdfc5..e9544370 100644 --- a/simpeg_drivers/electromagnetics/frequency_domain_1d/options.py +++ b/simpeg_drivers/electromagnetics/frequency_domain_1d/options.py @@ -76,4 +76,3 @@ class FDEM1DInversionOptions(BaseFDEMOptions, BaseInversionOptions, Base1DOption z_imag_channel: PropertyGroup | None = None z_imag_uncertainty: PropertyGroup | None = None models: ConductivityModelOptions - directives: DirectiveOptions = DirectiveOptions() diff --git a/simpeg_drivers/options.py b/simpeg_drivers/options.py index 8e04af92..b64efefd 100644 --- a/simpeg_drivers/options.py +++ b/simpeg_drivers/options.py @@ -385,7 +385,6 @@ class DirectiveOptions(BaseModel): :param auto_scale_tiles: Automatically scale tiles. :param auto_scale_channels: Automatically scale channels. - :param beta_search: Beta search. :param every_iteration_bool: Update the sensitivity weights every iteration. :param save_sensitivities: Save sensitivities to file. :param sens_wts_threshold: Threshold for sensitivity weights. diff --git a/simpeg_drivers/utils/utils.py b/simpeg_drivers/utils/utils.py index 1c2bea4b..7e996214 100644 --- a/simpeg_drivers/utils/utils.py +++ b/simpeg_drivers/utils/utils.py @@ -679,8 +679,8 @@ def get_default_parallelization_params(json_path: Path) -> tuple[int, int]: """ ui_json = load_ui_json_as_dict(json_path) - n_workers = (ui_json.get("n_workers", None),) - n_threads = (ui_json.get("n_threads", None),) + n_workers = ui_json.get("n_workers", None) + n_threads = ui_json.get("n_threads", None) if n_workers is None: cpu_count = multiprocessing.cpu_count() From 4278a6f4efdae302127e635156bf2875f9a7e5a9 Mon Sep 17 00:00:00 2001 From: domfournier Date: Fri, 20 Mar 2026 14:15:02 -0700 Subject: [PATCH 13/18] Fix return type --- simpeg_drivers/options.py | 2 +- simpeg_drivers/utils/regularization.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/simpeg_drivers/options.py b/simpeg_drivers/options.py index b64efefd..2b2f217b 100644 --- a/simpeg_drivers/options.py +++ b/simpeg_drivers/options.py @@ -297,7 +297,7 @@ def gradient_dip(self) -> FloatData | None: return self.gradient_orientations[1] @property - def gradient_orientations(self) -> tuple(float, float): + def gradient_orientations(self) -> list[FloatData] | None: """ Direction and dip angles for rotated gradient regularization. diff --git a/simpeg_drivers/utils/regularization.py b/simpeg_drivers/utils/regularization.py index 27b97dee..a48bd95f 100644 --- a/simpeg_drivers/utils/regularization.py +++ b/simpeg_drivers/utils/regularization.py @@ -16,7 +16,7 @@ x_rotation_matrix, z_rotation_matrix, ) -from geoh5py.data import Data +from geoh5py.data import FloatData from geoh5py.groups import PropertyGroup from geoh5py.groups.property_group_type import GroupTypeEnum from simpeg.regularization import SparseSmoothness @@ -437,7 +437,7 @@ def rotated_gradient( return unit_grad -def direction_and_dip(property_group: PropertyGroup) -> list[Data]: +def direction_and_dip(property_group: PropertyGroup) -> list[FloatData]: """Conversion of orientation group to direction and dip.""" group_type = property_group.property_group_type From b324e35a936a8c5c052130f54e79bb3329d049a1 Mon Sep 17 00:00:00 2001 From: domfournier Date: Fri, 20 Mar 2026 14:22:41 -0700 Subject: [PATCH 14/18] Deal with out_group of plate simulation --- simpeg_drivers/components/locations.py | 2 -- simpeg_drivers/plate_simulation/driver.py | 8 ++++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/simpeg_drivers/components/locations.py b/simpeg_drivers/components/locations.py index b61b649e..9b164d80 100644 --- a/simpeg_drivers/components/locations.py +++ b/simpeg_drivers/components/locations.py @@ -22,8 +22,6 @@ import numpy as np from geoh5py.objects import ObjectBase, Points from geoh5py.objects.surveys.direct_current import BaseElectrode -from geoh5py.shared import Entity -from scipy.interpolate import LinearNDInterpolator from scipy.spatial import cKDTree diff --git a/simpeg_drivers/plate_simulation/driver.py b/simpeg_drivers/plate_simulation/driver.py index f55b2a23..95ee6e00 100644 --- a/simpeg_drivers/plate_simulation/driver.py +++ b/simpeg_drivers/plate_simulation/driver.py @@ -74,7 +74,7 @@ def run(self) -> InversionDriver: with fetch_active_workspace(self.params.geoh5, mode="r+"): self.simulation_driver.run() - self.update_monitoring_directory(self.out_group) + self.update_monitoring_directory(self._out_group) logger.info("done.") logger.handlers.clear() @@ -105,7 +105,7 @@ def simulation_driver(self) -> InversionDriver: client=self._client, workers=self._workers, ) - self._simulation_driver.out_group.parent = self.out_group + self._simulation_driver.out_group.parent = self._out_group return self._simulation_driver @@ -183,11 +183,11 @@ def make_mesh(self) -> Octree: octree_params = self.params.mesh.octree_params( self.survey, self.simulation_parameters.active_cells.topography_object, - [p.surface.copy(parent=self.out_group) for p in self.plates], + [p.surface.copy(parent=self._out_group) for p in self.plates], ) octree_driver = OctreeDriver(octree_params) mesh = octree_driver.run() - mesh.parent = self.out_group + mesh.parent = self._out_group return mesh From 43887b181d235d45f43cbad8ee59ccf7094cc400 Mon Sep 17 00:00:00 2001 From: domfournier Date: Fri, 20 Mar 2026 14:28:01 -0700 Subject: [PATCH 15/18] More copilot --- simpeg_drivers/electricals/base_2d.py | 1 + simpeg_drivers/plate_simulation/sweep/driver.py | 2 +- simpeg_drivers/utils/surveys.py | 3 +-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/simpeg_drivers/electricals/base_2d.py b/simpeg_drivers/electricals/base_2d.py index c2307c05..e1f5c7f2 100644 --- a/simpeg_drivers/electricals/base_2d.py +++ b/simpeg_drivers/electricals/base_2d.py @@ -111,6 +111,7 @@ def selected_parts(self) -> list[int]: if ( self.line_selection is not None and self.line_selection.property is not None + and self.line_selection.value is not None ): for count, val in enumerate( np.unique(self.line_selection.property.values) diff --git a/simpeg_drivers/plate_simulation/sweep/driver.py b/simpeg_drivers/plate_simulation/sweep/driver.py index 76018108..51f47f65 100644 --- a/simpeg_drivers/plate_simulation/sweep/driver.py +++ b/simpeg_drivers/plate_simulation/sweep/driver.py @@ -139,7 +139,7 @@ def run(self): out_file = self.params.geoh5.h5file.parent / "summary.xlsx" summary.to_excel(out_file, index=False) with self.params.geoh5.open(mode="r+"): - self.out_group.add_file(out_file) + self._out_group.add_file(out_file) @staticmethod def run_trial( diff --git a/simpeg_drivers/utils/surveys.py b/simpeg_drivers/utils/surveys.py index 98f9061d..8ff2569d 100644 --- a/simpeg_drivers/utils/surveys.py +++ b/simpeg_drivers/utils/surveys.py @@ -14,7 +14,6 @@ import numpy as np from discretize import TreeMesh from geoh5py import Workspace -from geoh5py.data import IntegerData from geoh5py.objects import DrapeModel, PotentialElectrode from geoh5py.shared.merging.drape_model import DrapeModelMerger from scipy.sparse import csgraph, csr_matrix @@ -187,7 +186,7 @@ def create_mesh_by_line_id( :param workspace: Workspace to create the drape mesh in. :param survey: PotentialElectrode survey object. - :param line_ids: Array containing the line IDs for each vertex. + :param line_ids: Array containing the line IDs for each cell. :param drape_options: DrapeModelOptions containing the parameters for the drape mesh :param object_kwargs: Additional keyword arguments to pass to the DrapeModelMerger.create_object method. From 7a75ea3a6901f3c70b9b50a684727d1d90f1c832 Mon Sep 17 00:00:00 2001 From: domfournier Date: Fri, 20 Mar 2026 14:45:38 -0700 Subject: [PATCH 16/18] Clean out pylint disables --- simpeg_drivers/electricals/__init__.py | 15 --------------- .../direct_current/three_dimensions/__init__.py | 2 -- .../three_dimensions/__init__.py | 3 --- .../joint/joint_cross_gradient/__init__.py | 6 ------ simpeg_drivers/joint/joint_surveys/__init__.py | 6 ------ simpeg_drivers/joint/joint_surveys/driver.py | 6 +++--- .../natural_sources/magnetotellurics/__init__.py | 2 -- simpeg_drivers/natural_sources/tipper/__init__.py | 3 --- .../potential_fields/gravity/__init__.py | 3 --- .../potential_fields/magnetic_vector/__init__.py | 3 --- tests/run_tests/driver_joint_surveys_test.py | 10 +++++----- 11 files changed, 8 insertions(+), 51 deletions(-) diff --git a/simpeg_drivers/electricals/__init__.py b/simpeg_drivers/electricals/__init__.py index 6f783173..df32b204 100644 --- a/simpeg_drivers/electricals/__init__.py +++ b/simpeg_drivers/electricals/__init__.py @@ -7,18 +7,3 @@ # (see LICENSE file at the root of this source code package). ' # ' # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' - - -from __future__ import annotations - -from .direct_current.three_dimensions import ( - DC3DForwardOptions, - DC3DInversionOptions, -) -from .induced_polarization.three_dimensions.options import ( - IP3DForwardOptions, - IP3DInversionOptions, -) - -# pylint: disable=unused-import -# flake8: noqa diff --git a/simpeg_drivers/electricals/direct_current/three_dimensions/__init__.py b/simpeg_drivers/electricals/direct_current/three_dimensions/__init__.py index 8f111df9..776049d7 100644 --- a/simpeg_drivers/electricals/direct_current/three_dimensions/__init__.py +++ b/simpeg_drivers/electricals/direct_current/three_dimensions/__init__.py @@ -8,8 +8,6 @@ # ' # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' -# pylint: disable=unused-import - from .forward import DC3DForwardDriver from .inversion import DC3DInversionDriver from .options import DC3DForwardOptions, DC3DInversionOptions diff --git a/simpeg_drivers/electricals/induced_polarization/three_dimensions/__init__.py b/simpeg_drivers/electricals/induced_polarization/three_dimensions/__init__.py index e1a7af85..14c829d6 100644 --- a/simpeg_drivers/electricals/induced_polarization/three_dimensions/__init__.py +++ b/simpeg_drivers/electricals/induced_polarization/three_dimensions/__init__.py @@ -14,6 +14,3 @@ IP3DForwardOptions, IP3DInversionOptions, ) - -# pylint: disable=unused-import -# flake8: noqa diff --git a/simpeg_drivers/joint/joint_cross_gradient/__init__.py b/simpeg_drivers/joint/joint_cross_gradient/__init__.py index 862ca917..df32b204 100644 --- a/simpeg_drivers/joint/joint_cross_gradient/__init__.py +++ b/simpeg_drivers/joint/joint_cross_gradient/__init__.py @@ -7,9 +7,3 @@ # (see LICENSE file at the root of this source code package). ' # ' # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' - - -from .options import JointCrossGradientOptions - -# pylint: disable=unused-import -# flake8: noqa diff --git a/simpeg_drivers/joint/joint_surveys/__init__.py b/simpeg_drivers/joint/joint_surveys/__init__.py index 682c9205..df32b204 100644 --- a/simpeg_drivers/joint/joint_surveys/__init__.py +++ b/simpeg_drivers/joint/joint_surveys/__init__.py @@ -7,9 +7,3 @@ # (see LICENSE file at the root of this source code package). ' # ' # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' - - -from .options import JointSurveysOptions - -# pylint: disable=unused-import -# flake8: noqa diff --git a/simpeg_drivers/joint/joint_surveys/driver.py b/simpeg_drivers/joint/joint_surveys/driver.py index 581ba9b4..ee46223e 100644 --- a/simpeg_drivers/joint/joint_surveys/driver.py +++ b/simpeg_drivers/joint/joint_surveys/driver.py @@ -27,7 +27,7 @@ logger = getLogger(__name__) -class JointSurveyDriver(BaseJointDriver): +class JointSurveysDriver(BaseJointDriver): """Joint surveys inversion driver""" _params_class = JointSurveysOptions @@ -142,5 +142,5 @@ def directives(self): return self._directives -JointSurveyDriver.n_values = InversionDriver.n_values -JointSurveyDriver.mapping = InversionDriver.mapping +JointSurveysDriver.n_values = InversionDriver.n_values +JointSurveysDriver.mapping = InversionDriver.mapping diff --git a/simpeg_drivers/natural_sources/magnetotellurics/__init__.py b/simpeg_drivers/natural_sources/magnetotellurics/__init__.py index d073e8c5..30906b8f 100644 --- a/simpeg_drivers/natural_sources/magnetotellurics/__init__.py +++ b/simpeg_drivers/natural_sources/magnetotellurics/__init__.py @@ -14,5 +14,3 @@ MTForwardOptions, MTInversionOptions, ) - -# pylint: disable=unused-import diff --git a/simpeg_drivers/natural_sources/tipper/__init__.py b/simpeg_drivers/natural_sources/tipper/__init__.py index 042988b4..3bc188ce 100644 --- a/simpeg_drivers/natural_sources/tipper/__init__.py +++ b/simpeg_drivers/natural_sources/tipper/__init__.py @@ -15,6 +15,3 @@ TipperForwardOptions, TipperInversionOptions, ) - -# pylint: disable=unused-import -# flake8: noqa diff --git a/simpeg_drivers/potential_fields/gravity/__init__.py b/simpeg_drivers/potential_fields/gravity/__init__.py index 283f132f..2714925c 100644 --- a/simpeg_drivers/potential_fields/gravity/__init__.py +++ b/simpeg_drivers/potential_fields/gravity/__init__.py @@ -15,6 +15,3 @@ GravityForwardOptions, GravityInversionOptions, ) - -# pylint: disable=unused-import -# flake8: noqa diff --git a/simpeg_drivers/potential_fields/magnetic_vector/__init__.py b/simpeg_drivers/potential_fields/magnetic_vector/__init__.py index 3535b3c6..d4724a89 100644 --- a/simpeg_drivers/potential_fields/magnetic_vector/__init__.py +++ b/simpeg_drivers/potential_fields/magnetic_vector/__init__.py @@ -15,6 +15,3 @@ MagneticVectorForwardOptions, MagneticVectorInversionOptions, ) - -# pylint: disable=unused-import -# flake8: noqa diff --git a/tests/run_tests/driver_joint_surveys_test.py b/tests/run_tests/driver_joint_surveys_test.py index 8dedff90..64790081 100644 --- a/tests/run_tests/driver_joint_surveys_test.py +++ b/tests/run_tests/driver_joint_surveys_test.py @@ -24,7 +24,7 @@ from simpeg_drivers.electromagnetics.time_domain import TDEMInversionDriver from simpeg_drivers.electromagnetics.time_domain.options import TDEMInversionOptions from simpeg_drivers.joint.joint_surveys import JointSurveysOptions -from simpeg_drivers.joint.joint_surveys.driver import JointSurveyDriver +from simpeg_drivers.joint.joint_surveys.driver import JointSurveysDriver from simpeg_drivers.options import ActiveCellsOptions from simpeg_drivers.potential_fields.gravity import ( GravityForwardDriver, @@ -189,7 +189,7 @@ def test_joint_surveys_inv_run( auto_scale_misfits=True, ) - driver = JointSurveyDriver(joint_params) + driver = JointSurveysDriver(joint_params) driver.run() # The rescaling is done evenly on the two tiles for both surveys @@ -272,7 +272,7 @@ def test_joint_surveys_mvi_run(tmp_path, anomaly=0.05): # Default to Conductivity (S/m) ) - driver = JointSurveyDriver(joint_params) + driver = JointSurveysDriver(joint_params) assert np.isclose(driver.models.reference_model[0], 0) # Took it from driver_A assert driver.models.starting_model.shape == (driver.models.n_active * 3,) assert np.isclose( @@ -338,7 +338,7 @@ def test_joint_surveys_conductivity_run( # Default to Conductivity (S/m) ) - driver = JointSurveyDriver(joint_params) + driver = JointSurveysDriver(joint_params) assert np.isclose( driver.models.reference_model[0], np.log(1 / 5.0) ) # Took it from driver_A @@ -419,7 +419,7 @@ def test_joint_surveys_tem_run( starting_model=1e-3, ) - driver = JointSurveyDriver(joint_params) + driver = JointSurveysDriver(joint_params) assert ( len( [ From 90c36810d64fcf5659209296817fce06ddb5047f Mon Sep 17 00:00:00 2001 From: domfournier Date: Fri, 20 Mar 2026 14:57:43 -0700 Subject: [PATCH 17/18] Fix imports --- tests/run_tests/driver_joint_cross_gradient_test.py | 2 +- tests/run_tests/driver_joint_surveys_test.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/run_tests/driver_joint_cross_gradient_test.py b/tests/run_tests/driver_joint_cross_gradient_test.py index 363db6cd..b6d5e346 100644 --- a/tests/run_tests/driver_joint_cross_gradient_test.py +++ b/tests/run_tests/driver_joint_cross_gradient_test.py @@ -20,8 +20,8 @@ DC3DInversionDriver, DC3DInversionOptions, ) -from simpeg_drivers.joint.joint_cross_gradient import JointCrossGradientOptions from simpeg_drivers.joint.joint_cross_gradient.driver import JointCrossGradientDriver +from simpeg_drivers.joint.joint_cross_gradient.options import JointCrossGradientOptions from simpeg_drivers.potential_fields.gravity import ( GravityForwardDriver, GravityForwardOptions, diff --git a/tests/run_tests/driver_joint_surveys_test.py b/tests/run_tests/driver_joint_surveys_test.py index 64790081..1ab0ca60 100644 --- a/tests/run_tests/driver_joint_surveys_test.py +++ b/tests/run_tests/driver_joint_surveys_test.py @@ -23,8 +23,8 @@ ) from simpeg_drivers.electromagnetics.time_domain import TDEMInversionDriver from simpeg_drivers.electromagnetics.time_domain.options import TDEMInversionOptions -from simpeg_drivers.joint.joint_surveys import JointSurveysOptions from simpeg_drivers.joint.joint_surveys.driver import JointSurveysDriver +from simpeg_drivers.joint.joint_surveys.options import JointSurveysOptions from simpeg_drivers.options import ActiveCellsOptions from simpeg_drivers.potential_fields.gravity import ( GravityForwardDriver, From faf805d6f2680f83c8e64a68d3dd722abd254ba3 Mon Sep 17 00:00:00 2001 From: domfournier Date: Mon, 23 Mar 2026 15:31:14 -0700 Subject: [PATCH 18/18] Change target on fem1d after removing double Directives in options --- tests/run_tests/driver_airborne_fem_1d_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/run_tests/driver_airborne_fem_1d_test.py b/tests/run_tests/driver_airborne_fem_1d_test.py index 0e180cd2..e3515b54 100644 --- a/tests/run_tests/driver_airborne_fem_1d_test.py +++ b/tests/run_tests/driver_airborne_fem_1d_test.py @@ -38,7 +38,7 @@ # To test the full run and validate the inversion. # Move this file out of the test directory and run. -target_run = {"data_norm": 804.9849282354428, "phi_d": 58200, "phi_m": 118} +target_run = {"data_norm": 804.9849282354428, "phi_d": 64500, "phi_m": 717} def test_fem_fwr_1d_run(