Skip to content

Conversation

Copy link

Copilot AI commented Oct 14, 2025

Overview

This PR implements comprehensive JSON serialization and deserialization support for geological models in LoopStructural, enabling the entire model state—including interpolators and their solutions—to be saved to and loaded from JSON format.

Problem

Previously, the to_dict() method existed but had several limitations:

  • Numpy arrays were not converted to JSON-serializable lists
  • Feature interpolator state was not fully serialized
  • Solution coefficients from interpolation were not included
  • The method only saved feature names, not their complete state
  • Deserialization methods (from_dict(), load_from_json()) were not implemented

Solution

Enhanced the serialization system across all model components to ensure complete, JSON-compatible serialization and implemented full deserialization capability:

Core Changes

Interpolators

  • GeologicalInterpolator.to_dict(): Converts numpy arrays to lists for JSON compatibility
  • GeologicalInterpolator.from_dict(): Reconstructs interpolators with automatic type dispatch
  • DiscreteInterpolator.to_dict(): Includes solution coefficients (c array) and support structure
  • DiscreteInterpolator.from_dict(): Reconstructs support, solution coefficients, and constraint data
  • All constraint data (gradient, value, normal, tangent, interface) now properly serialized

Support Structures

  • BaseStructuredSupport.to_dict(): Converts all numpy arrays (origin, nsteps, step_vector, rotation_xy) to lists
  • TetMesh.to_dict(): Added to include type information for proper deserialization
  • TetMesh.__init__(): Updated to accept rotation_xy parameter
  • StructuredGrid.to_dict(): Uses proper type name serialization
  • Fixed nsteps serialization to prevent double increment during deserialization

Features

  • BaseFeature.to_dict(): Properly serializes FeatureType enums
  • GeologicalFeature.to_dict(): Includes complete interpolator state via to_dict()
  • GeologicalFeature.from_dict(): Reconstructs features with their interpolators

Model

  • GeologicalModel.to_dict(): Serializes all features with their complete state
  • GeologicalModel.from_dict(): Fully reconstructs models from dictionaries
  • GeologicalModel.save_to_json(): Convenience method for saving to file
  • GeologicalModel.load_from_json(): Loads and reconstructs models from JSON files
  • Error handling for individual feature serialization failures

What's Serialized

The complete model now includes:

  • Model configuration: Bounding box, stratigraphic column
  • Feature information: Name, type, associated faults and regions
  • Interpolator state: Type, all constraint data, solution coefficients, build status
  • Support structure: Grid/mesh configuration and parameters

Usage

# Serialize to dictionary
model_dict = model.to_dict()

# Deserialize from dictionary
model2 = GeologicalModel.from_dict(model_dict)

# Save to JSON file
model.save_to_json('my_model.json')

# Load from JSON file
model2 = GeologicalModel.load_from_json('my_model.json')

# Or use json module directly
import json
json_string = json.dumps(model.to_dict())
loaded_dict = json.loads(json_string)
model2 = GeologicalModel.from_dict(loaded_dict)

Testing

  • Added 11 comprehensive tests in tests/unit/modelling/test_model_serialization.py
    • 7 tests for serialization
    • 4 new tests for deserialization (from_dict, load_from_json, FDI support)
  • All tests pass
  • All 59 existing modelling tests continue to pass
  • Tested with multiple interpolator types (PLI, FDI)
  • Solution coefficients verified to match exactly (< 1e-10 difference)
  • Support structures maintain correct dimensions after round-trip
  • Interpolator evaluations produce identical results

Documentation

  • Added detailed example in examples/1_basic/plot_8_model_serialization.py
    • Demonstrates full round-trip serialization/deserialization
    • Shows solution verification with perfect match
    • Includes both dictionary and file-based approaches
  • Created comprehensive documentation in SERIALIZATION_IMPROVEMENTS.md

What Works Now

Complete round-trip serialization and deserialization:

  • Models can be saved to JSON and loaded back
  • Reconstructed models are functionally identical to originals
  • Solution coefficients match exactly
  • Support structures maintain correct dimensions
  • Works with PLI (Piecewise Linear) and FDI (Finite Difference) interpolators

Backward Compatibility

All changes are backward compatible:

  • Existing to_json() methods continue to work
  • No breaking changes to existing API
  • New functionality is additive only
  • Deserialization methods were previously stubs that raised NotImplementedError
Original prompt

Work on improving the json serialisation of the model. Ensure that the entire geological model including the current state of the interpolator, the solution to the interpolation can be saved into a json datastructure. The best approach is to make sure that each object that makes up the geological model has a .to_dict() method and a from_dict() method that allows for the state to be saved/loaded from json.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 4 commits October 14, 2025 06:33
Co-authored-by: lachlangrose <7371904+lachlangrose@users.noreply.github.com>
Co-authored-by: lachlangrose <7371904+lachlangrose@users.noreply.github.com>
Co-authored-by: lachlangrose <7371904+lachlangrose@users.noreply.github.com>
Co-authored-by: lachlangrose <7371904+lachlangrose@users.noreply.github.com>
Copilot AI changed the title [WIP] Improve JSON serialization for geological model Implement comprehensive JSON serialization for geological models Oct 14, 2025
Copilot AI requested a review from lachlangrose October 14, 2025 06:45
Copilot finished work on behalf of lachlangrose October 14, 2025 06:45
@lachlangrose
Copy link
Owner

@copilot can you start implementing from_dict functionality for all model elements

- Add from_dict methods to GeologicalInterpolator with automatic type dispatch
- Implement from_dict for DiscreteInterpolator to reconstruct support and solution
- Add from_dict to GeologicalFeature to reconstruct features with interpolators
- Implement from_dict for GeologicalModel to fully reconstruct models
- Add to_dict and rotation_xy parameter to TetMesh for proper serialization
- Update load_from_json to use from_dict instead of raising NotImplementedError
- Add 4 new tests for deserialization (from_dict, load_from_json, FDI support)
- Update example to demonstrate full round-trip serialization/deserialization

Co-authored-by: lachlangrose <7371904+lachlangrose@users.noreply.github.com>
Copy link
Author

Copilot AI commented Oct 14, 2025

@copilot can you start implementing from_dict functionality for all model elements

I've implemented full from_dict functionality for all model elements. The implementation includes:

Core changes:

  • GeologicalInterpolator.from_dict() - Routes to correct interpolator class based on type
  • DiscreteInterpolator.from_dict() - Reconstructs support, solution coefficients, and data
  • GeologicalFeature.from_dict() - Reconstructs features with interpolators
  • GeologicalModel.from_dict() - Fully reconstructs models from dictionaries
  • TetMesh updates - Added to_dict() and rotation_xy parameter for proper serialization

Usage:

# Dictionary round-trip
model_dict = model.to_dict()
model2 = GeologicalModel.from_dict(model_dict)

# File round-trip
model.save_to_json('model.json')
model2 = GeologicalModel.load_from_json('model.json')

Testing:

  • Added 4 new tests for deserialization
  • All 11 serialization tests pass
  • Solution coefficients match exactly (< 1e-10 difference)
  • Tested with both PLI and FDI interpolators

See commit for full implementation details.

The BaseStructuredSupport stores nsteps internally as nsteps+1 (added in __init__).
When serializing, we need to subtract 1 so that when deserialized and incremented again,
we get the correct value. This ensures support structures maintain the correct dimensions
after round-trip serialization.

Co-authored-by: lachlangrose <7371904+lachlangrose@users.noreply.github.com>
Copilot AI changed the title Implement comprehensive JSON serialization for geological models Implement comprehensive JSON serialization and deserialization for geological models Oct 14, 2025
Copilot finished work on behalf of lachlangrose October 14, 2025 23:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants