|
| 1 | +import numpy as np |
| 2 | +from sklearn.linear_model import LinearRegression |
| 3 | + |
| 4 | +def calculate_scale_shift(a: np.ndarray, b: np.ndarray) -> tuple: |
| 5 | + # Reshape arrays for sklearn |
| 6 | + a_reshaped = a.reshape(-1, 1) |
| 7 | + b_reshaped = b.reshape(-1, 1) |
| 8 | + |
| 9 | + # Linear regression |
| 10 | + model = LinearRegression().fit(a_reshaped, b_reshaped) |
| 11 | + |
| 12 | + # Get scale and shift |
| 13 | + s = model.coef_[0][0] |
| 14 | + c = model.intercept_[0] |
| 15 | + |
| 16 | + return s, c |
| 17 | + |
| 18 | + |
| 19 | +def gaussian_kernel(locations, length_scale, variance): |
| 20 | + import torch |
| 21 | + # Compute the squared Euclidean distance between each pair of points |
| 22 | + locations = torch.tensor(locations.values) |
| 23 | + distance_squared = torch.cdist(locations, locations, p=2).pow(2) |
| 24 | + # Compute the covariance matrix using the Gaussian kernel |
| 25 | + covariance_matrix = variance * torch.exp(-0.5 * distance_squared / length_scale**2) |
| 26 | + return covariance_matrix |
| 27 | + |
| 28 | + |
| 29 | +import numpy as np |
| 30 | + |
| 31 | +import gempy as gp |
| 32 | +import xarray as xr |
| 33 | +from vector_geology.model_building_functions import optimize_nuggets_for_group |
| 34 | + |
| 35 | + |
| 36 | +def initialize_geo_model(structural_elements: list[gp.data.StructuralElement], extent: list[float], |
| 37 | + topography: xr.Dataset, load_nuggets: bool = False |
| 38 | + ) -> gp.data.GeoModel: |
| 39 | + structural_group_red = gp.data.StructuralGroup( |
| 40 | + name="Red", |
| 41 | + elements=[structural_elements[i] for i in [0, 4, 8]], |
| 42 | + structural_relation=gp.data.StackRelationType.ERODE |
| 43 | + ) |
| 44 | + |
| 45 | + # Any, Probably we can decimize this an extra notch |
| 46 | + structural_group_green = gp.data.StructuralGroup( |
| 47 | + name="Green", |
| 48 | + elements=[structural_elements[i] for i in [5]], |
| 49 | + structural_relation=gp.data.StackRelationType.ERODE |
| 50 | + ) |
| 51 | + |
| 52 | + # Blue range 2 cov 4 |
| 53 | + structural_group_blue = gp.data.StructuralGroup( |
| 54 | + name="Blue", |
| 55 | + elements=[structural_elements[i] for i in [2, 3]], |
| 56 | + structural_relation=gp.data.StackRelationType.ERODE |
| 57 | + ) |
| 58 | + |
| 59 | + structural_group_intrusion = gp.data.StructuralGroup( |
| 60 | + name="Intrusion", |
| 61 | + elements=[structural_elements[i] for i in [1]], |
| 62 | + structural_relation=gp.data.StackRelationType.ERODE |
| 63 | + ) |
| 64 | + |
| 65 | + structural_groups = [structural_group_intrusion, structural_group_green, structural_group_blue, structural_group_red] |
| 66 | + structural_frame = gp.data.StructuralFrame( |
| 67 | + structural_groups=structural_groups[2:], |
| 68 | + color_gen=gp.data.ColorsGenerator() |
| 69 | + ) |
| 70 | + # TODO: If elements do not have color maybe loop them on structural frame constructor? |
| 71 | + |
| 72 | + geo_model: gp.data.GeoModel = gp.create_geomodel( |
| 73 | + project_name='Tutorial_ch1_1_Basics', |
| 74 | + extent=extent, |
| 75 | + resolution=[20, 10, 20], |
| 76 | + refinement=5, # * Here we define the number of octree levels. If octree levels are defined, the resolution is ignored. |
| 77 | + structural_frame=structural_frame |
| 78 | + ) |
| 79 | + |
| 80 | + if topography is not None: |
| 81 | + gp.set_topography_from_arrays( |
| 82 | + grid=geo_model.grid, |
| 83 | + xyz_vertices=topography.vertex.values |
| 84 | + ) |
| 85 | + |
| 86 | + if load_nuggets: |
| 87 | + import os |
| 88 | + |
| 89 | + project_root = os.getcwd() |
| 90 | + path_to_temp = os.path.join(project_root, "../temp") |
| 91 | + apply_optimized_nuggets( |
| 92 | + geo_model=geo_model, |
| 93 | + loaded_nuggets_red=(np.load(path_to_temp + "/nuggets_Red.npy")), |
| 94 | + loaded_nuggets_blue=(np.load(path_to_temp + "/nuggets_Blue.npy")), |
| 95 | + loaded_nuggets_green=(np.load(path_to_temp + "/nuggets_Green.npy")) |
| 96 | + ) |
| 97 | + |
| 98 | + geo_model.structural_frame.get_element_by_name("KKR").color = "#A46283" |
| 99 | + geo_model.structural_frame.get_element_by_name("LGR").color = "#6394A4" |
| 100 | + geo_model.structural_frame.get_element_by_name("WAL").color = "#72A473" |
| 101 | + geo_model.structural_frame.get_element_by_name("ABL").color = "#1D3943" |
| 102 | + geo_model.structural_frame.basement_color = "#8B4220" |
| 103 | + |
| 104 | + geo_model.update_transform() |
| 105 | + |
| 106 | + return geo_model |
| 107 | + |
| 108 | + |
| 109 | +def optimize_nuggets_for_whole_project(geo_model: gp.data.GeoModel): |
| 110 | + geo_model.interpolation_options.kernel_options.range = 0.7 |
| 111 | + geo_model.interpolation_options.kernel_options.c_o = 4 |
| 112 | + optimize_nuggets_for_group( |
| 113 | + geo_model=geo_model, |
| 114 | + structural_group=geo_model.structural_frame.get_group_by_name('Red'), |
| 115 | + plot_evaluation=False, |
| 116 | + plot_result=True |
| 117 | + ) |
| 118 | + geo_model.interpolation_options.kernel_options.range = 2 |
| 119 | + geo_model.interpolation_options.kernel_options.c_o = 4 |
| 120 | + optimize_nuggets_for_group( |
| 121 | + geo_model=geo_model, |
| 122 | + structural_group=geo_model.structural_frame.get_group_by_name('Blue'), |
| 123 | + plot_evaluation=False, |
| 124 | + plot_result=False |
| 125 | + ) |
| 126 | + if False: |
| 127 | + optimize_nuggets_for_group( |
| 128 | + geo_model=geo_model, |
| 129 | + structural_group=geo_model.structural_frame.get_group_by_name('Green'), |
| 130 | + plot_evaluation=False, |
| 131 | + plot_result=True |
| 132 | + ) |
| 133 | + |
| 134 | + |
| 135 | +def apply_optimized_nuggets(geo_model: gp.data.GeoModel, loaded_nuggets_red, loaded_nuggets_blue, loaded_nuggets_green): |
| 136 | + gp.modify_surface_points( |
| 137 | + geo_model, |
| 138 | + slice=None, |
| 139 | + elements_names=[element.name for element in geo_model.structural_frame.get_group_by_name('Red').elements], |
| 140 | + nugget=loaded_nuggets_red |
| 141 | + ) |
| 142 | + if True: # Ignore OB |
| 143 | + gp.modify_surface_points( |
| 144 | + geo_model, |
| 145 | + slice=None, |
| 146 | + elements_names=[element.name for element in geo_model.structural_frame.get_group_by_name('Blue').elements], |
| 147 | + nugget=loaded_nuggets_blue |
| 148 | + ) |
| 149 | + if False: |
| 150 | + gp.modify_surface_points( |
| 151 | + geo_model, |
| 152 | + slice=None, |
| 153 | + elements_names=[element.name for element in geo_model.structural_frame.get_group_by_name('Green').elements], |
| 154 | + nugget=loaded_nuggets_green |
| 155 | + ) |
| 156 | + |
| 157 | + |
| 158 | +def setup_geophysics(env_path: str, geo_model: gp.data.GeoModel): |
| 159 | + import pandas as pd |
| 160 | + from dotenv import dotenv_values |
| 161 | + config = dotenv_values() |
| 162 | + |
| 163 | + df = pd.read_csv( |
| 164 | + filepath_or_buffer=config.get(env_path), |
| 165 | + sep=',', |
| 166 | + header=0 |
| 167 | + ) |
| 168 | + |
| 169 | + # Remove the items that have X > 5650000 |
| 170 | + df = df[df['X'] < 565000] |
| 171 | + |
| 172 | + interesting_columns = df[['X', 'Y', 'Bouguer_267_complete']] |
| 173 | + # %% |
| 174 | + device_location = interesting_columns[['X', 'Y']] |
| 175 | + # stack 0 to the z axis |
| 176 | + device_location['Z'] = 0 |
| 177 | + |
| 178 | + gp.set_centered_grid( |
| 179 | + grid=geo_model.grid, |
| 180 | + centers=device_location, |
| 181 | + resolution=np.array([10, 10, 15]), |
| 182 | + radius=np.array([5000, 5000, 5000]) |
| 183 | + ) |
| 184 | + |
| 185 | + gravity_gradient = gp.calculate_gravity_gradient(geo_model.grid.centered_grid) |
| 186 | + |
| 187 | + # %% |
| 188 | + from gempy_engine.core.backend_tensor import BackendTensor |
| 189 | + geo_model.geophysics_input = gp.data.GeophysicsInput( |
| 190 | + tz=BackendTensor.t.array(gravity_gradient), |
| 191 | + densities=BackendTensor.t.array([2.61, 2.92, 3.1, 2.92, 2.61, 2.61]), |
| 192 | + ) |
| 193 | + |
| 194 | + return interesting_columns |
0 commit comments