Skip to content

Commit 5f2b6d8

Browse files
authored
Merge pull request #89 from MiraGeoscience/GEOPY-789
GEOPY-789: Joint inversion: PGI
2 parents 1fff506 + c0711c7 commit 5f2b6d8

4 files changed

Lines changed: 89 additions & 6 deletions

File tree

simpeg/directives/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
SaveLogFilesGeoH5,
129129
SaveLPModelGroup,
130130
SaveModelGeoH5,
131+
SavePGIModel,
131132
SavePropertyGroup,
132133
SaveSensitivityGeoH5,
133134
)

simpeg/directives/_regularization.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,10 @@ def endIter(self):
289289
if not isinstance(reg, Sparse):
290290
continue
291291

292-
for obj in reg.objfcts:
292+
for multi, obj in reg:
293+
if multi == 0:
294+
continue
295+
293296
obj.irls_threshold /= self.irls_cooling_factor
294297

295298
self.metrics.irls_iteration_count += 1
@@ -327,10 +330,16 @@ def start_irls(self):
327330
if not isinstance(reg, Sparse):
328331
continue
329332

330-
for obj in reg.objfcts:
331-
threshold = np.percentile(
332-
np.abs(obj.mapping * obj._delta_m(self.invProb.model)),
333-
self.percentile,
333+
for multi, obj in reg:
334+
if multi == 0:
335+
continue
336+
337+
threshold = (
338+
np.percentile(
339+
np.abs(obj.mapping * obj._delta_m(self.invProb.model)),
340+
self.percentile,
341+
)
342+
+ 1e-16
334343
)
335344
if isinstance(obj, SmoothnessFirstOrder):
336345
threshold /= reg.regularization_mesh.base_length

simpeg/directives/_save_geoh5.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55

66
import numpy as np
77
from scipy.sparse import csc_matrix, csr_matrix
8+
from simpeg.regularization import PGIsmallness
9+
810
from .directives import InversionDirective
911
from simpeg.maps import IdentityMap
1012

1113
from geoh5py.data import NumericData
14+
from geoh5py.data.data_type import ReferencedValueMapType
1215
from geoh5py.groups.property_group import GroupTypeEnum
1316
from geoh5py.groups import UIJsonGroup
1417
from geoh5py.objects import ObjectBase
@@ -503,3 +506,72 @@ def get_names(
503506
base_name = "LP models"
504507

505508
return channel_name, base_name
509+
510+
511+
class SavePGIModel(SaveArrayGeoH5):
512+
"""
513+
Save the model as a property group in the geoh5 file
514+
"""
515+
516+
def __init__(
517+
self,
518+
h5_object: ObjectBase,
519+
pgi_regularization: PGIsmallness,
520+
unit_map: dict,
521+
physical_properties: list[str],
522+
reference_type: ReferencedValueMapType | None = None,
523+
**kwargs,
524+
):
525+
self.pgi_regularization = pgi_regularization
526+
self.unit_map: dict = unit_map
527+
self.reference_type = reference_type
528+
self.physical_properties = physical_properties
529+
super().__init__(h5_object, **kwargs)
530+
531+
def get_values(self, values: list[np.ndarray] | None):
532+
533+
if values is None:
534+
values = self.invProb.model
535+
536+
modellist = self.pgi_regularization.wiresmap * values
537+
model = np.c_[
538+
[a * b for a, b in zip(self.pgi_regularization.maplist, modellist)]
539+
].T
540+
membership = self.pgi_regularization.gmm._estimate_log_prob(model).argmax(
541+
axis=1
542+
)
543+
return membership
544+
545+
def write(self, iteration: int, values: list[np.ndarray] | None = None):
546+
"""
547+
Method to write the reference model with data map.
548+
"""
549+
petro_model = self.get_values(values)
550+
petro_model = self.apply_transformations(petro_model).flatten()
551+
channel_name, base_name = self.get_names("petrophysics", "", iteration)
552+
with fetch_active_workspace(self._geoh5, mode="r+") as w_s:
553+
h5_object = w_s.get_entity(self.h5_object)[0]
554+
data = h5_object.add_data(
555+
{
556+
channel_name: {
557+
"association": self.association,
558+
"values": petro_model,
559+
"type": "referenced",
560+
}
561+
}
562+
)
563+
564+
if self.reference_type is not None:
565+
data.entity_type.value_map = self.reference_type.value_map
566+
data.entity_type.color_map = self.reference_type.color_map
567+
568+
# TODO: Add the means of the transformed models
569+
# means = self.pgi_regularization.gmm.means_
570+
# for ii, phys_prop in enumerate(self.physical_properties):
571+
# data.add_data_map(
572+
# f"Mean {phys_prop}",
573+
# {
574+
# ind: f"{mean:.3e}"
575+
# for ind, mean in zip(self.unit_map, means[:, ii])
576+
# },
577+
# )

simpeg/directives/pgi_directives.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ def endIter(self):
121121
self.pgi_reg.gmm = clfupdate
122122
membership = self.pgi_reg.gmm.predict(model)
123123

124-
if self.fixed_membership is not None:
124+
if clfupdate.fixed_membership is not None:
125+
self.fixed_membership = clfupdate.fixed_membership
125126
membership[self.fixed_membership[:, 0]] = self.fixed_membership[:, 1]
126127

127128
mref = mkvc(self.pgi_reg.gmm.means_[membership])

0 commit comments

Comments
 (0)