1
+ import numpy as np
1
2
import os
3
+ import pyro .distributions as dist
4
+ import torch
5
+ from pyro .distributions import TorchDistributionMixin
6
+
2
7
import gempy as gp
3
- import gempy_engine
4
- import numpy as np
8
+ from gempy_engine .core .backend_tensor import BackendTensor
5
9
6
10
7
11
def test_basic_gempy_I () -> None :
@@ -20,68 +24,72 @@ def test_basic_gempy_I() -> None:
20
24
# TODO: Convert this into an options preset
21
25
geo_model .interpolation_options .uni_degree = 0
22
26
geo_model .interpolation_options .mesh_extraction = False
23
- geo_model .interpolation_options .sigmoid_slope = 1100.
27
+ geo_model .interpolation_options .sigmoid_slope = 1100.
24
28
29
+ # region Minimal grid for the specific likelihood function
25
30
x_loc = 6000
26
31
y_loc = 0
27
32
z_loc = np .linspace (0 , 4000 , 100 )
28
33
xyz_coord = np .array ([[x_loc , y_loc , z ] for z in z_loc ])
29
34
gp .set_custom_grid (geo_model .grid , xyz_coord = xyz_coord )
35
+ # endregion
30
36
31
37
# TODO: Make sure only the custom grid ins active
32
-
38
+
39
+
33
40
gp .compute_model (
34
41
gempy_model = geo_model ,
35
- engine_config = gp .data .GemPyEngineConfig (backend = gp .data .AvailableBackends .numpy )
42
+ engine_config = gp .data .GemPyEngineConfig (
43
+ backend = gp .data .AvailableBackends .numpy
44
+ )
36
45
)
37
-
38
- from gempy_engine .core .backend_tensor import BackendTensor
39
- BackendTensor .change_backend_gempy (engine_backend = gp .data .AvailableBackends .PYTORCH )
40
46
41
- import pyro . distributions as dist
42
- import torch
47
+ # TODO: Make this a more elegant way
48
+ BackendTensor . change_backend_gempy ( engine_backend = gp . data . AvailableBackends . PYTORCH )
43
49
44
50
normal = dist .Normal (
45
51
loc = (geo_model .surface_points_copy_transformed .xyz [0 , 2 ]),
46
52
scale = torch .tensor (0.1 , dtype = torch .float64 )
47
53
)
48
- # %%
49
- # Running Prior Sampling and Visualization
50
- # ----------------------------------------
51
- # Prior sampling is an essential step in probabilistic modeling.
52
- # It helps in understanding the distribution of our prior assumptions before observing any data.
53
-
54
- # %%
55
- # Prepare observation data
56
- import torch
57
- y_obs_list = torch . tensor ([ 200 , 210 , 190 ])
58
-
59
- # %%
54
+
55
+ from gempy_probability . modules . model_definition . model_examples import model
56
+ _prob_run (
57
+ geo_model = geo_model ,
58
+ prob_model = model ,
59
+ normal = normal ,
60
+ y_obs_list = torch . tensor ([ 200 , 210 , 190 ])
61
+ )
62
+
63
+
64
+ def _prob_run ( geo_model : gp . data . GeoModel , prob_model : callable ,
65
+ normal : TorchDistributionMixin , y_obs_list : torch . Tensor ) -> None :
60
66
# Run prior sampling and visualization
61
67
from pyro .infer import Predictive
62
68
import pyro
63
69
import arviz as az
64
70
import matplotlib .pyplot as plt
65
71
66
- from gempy_probability .modules .model_definition .model_examples import model
72
+ from pyro .infer import NUTS
73
+ from pyro .infer import MCMC
74
+ from pyro .infer .autoguide import init_to_mean
75
+
76
+ # region prior sampling
67
77
predictive = Predictive (
68
- model = model ,
78
+ model = prob_model ,
69
79
num_samples = 50
70
80
)
71
-
72
81
prior = predictive (geo_model , normal , y_obs_list )
73
82
74
83
data = az .from_pyro (prior = prior )
75
84
az .plot_trace (data .prior )
76
85
plt .show ()
77
86
78
- from pyro .infer import NUTS
79
- from pyro .infer import MCMC
80
- from pyro .infer .autoguide import init_to_mean
87
+ # endregion
81
88
89
+ # region inference
82
90
pyro .primitives .enable_validation (is_validate = True )
83
91
nuts_kernel = NUTS (
84
- model ,
92
+ prob_model ,
85
93
step_size = 0.0085 ,
86
94
adapt_step_size = True ,
87
95
target_accept_prob = 0.9 ,
@@ -95,20 +103,24 @@ def test_basic_gempy_I() -> None:
95
103
disable_validation = False
96
104
)
97
105
mcmc .run (geo_model , normal , y_obs_list )
98
-
99
106
posterior_samples = mcmc .get_samples ()
100
-
101
107
posterior_predictive_fn = Predictive (
102
- model = model ,
108
+ model = prob_model ,
103
109
posterior_samples = posterior_samples
104
110
)
105
-
106
111
posterior_predictive = posterior_predictive_fn (geo_model , normal , y_obs_list )
107
-
108
112
data = az .from_pyro (posterior = mcmc , prior = prior , posterior_predictive = posterior_predictive )
113
+ # Test posterior mean values
114
+ posterior_top_mean = float (data .posterior [r'$\mu_{top}$' ].mean ())
115
+ assert 0.0070 < posterior_top_mean < 0.0071 , f"Top layer mean { posterior_top_mean } outside expected range"
116
+ posterior_thickness_mean = float (data .posterior_predictive [r'$\mu_{thickness}$' ].mean ())
117
+ assert 220 < posterior_thickness_mean < 225 , f"Thickness mean { posterior_thickness_mean } outside expected range"
118
+ # Test convergence diagnostics
119
+ assert float (data .sample_stats .diverging .sum ()) == 0 , "MCMC sampling has divergences"
120
+ # endregion
121
+
109
122
az .plot_trace (data )
110
123
plt .show ()
111
-
112
124
from gempy_probability .modules .plot .plot_posterior import default_red , default_blue
113
125
az .plot_density (
114
126
data = [data .posterior_predictive , data .prior_predictive ],
@@ -118,7 +130,6 @@ def test_basic_gempy_I() -> None:
118
130
colors = [default_red , default_blue ],
119
131
)
120
132
plt .show ()
121
-
122
133
az .plot_density (
123
134
data = [data , data .prior ],
124
135
shade = .9 ,
0 commit comments