8
8
import gempy as gp
9
9
from gempy .modules .json_io import JsonIO
10
10
from gempy_engine .core .data .stack_relation_type import StackRelationType
11
+ from gempy .core .data .importer_helper import ImporterHelper
12
+ import pandas as pd
13
+ from gempy .core .data .structural_group import FaultsRelationSpecialCase
11
14
12
15
13
16
@pytest .fixture
@@ -580,4 +583,234 @@ def test_interpolation_options_handling(tmp_path, sample_model_with_series):
580
583
assert loaded_model .interpolation_options .kernel_options .range == 10.0
581
584
assert loaded_model .interpolation_options .kernel_options .c_o == 15.0
582
585
assert loaded_model .interpolation_options .mesh_extraction is False
583
- assert loaded_model .interpolation_options .number_octree_levels == 2
586
+ assert loaded_model .interpolation_options .number_octree_levels == 2
587
+
588
+
589
+ def test_fault_relationships (tmp_path ):
590
+ """Test saving and loading models with fault relationships."""
591
+ # Create temporary CSV files for surface points and orientations
592
+ surface_points_data = pd .DataFrame ({
593
+ 'X' : [500 , 500 , 500 ],
594
+ 'Y' : [500 , 500 , 500 ],
595
+ 'Z' : [800 , 500 , 200 ],
596
+ 'surface' : ['fault' , 'rock2' , 'rock1' ]
597
+ })
598
+ orientations_data = pd .DataFrame ({
599
+ 'X' : [500 , 500 , 500 ],
600
+ 'Y' : [500 , 500 , 500 ],
601
+ 'Z' : [800 , 500 , 200 ],
602
+ 'dip' : [90 , 0 , 0 ],
603
+ 'azimuth' : [90 , 90 , 90 ],
604
+ 'polarity' : [1 , 1 , 1 ],
605
+ 'surface' : ['fault' , 'rock2' , 'rock1' ]
606
+ })
607
+
608
+ surface_points_path = tmp_path / "surface_points.csv"
609
+ orientations_path = tmp_path / "orientations.csv"
610
+ surface_points_data .to_csv (surface_points_path , index = False )
611
+ orientations_data .to_csv (orientations_path , index = False )
612
+
613
+ # Create a model with fault relationships
614
+ importer_helper = ImporterHelper (
615
+ path_to_surface_points = str (surface_points_path ),
616
+ path_to_orientations = str (orientations_path )
617
+ )
618
+ model = gp .create_geomodel (
619
+ project_name = 'fault_test' ,
620
+ extent = [0 , 1000 , 0 , 1000 , 0 , 1000 ],
621
+ resolution = [10 , 10 , 10 ],
622
+ importer_helper = importer_helper
623
+ )
624
+
625
+ # Map stack to surfaces
626
+ gp .map_stack_to_surfaces (
627
+ gempy_model = model ,
628
+ mapping_object = {
629
+ "Fault_Series" : ['fault' ],
630
+ "Strat_Series1" : ['rock2' ],
631
+ "Strat_Series2" : ['rock1' ]
632
+ }
633
+ )
634
+
635
+ # Set structural relations
636
+ model .structural_frame .structural_groups [0 ].structural_relation = StackRelationType .FAULT
637
+ model .structural_frame .structural_groups [0 ].fault_relations = FaultsRelationSpecialCase .OFFSET_ALL
638
+
639
+ # Save the model
640
+ file_path = tmp_path / "fault_model.json"
641
+ JsonIO .save_model_to_json (model , str (file_path ))
642
+
643
+ # Load the model and verify
644
+ loaded_model = JsonIO .load_model_from_json (str (file_path ))
645
+
646
+ # Check structural groups
647
+ assert len (loaded_model .structural_frame .structural_groups ) == 3
648
+ assert loaded_model .structural_frame .structural_groups [0 ].name == "Fault_Series"
649
+ assert loaded_model .structural_frame .structural_groups [0 ].structural_relation == StackRelationType .FAULT
650
+ assert loaded_model .structural_frame .structural_groups [0 ].fault_relations == FaultsRelationSpecialCase .OFFSET_ALL
651
+
652
+ # Check fault relations matrix
653
+ np .testing .assert_array_equal (
654
+ loaded_model .structural_frame .fault_relations ,
655
+ np .array ([[0 , 1 , 1 ], [0 , 0 , 0 ], [0 , 0 , 0 ]])
656
+ )
657
+
658
+
659
+ def test_multiple_series_relationships (tmp_path ):
660
+ """Test saving and loading models with multiple series and different structural relationships."""
661
+ # Create temporary CSV files for surface points and orientations
662
+ surface_points_data = pd .DataFrame ({
663
+ 'X' : [500 , 500 , 500 , 500 ],
664
+ 'Y' : [500 , 500 , 500 , 500 ],
665
+ 'Z' : [800 , 600 , 400 , 200 ],
666
+ 'surface' : ['fault' , 'rock3' , 'rock2' , 'rock1' ]
667
+ })
668
+ orientations_data = pd .DataFrame ({
669
+ 'X' : [500 , 500 , 500 , 500 ],
670
+ 'Y' : [500 , 500 , 500 , 500 ],
671
+ 'Z' : [800 , 600 , 400 , 200 ],
672
+ 'dip' : [90 , 0 , 0 , 0 ],
673
+ 'azimuth' : [90 , 90 , 90 , 90 ],
674
+ 'polarity' : [1 , 1 , 1 , 1 ],
675
+ 'surface' : ['fault' , 'rock3' , 'rock2' , 'rock1' ]
676
+ })
677
+
678
+ surface_points_path = tmp_path / "surface_points.csv"
679
+ orientations_path = tmp_path / "orientations.csv"
680
+ surface_points_data .to_csv (surface_points_path , index = False )
681
+ orientations_data .to_csv (orientations_path , index = False )
682
+
683
+ # Create a model with multiple series relationships
684
+ importer_helper = ImporterHelper (
685
+ path_to_surface_points = str (surface_points_path ),
686
+ path_to_orientations = str (orientations_path )
687
+ )
688
+ model = gp .create_geomodel (
689
+ project_name = 'multiple_series_test' ,
690
+ extent = [0 , 1000 , 0 , 1000 , 0 , 1000 ],
691
+ resolution = [10 , 10 , 10 ],
692
+ importer_helper = importer_helper
693
+ )
694
+
695
+ # Map stack to surfaces
696
+ gp .map_stack_to_surfaces (
697
+ gempy_model = model ,
698
+ mapping_object = {
699
+ "Fault_Series" : ['fault' ],
700
+ "Series3" : ['rock3' ],
701
+ "Series2" : ['rock2' ],
702
+ "Series1" : ['rock1' ]
703
+ }
704
+ )
705
+
706
+ # Set structural relations
707
+ model .structural_frame .structural_groups [0 ].structural_relation = StackRelationType .FAULT
708
+ model .structural_frame .structural_groups [0 ].fault_relations = FaultsRelationSpecialCase .OFFSET_ALL
709
+ model .structural_frame .structural_groups [1 ].structural_relation = StackRelationType .ONLAP
710
+ model .structural_frame .structural_groups [2 ].structural_relation = StackRelationType .ERODE
711
+ model .structural_frame .structural_groups [3 ].structural_relation = StackRelationType .ERODE
712
+
713
+ # Set colors for verification
714
+ model .structural_frame .get_element_by_name ("fault" ).color = '#527682' # Fault color
715
+ model .structural_frame .get_element_by_name ("rock3" ).color = '#9f0052' # rock3 color
716
+ model .structural_frame .get_element_by_name ("rock2" ).color = '#015482' # rock2 color
717
+ model .structural_frame .get_element_by_name ("rock1" ).color = '#728f02' # rock1 color
718
+
719
+ # Save the model
720
+ file_path = tmp_path / "multiple_series_model.json"
721
+ JsonIO .save_model_to_json (model , str (file_path ))
722
+
723
+ # Load the model and verify
724
+ loaded_model = JsonIO .load_model_from_json (str (file_path ))
725
+
726
+ # Check structural groups
727
+ assert len (loaded_model .structural_frame .structural_groups ) == 4
728
+ assert loaded_model .structural_frame .structural_groups [0 ].structural_relation == StackRelationType .FAULT
729
+ assert loaded_model .structural_frame .structural_groups [1 ].structural_relation == StackRelationType .ONLAP
730
+ assert loaded_model .structural_frame .structural_groups [2 ].structural_relation == StackRelationType .ERODE
731
+
732
+ # Check colors are preserved
733
+ assert loaded_model .structural_frame .get_element_by_name ("fault" ).color == '#527682'
734
+ assert loaded_model .structural_frame .get_element_by_name ("rock3" ).color == '#9f0052'
735
+ assert loaded_model .structural_frame .get_element_by_name ("rock2" ).color == '#015482'
736
+ assert loaded_model .structural_frame .get_element_by_name ("rock1" ).color == '#728f02'
737
+
738
+
739
+ def test_combination_model (tmp_path ):
740
+ """Test saving and loading a complex model that combines faults and unconformities."""
741
+ # Create temporary CSV files for surface points and orientations
742
+ surface_points_data = pd .DataFrame ({
743
+ 'X' : [500 , 500 , 500 ],
744
+ 'Y' : [500 , 500 , 500 ],
745
+ 'Z' : [800 , 500 , 200 ],
746
+ 'surface' : ['fault' , 'rock2' , 'rock1' ]
747
+ })
748
+ orientations_data = pd .DataFrame ({
749
+ 'X' : [500 , 500 , 500 ],
750
+ 'Y' : [500 , 500 , 500 ],
751
+ 'Z' : [800 , 500 , 200 ],
752
+ 'dip' : [90 , 0 , 0 ],
753
+ 'azimuth' : [90 , 90 , 90 ],
754
+ 'polarity' : [1 , 1 , 1 ],
755
+ 'surface' : ['fault' , 'rock2' , 'rock1' ]
756
+ })
757
+
758
+ surface_points_path = tmp_path / "surface_points.csv"
759
+ orientations_path = tmp_path / "orientations.csv"
760
+ surface_points_data .to_csv (surface_points_path , index = False )
761
+ orientations_data .to_csv (orientations_path , index = False )
762
+
763
+ # Create a combination model
764
+ importer_helper = ImporterHelper (
765
+ path_to_surface_points = str (surface_points_path ),
766
+ path_to_orientations = str (orientations_path )
767
+ )
768
+ model = gp .create_geomodel (
769
+ project_name = 'Combination Model' ,
770
+ extent = [0 , 1000 , 0 , 1000 , 0 , 1000 ],
771
+ resolution = [10 , 10 , 10 ],
772
+ importer_helper = importer_helper
773
+ )
774
+
775
+ # Map stack to surfaces
776
+ gp .map_stack_to_surfaces (
777
+ gempy_model = model ,
778
+ mapping_object = {
779
+ "Fault_Series" : ['fault' ],
780
+ "Strat_Series1" : ['rock2' ],
781
+ "Strat_Series2" : ['rock1' ]
782
+ }
783
+ )
784
+
785
+ # Set structural relations
786
+ model .structural_frame .structural_groups [0 ].structural_relation = StackRelationType .FAULT
787
+ model .structural_frame .structural_groups [0 ].fault_relations = FaultsRelationSpecialCase .OFFSET_ALL
788
+ model .structural_frame .structural_groups [1 ].structural_relation = StackRelationType .ERODE
789
+ model .structural_frame .structural_groups [2 ].structural_relation = StackRelationType .ONLAP
790
+
791
+ # Set metadata
792
+ model .meta .creation_date = "2024-03-24"
793
+ model .meta .last_modification_date = "2024-03-24"
794
+
795
+ # Save the model
796
+ file_path = tmp_path / "combination_model.json"
797
+ JsonIO .save_model_to_json (model , str (file_path ))
798
+
799
+ # Load the model and verify
800
+ loaded_model = JsonIO .load_model_from_json (str (file_path ))
801
+
802
+ # Check structural setup
803
+ assert len (loaded_model .structural_frame .structural_groups ) == 3
804
+ assert loaded_model .structural_frame .structural_groups [0 ].structural_relation == StackRelationType .FAULT
805
+ assert loaded_model .structural_frame .structural_groups [1 ].structural_relation == StackRelationType .ERODE
806
+ assert loaded_model .structural_frame .structural_groups [2 ].structural_relation == StackRelationType .ONLAP
807
+
808
+ # Check fault relations
809
+ np .testing .assert_array_equal (
810
+ loaded_model .structural_frame .fault_relations ,
811
+ np .array ([[0 , 1 , 1 ], [0 , 0 , 0 ], [0 , 0 , 0 ]])
812
+ )
813
+
814
+ # Check metadata
815
+ assert loaded_model .meta .creation_date == "2024-03-24"
816
+ assert loaded_model .meta .last_modification_date == "2024-03-24"
0 commit comments