|
| 1 | +```@meta |
| 2 | +EditURL = "../../../tutorials/Tutorial_Basic.jl" |
| 3 | +``` |
| 4 | + |
| 5 | +# Getting started |
| 6 | +### Aim: |
| 7 | +The aim of this tutorial is to give you a feeling for the `GeophysicalModelGenerator` package. |
| 8 | + |
| 9 | +### 1. Loading data |
| 10 | +We start with loading the package, and assume that you have installed it: |
| 11 | + |
| 12 | +```julia |
| 13 | +using GeophysicalModelGenerator; |
| 14 | +``` |
| 15 | + |
| 16 | +Lets load a first 3D seismic tomography data set of the Alps. We uploaded an example file on Zenodo [here](https://zenodo.org/records/10738510), which comes from the paper of [Paffrath et al. 2021](https://se.copernicus.org/articles/12/2671/2021/se-12-2671-2021.html). |
| 17 | +We can load this in `GMG` with: |
| 18 | + |
| 19 | +```julia |
| 20 | +Tomo_Alps_full = load_GMG("https://zenodo.org/records/10738510/files/Paffrath_2021_SE_Pwave.jld2?download=1") |
| 21 | +``` |
| 22 | + |
| 23 | +```` |
| 24 | +GeoData |
| 25 | + size : (162, 130, 42) |
| 26 | + lon ϵ [ -13.3019 : 35.3019] |
| 27 | + lat ϵ [ 30.7638 : 61.2362] |
| 28 | + depth ϵ [ -606.0385 : 31.0385] |
| 29 | + fields : (:dVp_Percentage,) |
| 30 | +
|
| 31 | +```` |
| 32 | + |
| 33 | +This is a so-called `GeoData` object, which is a 3D grid of seismic velocities as a function of longitude, latitude and depth, which can include various fields (here we only have a single field: `:dVp_Percentage`) |
| 34 | +We can save this in `VTK` format, which is a widely used format that can for exampke be read by the 3D open-source visualization tool [Paraview](https://www.paraview.org/): |
| 35 | + |
| 36 | +```julia |
| 37 | +Write_Paraview(Tomo_Alps_full,"Tomo_Alps_full") |
| 38 | +``` |
| 39 | + |
| 40 | +```` |
| 41 | +Saved file: Tomo_Alps_full.vts |
| 42 | +
|
| 43 | +```` |
| 44 | + |
| 45 | +We also uploaded a dataset with the topography of the Alpine region which can be downloaded with: |
| 46 | + |
| 47 | +```julia |
| 48 | +Topo_Alps = load_GMG("https://zenodo.org/records/10738510/files/AlpsTopo.jld2?download=1") |
| 49 | +``` |
| 50 | + |
| 51 | +```` |
| 52 | +GeoData |
| 53 | + size : (961, 841, 1) |
| 54 | + lon ϵ [ 4.0 : 20.0] |
| 55 | + lat ϵ [ 36.0 : 50.0] |
| 56 | + depth ϵ [ -4.181 : 4.377] |
| 57 | + fields : (:Topography,) |
| 58 | +
|
| 59 | +```` |
| 60 | + |
| 61 | +Different than the 3D tomographic model, the topography has size 1 for the last index which indicates that this is a 3D surface. As you can see, the depth varies, which is because it is a warped surface. |
| 62 | +We can write this to disk as well |
| 63 | + |
| 64 | +```julia |
| 65 | +Write_Paraview(Topo_Alps,"Topo_Alps") |
| 66 | +``` |
| 67 | + |
| 68 | +```` |
| 69 | +Saved file: Topo_Alps.vts |
| 70 | +
|
| 71 | +```` |
| 72 | + |
| 73 | +If we open both datasets in Paraview, we see this (after giving some color to the topography): |
| 74 | + |
| 75 | +Note that I use the `Oleron` scientific colormap for the tomography which you can download [here](https://www.fabiocrameri.ch/colourmaps/) |
| 76 | + |
| 77 | +### 2. Extract subset of data |
| 78 | +As you can see the tomographic data covers a much larger area than the Alps itself, and in most of that area there is no data. |
| 79 | +It is thus advantageous to cut out a piece of the dataset that we are interested in which can be done with `ExtractSubVolume`: |
| 80 | + |
| 81 | +```julia |
| 82 | +Tomo_Alps = ExtractSubvolume(Tomo_Alps_full,Lon_level=(4,20),Lat_level=(36,50), Depth_level=(-600,-10)) |
| 83 | + |
| 84 | +Write_Paraview(Tomo_Alps,"Tomo_Alps"); |
| 85 | +``` |
| 86 | + |
| 87 | +```` |
| 88 | +Saved file: Tomo_Alps.vts |
| 89 | +
|
| 90 | +```` |
| 91 | + |
| 92 | +Which looks like: |
| 93 | + |
| 94 | + |
| 95 | +### 3. Create cross sections |
| 96 | +Paraview has the option to `Slice` through the data but it is not very intuitive to do this in 3D. Another limitation of Paraview is that it does not have native support for spherical coordinates, and therefore the data is translated to cartesian (`x`,`y`,`z`) coordinates (with the center of the Earth at `(0,0,0)`). |
| 97 | +That makes this a bit cumbersome to make a cross-section at a particular location. |
| 98 | +If you are interested in this you can use the `CrossSection` function: |
| 99 | + |
| 100 | +```julia |
| 101 | +data_200km = CrossSection(Tomo_Alps, Depth_level=-200) |
| 102 | +``` |
| 103 | + |
| 104 | +```` |
| 105 | +GeoData |
| 106 | + size : (54, 60, 1) |
| 107 | + lon ϵ [ 3.9057 : 19.9057] |
| 108 | + lat ϵ [ 35.9606 : 49.8976] |
| 109 | + depth ϵ [ -202.0385 : -202.0385] |
| 110 | + fields : (:dVp_Percentage, :FlatCrossSection) |
| 111 | +
|
| 112 | +```` |
| 113 | + |
| 114 | +As you see, this is not exactly at 200 km depth, but at the closest `z`-level in the data sets. If you want to be exactly at 200 km, use the `Interpolate` option: |
| 115 | + |
| 116 | +```julia |
| 117 | +data_200km_exact = CrossSection(Tomo_Alps, Depth_level=-200, Interpolate=true) |
| 118 | +``` |
| 119 | + |
| 120 | +```` |
| 121 | +GeoData |
| 122 | + size : (100, 100, 1) |
| 123 | + lon ϵ [ 3.9057 : 19.9057] |
| 124 | + lat ϵ [ 35.9606 : 49.8976] |
| 125 | + depth ϵ [ -200.0 : -200.0] |
| 126 | + fields : (:dVp_Percentage, :FlatCrossSection) |
| 127 | +
|
| 128 | +```` |
| 129 | + |
| 130 | +In general, you can get help info for all functions with `?`: |
| 131 | +```julia |
| 132 | +help?> CrossSection |
| 133 | +search: CrossSection CrossSectionVolume CrossSectionPoints CrossSectionSurface FlattenCrossSection |
| 134 | + |
| 135 | + CrossSection(DataSet::AbstractGeneralGrid; dims=(100,100), Interpolate=false, Depth_level=nothing, Lat_level=nothing, Lon_level=nothing, Start=nothing, End=nothing, Depth_extent=nothing, section_width=50km) |
| 136 | + |
| 137 | + Creates a cross-section through a GeoData object. |
| 138 | + |
| 139 | + • Cross-sections can be horizontal (map view at a given depth), if Depth_level is specified |
| 140 | + |
| 141 | + • They can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points. |
| 142 | + |
| 143 | + • Depending on the type of input data (volume, surface or point data), cross sections will be created in a different manner: |
| 144 | + |
| 145 | + 1. Volume data: data will be interpolated or directly extracted from the data set. |
| 146 | + |
| 147 | + 2. Surface data: surface data will be interpolated or directly extracted from the data set |
| 148 | + |
| 149 | + 3. Point data: data will be projected to the chosen profile. Only data within a chosen distance (default is 50 km) will be used |
| 150 | + |
| 151 | + • Interpolate indicates whether we want to simply extract the data from the data set (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims NOTE: THIS ONLY APPLIES TO VOLUMETRIC AND SURFACE DATA |
| 152 | + SETS |
| 153 | + |
| 154 | + • 'section_width' indicates the maximal distance within which point data will be projected to the profile |
| 155 | + |
| 156 | + Example: |
| 157 | + ≡≡≡≡≡≡≡≡ |
| 158 | + |
| 159 | + julia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km); |
| 160 | + julia> Data = Depth*2; # some data |
| 161 | + julia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5); |
| 162 | + julia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz))); |
| 163 | + julia> Data_cross = CrossSection(Data_set3D, Depth_level=-100km) |
| 164 | + GeoData |
| 165 | + size : (11, 11, 1) |
| 166 | + lon ϵ [ 10.0 : 20.0] |
| 167 | + lat ϵ [ 30.0 : 40.0] |
| 168 | + depth ϵ [ -100.0 km : -100.0 km] |
| 169 | + fields: (:Depthdata, :LonData, :Velocity) |
| 170 | +``` |
| 171 | + |
| 172 | +Let's use this to make a vertical cross-section as well: |
| 173 | + |
| 174 | +```julia |
| 175 | +Cross_vert = CrossSection(Tomo_Alps, Start=(5,47), End=(15,44)) |
| 176 | +``` |
| 177 | + |
| 178 | +```` |
| 179 | +GeoData |
| 180 | + size : (100, 100, 1) |
| 181 | + lon ϵ [ 5.0 : 15.0] |
| 182 | + lat ϵ [ 47.0 : 44.0] |
| 183 | + depth ϵ [ -606.0385 : -15.5769] |
| 184 | + fields : (:dVp_Percentage, :FlatCrossSection) |
| 185 | +
|
| 186 | +```` |
| 187 | + |
| 188 | +And write them to paraview: |
| 189 | + |
| 190 | +```julia |
| 191 | +Write_Paraview(Cross_vert,"Cross_vert"); |
| 192 | +Write_Paraview(data_200km,"data_200km"); |
| 193 | +``` |
| 194 | + |
| 195 | +```` |
| 196 | +Saved file: Cross_vert.vts |
| 197 | +Saved file: data_200km.vts |
| 198 | +
|
| 199 | +```` |
| 200 | + |
| 201 | + |
| 202 | +In creating this image, I used the `Clip` tool of Paraview to only show topography above sealevel and made it 50% transparent. |
| 203 | + |
| 204 | +### 4. Cartesian data |
| 205 | +As you can see, the curvature or the Earth is taken into account here. Yet, for many applications it is more convenient to work in Cartesian coordinates (kilometers) rather then in geographic coordinates. |
| 206 | +`GeophysicalModelGenerator` has a number of tools for this. |
| 207 | +First we need do define a `ProjectionPoint` around which we project the data |
| 208 | + |
| 209 | +```julia |
| 210 | +proj = ProjectionPoint(Lon=12.0,Lat =43) |
| 211 | + |
| 212 | +Topo_cart = Convert2CartData(Topo_Alps, proj) |
| 213 | +``` |
| 214 | + |
| 215 | +```` |
| 216 | +CartData |
| 217 | + size : (961, 841, 1) |
| 218 | + x ϵ [ -748.7493528015041 : 695.3491277129204] |
| 219 | + y ϵ [ -781.2344794653393 : 831.6826244089501] |
| 220 | + z ϵ [ -4.181 : 4.377] |
| 221 | + fields : (:Topography,) |
| 222 | +
|
| 223 | +```` |
| 224 | + |
| 225 | +And do the same with the tomography: |
| 226 | + |
| 227 | +```julia |
| 228 | +Tomo_cart = Convert2CartData(Tomo_Alps, proj) |
| 229 | +``` |
| 230 | + |
| 231 | +```` |
| 232 | +CartData |
| 233 | + size : (54, 60, 39) |
| 234 | + x ϵ [ -757.8031278236692 : 687.0608438357591] |
| 235 | + y ϵ [ -785.601866956207 : 821.3433749818317] |
| 236 | + z ϵ [ -606.0385 : -15.5769] |
| 237 | + fields : (:dVp_Percentage,) |
| 238 | +
|
| 239 | +```` |
| 240 | + |
| 241 | +Save: |
| 242 | + |
| 243 | +```julia |
| 244 | +Write_Paraview(Tomo_cart,"Tomo_cart"); |
| 245 | +Write_Paraview(Topo_cart,"Topo_cart"); |
| 246 | +``` |
| 247 | + |
| 248 | +```` |
| 249 | +Saved file: Tomo_cart.vts |
| 250 | +Saved file: Topo_cart.vts |
| 251 | +
|
| 252 | +```` |
| 253 | + |
| 254 | + |
| 255 | +As the coordinates are now aligned with the `x`,`y`,`z` coordinate axes in Paraview it is now straightforward to use the build-in tools to explore the data. |
| 256 | + |
| 257 | +### 5. Rectilinear data |
| 258 | +Yet, because of the curvature of the Earth, the resulting 3D model is not strictly rectilinear, which is often a requiment for cartesian numerical models. |
| 259 | +This can be achieved in a relatively straightforward manner, by creating a new 3D dataset that is slightly within the curved boundaries of the projected data set: |
| 260 | + |
| 261 | +```julia |
| 262 | +Tomo_rect = CartData(XYZGrid(-550.0:10:600, -500.0:10:700, -600.0:5:-17)); |
| 263 | +``` |
| 264 | + |
| 265 | +the routine `ProjectCartData` will then project the data from the geographic coordinates to the new rectilinear grid: |
| 266 | + |
| 267 | +```julia |
| 268 | +Tomo_rect = ProjectCartData(Tomo_rect, Tomo_Alps, proj) |
| 269 | +``` |
| 270 | + |
| 271 | +```` |
| 272 | +CartData |
| 273 | + size : (116, 121, 117) |
| 274 | + x ϵ [ -550.0 : 600.0] |
| 275 | + y ϵ [ -500.0 : 700.0] |
| 276 | + z ϵ [ -600.0 : -20.0] |
| 277 | + fields : (:dVp_Percentage,) |
| 278 | +
|
| 279 | +```` |
| 280 | + |
| 281 | +we can do the same with topography: |
| 282 | + |
| 283 | +```julia |
| 284 | +Topo_rect = CartData(XYZGrid(-550.0:1:600, -500.0:1:700, 0)) |
| 285 | +Topo_rect = ProjectCartData(Topo_rect, Topo_Alps, proj) |
| 286 | +``` |
| 287 | + |
| 288 | +```` |
| 289 | +CartData |
| 290 | + size : (1151, 1201, 1) |
| 291 | + x ϵ [ -550.0 : 600.0] |
| 292 | + y ϵ [ -500.0 : 700.0] |
| 293 | + z ϵ [ -3.6366708734115245 : 4.2399313641768455] |
| 294 | + fields : (:Topography,) |
| 295 | +
|
| 296 | +```` |
| 297 | + |
| 298 | +Save it: |
| 299 | + |
| 300 | +```julia |
| 301 | +Write_Paraview(Tomo_rect,"Tomo_rect"); |
| 302 | +Write_Paraview(Topo_rect,"Topo_rect"); |
| 303 | +``` |
| 304 | + |
| 305 | +```` |
| 306 | +Saved file: Tomo_rect.vts |
| 307 | +Saved file: Topo_rect.vts |
| 308 | +
|
| 309 | +```` |
| 310 | + |
| 311 | + |
| 312 | + |
| 313 | +At this stage, the data can directly be used to generate cartesian numerical model setups, as explained in the other tutorials. |
| 314 | + |
| 315 | +--- |
| 316 | + |
| 317 | +*This page was generated using [Literate.jl](https://github.com/fredrikekre/Literate.jl).* |
| 318 | + |
0 commit comments