# Gravity disturbances#

One of the main uses of Boule in geophysics is the calculation of gravity disturbances. Our closed-form implementation of normal gravity allows accurate gravity disturbance calculation at any height without the errors associated with approximate free-air corrections.

As an example, lets calculate a gravity disturbance grid for the Earth using a global gravity from the EIGEN-6C4 spherical harmonic model at a height of 10 km.

First off, we import the required packages to do this:

```import boule as bl
import ensaio
import pygmt         # For plotting nice maps
```

Next, we can download and cache the gravity grid using `ensaio` and load it with `xarray`:

```fname = ensaio.fetch_earth_gravity(version=1)
observed_gravity
```
```<xarray.DataArray 'gravity' (latitude: 1081, longitude: 2161)>
array([[980106.5 , 980106.5 , 980106.5 , ..., 980106.5 , 980106.5 ,
980106.5 ],
[980108.25, 980108.25, 980108.25, ..., 980108.25, 980108.25,
980108.25],
[980108.8 , 980108.8 , 980108.8 , ..., 980108.75, 980108.75,
980108.8 ],
...,
[980153.8 , 980153.75, 980153.6 , ..., 980153.94, 980153.8 ,
980153.8 ],
[980160.44, 980160.44, 980160.44, ..., 980160.44, 980160.44,
980160.44],
[980157.5 , 980157.5 , 980157.5 , ..., 980157.5 , 980157.5 ,
980157.5 ]], dtype=float32)
Coordinates:
* longitude  (longitude) float64 -180.0 -179.8 -179.7 ... 179.7 179.8 180.0
* latitude   (latitude) float64 -90.0 -89.83 -89.67 -89.5 ... 89.67 89.83 90.0
height     (latitude, longitude) float32 1e+04 1e+04 1e+04 ... 1e+04 1e+04
Attributes:
Conventions:     CF-1.8
title:           Gravity acceleration (EIGEN-6C4) at a constant geometric...
crs:             WGS84
source:          Generated from the EIGEN-6C4 model by the ICGEM Calculat...
references:      https://doi.org/10.5880/icgem.2015.1
long_name:       gravity acceleration
description:     magnitude of the gravity acceleration vector (gravitatio...
units:           mGal
actual_range:    [974748.6 980201.9]

Let’s plot this data on a map using `pygmt` to see what it looks like:

```fig = pygmt.Figure()
fig.grdimage(
observed_gravity,
projection="W20c",
cmap="viridis",
)
fig.basemap(frame=["af", "WEsn"])
fig.colorbar(
position="JCB+w10c",
frame=["af", 'y+l"mGal"', 'x+l"observed gravity"'],
)
fig.coast(shorelines=True, resolution="c", area_thresh=1e4)
fig.show()
```

Now we can calculate the WGS84 normal gravity at the same points as the observed gravity using `boule.Ellipsoid.normal_gravity`:

```normal_gravity = bl.WGS84.normal_gravity(
observed_gravity.latitude, observed_gravity.height,
)
normal_gravity
```
```<xarray.DataArray (latitude: 1081, longitude: 2161)>
array([[980142.33509235, 980142.33509235, 980142.33509235, ...,
980142.33509235, 980142.33509235, 980142.33509235],
[980142.29097894, 980142.29097894, 980142.29097894, ...,
980142.29097894, 980142.29097894, 980142.29097894],
[980142.15864029, 980142.15864029, 980142.15864029, ...,
980142.15864029, 980142.15864029, 980142.15864029],
...,
[980142.15864035, 980142.15864035, 980142.15864035, ...,
980142.15864035, 980142.15864035, 980142.15864035],
[980142.29097894, 980142.29097894, 980142.29097894, ...,
980142.29097894, 980142.29097894, 980142.29097894],
[980142.33509235, 980142.33509235, 980142.33509235, ...,
980142.33509235, 980142.33509235, 980142.33509235]])
Coordinates:
* latitude   (latitude) float64 -90.0 -89.83 -89.67 -89.5 ... 89.67 89.83 90.0
* longitude  (longitude) float64 -180.0 -179.8 -179.7 ... 179.7 179.8 180.0
height     (latitude, longitude) float32 1e+04 1e+04 1e+04 ... 1e+04 1e+04```
```fig = pygmt.Figure()
fig.grdimage(
normal_gravity,
projection="W20c",
cmap="viridis",
)
fig.basemap(frame=["af", "WEsn"])
fig.colorbar(
position="JCB+w10c",
frame=["af", 'y+l"mGal"', 'x+l"normal gravity"'],
)
fig.coast(shorelines=True, resolution="c", area_thresh=1e4)
fig.show()
```

We can arrive at a grid of gravity disturbances by subtracting normal gravity from the data grid:

```disturbance = observed_gravity - normal_gravity
disturbance
```
```<xarray.DataArray (latitude: 1081, longitude: 2161)>
array([[-35.83509235, -35.83509235, -35.83509235, ..., -35.83509235,
-35.83509235, -35.83509235],
[-34.04097894, -34.04097894, -34.04097894, ..., -34.04097894,
-34.04097894, -34.04097894],
[-33.34614029, -33.34614029, -33.34614029, ..., -33.40864029,
-33.40864029, -33.34614029],
...,
[ 11.65385965,  11.59135965,  11.46635965, ...,  11.77885965,
11.65385965,  11.65385965],
[ 18.14652106,  18.14652106,  18.14652106, ...,  18.14652106,
18.14652106,  18.14652106],
[ 15.16490765,  15.16490765,  15.16490765, ...,  15.16490765,
15.16490765,  15.16490765]])
Coordinates:
* longitude  (longitude) float64 -180.0 -179.8 -179.7 ... 179.7 179.8 180.0
* latitude   (latitude) float64 -90.0 -89.83 -89.67 -89.5 ... 89.67 89.83 90.0
height     (latitude, longitude) float32 1e+04 1e+04 1e+04 ... 1e+04 1e+04```

Finally, we can display the disturbance in a nice global map:

```fig = pygmt.Figure()
fig.grdimage(
)
fig.basemap(frame=["af", "WEsn"])
fig.colorbar(
position="JCB+w10c",
frame=["af", 'y+l"mGal"', 'x+l"gravity disturbance"'],
)
fig.coast(shorelines=True, resolution="c", area_thresh=1e4)
fig.show()
```

Gravity disturbances can be interpreted geophysically as the gravitational effect of anomalous masses, i.e. those that are not present in the normal (ellipsoidal) Earth. The disturbance clearly highlights all of the major subduction zones and large oceanic island chains, all of which are not in local isostatic equilibrium.

Tip

We used the WGS84 ellipsoid here but the workflow is the same for any other ellipsoid. Checkout Available ellipsoids for options.