Skip to content

Commit ece9988

Browse files
committed
add basic tutorial
1 parent 85101fb commit ece9988

File tree

7 files changed

+460
-0
lines changed

7 files changed

+460
-0
lines changed
160 KB
Loading
295 KB
Loading
221 KB
Loading
214 KB
Loading
240 KB
Loading

docs/src/man/Tutorial_Basic.md

Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
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 ths 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 donwloaded 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+
![Basic_Tutorial_1](../assets/img/Basic_Tutorial_1.png)
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+
![Basic_Tutorial_2](../assets/img/Basic_Tutorial_2.png)
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+
![Basic_Tutorial_3](../assets/img/Basic_Tutorial_3.png)
202+
In creating this image, I used the `Clip` tool of Paraview to only show topography above sealevel and made it 50% transparant.
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+
![Basic_Tutorial_4](../assets/img/Basic_Tutorial_4.png)
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+
![Basic_Tutorial_5](../assets/img/Basic_Tutorial_5.png)
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

Comments
 (0)