Skip to content

Commit 9a8fcbe

Browse files
authored
Merge pull request #1013 from flohorovicic/feature/json_io
Feature/json io
2 parents a002410 + 040d84a commit 9a8fcbe

20 files changed

+2931
-5
lines changed

.gitignore

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
2-
31
.vscode
42
.idea
53
.DS_Store
@@ -172,3 +170,14 @@ examples/integrations/*.out
172170
/.obsidian/core-plugins-migration.json
173171
/.obsidian/hotkeys.json
174172
/.obsidian/workspace.json
173+
174+
# Ignore generated tutorial files
175+
examples/tutorials/z_other_tutorials/json_io/04_simple_layer_stack.py
176+
examples/tutorials/z_other_tutorials/json_io/fault_scalar_field.png
177+
examples/tutorials/z_other_tutorials/json_io/initial_model_y.png
178+
examples/tutorials/z_other_tutorials/json_io/model_with_data.png
179+
examples/tutorials/z_other_tutorials/json_io/multiple_series_faults_computed.json
180+
181+
# Generated JSON files from examples
182+
examples/tutorials/z_other_tutorials/json_io/combination_model.json
183+
examples/tutorials/z_other_tutorials/json_io/combination_model_computed.json
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
"""
2+
Tutorial for JSON I/O operations in GemPy - Surface Points
3+
=======================================================
4+
5+
This tutorial demonstrates how to save and load surface points data using JSON files in GemPy.
6+
"""
7+
8+
import json
9+
import numpy as np
10+
import gempy as gp
11+
from gempy.modules.json_io import JsonIO
12+
13+
# Create a sample surface points dataset
14+
# ------------------------------------
15+
16+
# Create some sample surface points
17+
x = np.array([0, 1, 2, 3, 4])
18+
y = np.array([0, 1, 2, 3, 4])
19+
z = np.array([0, 1, 2, 3, 4])
20+
ids = np.array([0, 0, 1, 1, 2]) # Three different surfaces
21+
nugget = np.array([0.00002, 0.00002, 0.00002, 0.00002, 0.00002])
22+
23+
# Create name to id mapping
24+
name_id_map = {f"surface_{id}": id for id in np.unique(ids)}
25+
26+
# Create a SurfacePointsTable
27+
surface_points = gp.data.SurfacePointsTable.from_arrays(
28+
x=x,
29+
y=y,
30+
z=z,
31+
names=[f"surface_{id}" for id in ids],
32+
nugget=nugget,
33+
name_id_map=name_id_map
34+
)
35+
36+
# Create a JSON file with the surface points data
37+
# ---------------------------------------------
38+
39+
# Create the JSON structure
40+
json_data = {
41+
"metadata": {
42+
"name": "sample_model",
43+
"creation_date": "2024-03-19",
44+
"last_modification_date": "2024-03-19",
45+
"owner": "tutorial"
46+
},
47+
"surface_points": [
48+
{
49+
"x": float(x[i]),
50+
"y": float(y[i]),
51+
"z": float(z[i]),
52+
"id": int(ids[i]),
53+
"nugget": float(nugget[i])
54+
}
55+
for i in range(len(x))
56+
],
57+
"orientations": [],
58+
"faults": [],
59+
"series": [],
60+
"grid_settings": {
61+
"regular_grid_resolution": [10, 10, 10],
62+
"regular_grid_extent": [0, 4, 0, 4, 0, 4],
63+
"octree_levels": None
64+
},
65+
"interpolation_options": {}
66+
}
67+
68+
# Save the JSON file
69+
with open("sample_surface_points.json", "w") as f:
70+
json.dump(json_data, f, indent=4)
71+
72+
# Load the surface points from JSON
73+
# -------------------------------
74+
75+
# Load the model from JSON
76+
loaded_surface_points = JsonIO._load_surface_points(json_data["surface_points"])
77+
78+
# Verify the loaded data
79+
print("\nOriginal surface points:")
80+
print(surface_points)
81+
print("\nLoaded surface points:")
82+
print(loaded_surface_points)
83+
84+
# Verify the data matches
85+
print("\nVerifying data matches:")
86+
print(f"X coordinates match: {np.allclose(surface_points.xyz[:, 0], loaded_surface_points.xyz[:, 0])}")
87+
print(f"Y coordinates match: {np.allclose(surface_points.xyz[:, 1], loaded_surface_points.xyz[:, 1])}")
88+
print(f"Z coordinates match: {np.allclose(surface_points.xyz[:, 2], loaded_surface_points.xyz[:, 2])}")
89+
print(f"IDs match: {np.array_equal(surface_points.ids, loaded_surface_points.ids)}")
90+
print(f"Nugget values match: {np.allclose(surface_points.nugget, loaded_surface_points.nugget)}")
91+
92+
# Print the name_id_maps to compare
93+
print("\nName to ID mappings:")
94+
print(f"Original: {surface_points.name_id_map}")
95+
print(f"Loaded: {loaded_surface_points.name_id_map}")
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
"""
2+
Tutorial: Loading a Horizontal Stratigraphic Model using JSON I/O
3+
===============================================================
4+
5+
This tutorial demonstrates how to load a horizontal stratigraphic model using GemPy's JSON I/O functionality.
6+
The model consists of two horizontal layers (rock1 and rock2) with surface points and orientations.
7+
"""
8+
9+
# %%
10+
# Import necessary libraries
11+
import matplotlib
12+
matplotlib.use('Agg') # Use non-interactive backend
13+
import gempy as gp
14+
import gempy_viewer as gpv
15+
import numpy as np
16+
import json
17+
from pathlib import Path
18+
import matplotlib.pyplot as plt
19+
from datetime import datetime
20+
21+
# %%
22+
# Define the model data
23+
model_data = {
24+
"metadata": {
25+
"name": "Horizontal Stratigraphic Model",
26+
"creation_date": "2024-03-24",
27+
"last_modification_date": datetime.now().strftime("%Y-%m-%d"),
28+
"owner": "GemPy Team"
29+
},
30+
"surface_points": [
31+
{"x": 0.0, "y": 0.0, "z": 0.0, "id": 1, "nugget": 0.0},
32+
{"x": 1.0, "y": 0.0, "z": 0.0, "id": 1, "nugget": 0.0},
33+
{"x": 0.0, "y": 1.0, "z": 0.0, "id": 1, "nugget": 0.0},
34+
{"x": 1.0, "y": 1.0, "z": 0.0, "id": 1, "nugget": 0.0},
35+
{"x": 0.0, "y": 0.0, "z": 1.0, "id": 2, "nugget": 0.0},
36+
{"x": 1.0, "y": 0.0, "z": 1.0, "id": 2, "nugget": 0.0},
37+
{"x": 0.0, "y": 1.0, "z": 1.0, "id": 2, "nugget": 0.0},
38+
{"x": 1.0, "y": 1.0, "z": 1.0, "id": 2, "nugget": 0.0}
39+
],
40+
"orientations": [
41+
{"x": 0.5, "y": 0.5, "z": 0.0, "G_x": 0.0, "G_y": 0.0, "G_z": 1.0, "id": 1, "nugget": 0.0, "polarity": 1},
42+
{"x": 0.5, "y": 0.5, "z": 1.0, "G_x": 0.0, "G_y": 0.0, "G_z": 1.0, "id": 2, "nugget": 0.0, "polarity": 1}
43+
],
44+
"series": [
45+
{
46+
"name": "series1",
47+
"surfaces": ["layer1", "layer2"],
48+
"structural_relation": "ERODE",
49+
"colors": ["#ff0000", "#00ff00"]
50+
}
51+
],
52+
"grid_settings": {
53+
"regular_grid_resolution": [10, 10, 10],
54+
"regular_grid_extent": [0.0, 1.0, 0.0, 1.0, 0.0, 1.0],
55+
"octree_levels": None
56+
},
57+
"interpolation_options": {
58+
"kernel_options": {
59+
"range": 1.7,
60+
"c_o": 10
61+
},
62+
"mesh_extraction": True,
63+
"number_octree_levels": 1
64+
},
65+
"fault_relations": None,
66+
"id_name_mapping": {
67+
"name_to_id": {
68+
"layer1": 1,
69+
"layer2": 2
70+
}
71+
}
72+
}
73+
74+
# %%
75+
# Save the model data to a JSON file
76+
tutorial_dir = Path(__file__).parent
77+
json_file = tutorial_dir / "horizontal_stratigraphic.json"
78+
with open(json_file, "w") as f:
79+
json.dump(model_data, f, indent=4)
80+
81+
# %%
82+
# Load the model from JSON
83+
model = gp.modules.json_io.JsonIO.load_model_from_json(str(json_file))
84+
85+
# %%
86+
# Compute the geological model
87+
gp.compute_model(model)
88+
89+
# %%
90+
# Plot the model
91+
# Plot the initial geological model in the y direction without results
92+
fig, ax = plt.subplots(figsize=(10, 6))
93+
gpv.plot_2d(model, direction=['y'], show_results=False, ax=ax)
94+
plt.title("Initial Geological Model (y direction)")
95+
plt.savefig('initial_model_y.png')
96+
plt.close()
97+
98+
# Plot the result of the model in the x and y direction with data and without boundaries
99+
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
100+
gpv.plot_2d(model, direction=['x'], show_data=True, show_boundaries=False, ax=ax1)
101+
ax1.set_title("Model with Data (x direction)")
102+
gpv.plot_2d(model, direction=['y'], show_data=True, show_boundaries=False, ax=ax2)
103+
ax2.set_title("Model with Data (y direction)")
104+
plt.tight_layout()
105+
plt.savefig('model_with_data.png')
106+
plt.close()

0 commit comments

Comments
 (0)