Skip to content

Commit 6cf9a44

Browse files
committed
fix: Fix metadata handling in JSON I/O for proper preservation when loading and saving models
1 parent 0f1734b commit 6cf9a44

File tree

2 files changed

+103
-3
lines changed

2 files changed

+103
-3
lines changed

examples/tutorials/z_other_tutorials/json_io/03_multiple_series_faults.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,13 @@
104104
# Load the model from JSON
105105
model = JsonIO.load_model_from_json(str(json_file))
106106

107+
# Print metadata to verify it's properly loaded
108+
print("\nModel Metadata:")
109+
print(f"Name: {model.meta.name}")
110+
print(f"Creation Date: {model.meta.creation_date}")
111+
print(f"Last Modification Date: {model.meta.last_modification_date}")
112+
print(f"Owner: {model.meta.owner}")
113+
107114
# Print structural groups
108115
print("\nStructural Groups:")
109116
print(model.structural_frame.structural_groups)
@@ -130,6 +137,21 @@
130137
# Compute the geological model
131138
gp.compute_model(model)
132139

140+
# %%
141+
# Save the computed model to a new JSON file
142+
computed_json_file = tutorial_dir / "multiple_series_faults_computed.json"
143+
JsonIO.save_model_to_json(model, str(computed_json_file))
144+
print(f"\nSaved computed model to: {computed_json_file}")
145+
146+
# %%
147+
# Load the computed model back to verify metadata is preserved
148+
reloaded_model = JsonIO.load_model_from_json(str(computed_json_file))
149+
print("\nReloaded Model Metadata:")
150+
print(f"Name: {reloaded_model.meta.name}")
151+
print(f"Creation Date: {reloaded_model.meta.creation_date}")
152+
print(f"Last Modification Date: {reloaded_model.meta.last_modification_date}")
153+
print(f"Owner: {reloaded_model.meta.owner}")
154+
133155
# %%
134156
# Plot the model
135157
# Plot the initial geological model in the y direction without results

gempy/modules/json_io/json_operations.py

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def load_model_from_json(file_path: str):
2626
GeoModel: A new GemPy model instance
2727
"""
2828
# Import here to avoid circular imports
29-
from gempy.core.data.geo_model import GeoModel
29+
from gempy.core.data.geo_model import GeoModel, GeoModelMeta
3030
from gempy.core.data.grid import Grid
3131
from gempy.core.data.structural_frame import StructuralFrame
3232
from gempy_engine.core.data import InterpolationOptions
@@ -68,6 +68,14 @@ def load_model_from_json(file_path: str):
6868
number_octree_levels=1 # Default value
6969
)
7070

71+
# Create GeoModelMeta with all metadata fields
72+
model_meta = GeoModelMeta(
73+
name=data['metadata']['name'],
74+
creation_date=data['metadata'].get('creation_date', None),
75+
last_modification_date=data['metadata'].get('last_modification_date', None),
76+
owner=data['metadata'].get('owner', None)
77+
)
78+
7179
# Create GeoModel
7280
model = GeoModel(
7381
name=data['metadata']['name'],
@@ -76,6 +84,9 @@ def load_model_from_json(file_path: str):
7684
interpolation_options=interpolation_options
7785
)
7886

87+
# Set the metadata
88+
model.meta = model_meta
89+
7990
# Map series to surfaces with structural relations
8091
mapping_object = {series['name']: series['surfaces'] for series in data['series']}
8192
map_stack_to_surfaces(model, mapping_object, series_data=data['series'])
@@ -210,8 +221,75 @@ def save_model_to_json(model, file_path: str) -> None:
210221
model: The GemPy model to save
211222
file_path (str): Path where to save the JSON file
212223
"""
213-
# TODO: Implement saving logic
214-
raise NotImplementedError("JSON saving not yet implemented")
224+
# Create JSON structure
225+
json_data = {
226+
"metadata": {
227+
"name": model.meta.name,
228+
"creation_date": model.meta.creation_date,
229+
"last_modification_date": model.meta.last_modification_date,
230+
"owner": model.meta.owner
231+
},
232+
"surface_points": [],
233+
"orientations": [],
234+
"series": [],
235+
"grid_settings": {
236+
"regular_grid_resolution": model.grid._dense_grid.resolution.tolist(),
237+
"regular_grid_extent": model.grid._dense_grid.extent.tolist(),
238+
"octree_levels": None # TODO: Add octree levels if needed
239+
},
240+
"interpolation_options": {}
241+
}
242+
243+
# Get series and surface information
244+
for group in model.structural_frame.structural_groups:
245+
series_entry = {
246+
"name": group.name,
247+
"surfaces": [element.name for element in group.elements],
248+
"structural_relation": group.structural_relation.name,
249+
"colors": [element.color for element in group.elements]
250+
}
251+
json_data["series"].append(series_entry)
252+
253+
# Get surface points
254+
surface_points_table = model.surface_points_copy
255+
xyz_values = surface_points_table.xyz
256+
ids = surface_points_table.ids
257+
nugget_values = surface_points_table.nugget
258+
259+
for i in range(len(xyz_values)):
260+
point = {
261+
"x": float(xyz_values[i, 0]),
262+
"y": float(xyz_values[i, 1]),
263+
"z": float(xyz_values[i, 2]),
264+
"id": int(ids[i]),
265+
"nugget": float(nugget_values[i])
266+
}
267+
json_data["surface_points"].append(point)
268+
269+
# Get orientations
270+
orientations_table = model.orientations_copy
271+
ori_xyz_values = orientations_table.xyz
272+
ori_grads_values = orientations_table.grads
273+
ori_ids = orientations_table.ids
274+
ori_nugget_values = orientations_table.nugget
275+
276+
for i in range(len(ori_xyz_values)):
277+
orientation = {
278+
"x": float(ori_xyz_values[i, 0]),
279+
"y": float(ori_xyz_values[i, 1]),
280+
"z": float(ori_xyz_values[i, 2]),
281+
"G_x": float(ori_grads_values[i, 0]),
282+
"G_y": float(ori_grads_values[i, 1]),
283+
"G_z": float(ori_grads_values[i, 2]),
284+
"id": int(ori_ids[i]),
285+
"nugget": float(ori_nugget_values[i]),
286+
"polarity": 1 # Default value, update if available
287+
}
288+
json_data["orientations"].append(orientation)
289+
290+
# Save to file
291+
with open(file_path, 'w') as f:
292+
json.dump(json_data, f, indent=4)
215293

216294
@staticmethod
217295
def _validate_json_schema(data: Dict[str, Any]) -> bool:

0 commit comments

Comments
 (0)