This is a simple script that demonstrates how to open netcdf files (a typical format of file used for storing large amounts of data, and often used to display output from 3D Earth system models). This example uses a version of the marine reservoir ages output from Butzin et al. 2017.


In [13]:
# load required packages
library(ncdf4)
library(maps)

In [14]:
#Open netcdf file 
nc <- nc_open( "mra14_intcal13_pd_21kcalBP.nc")

In [15]:
#list names of variables in netcdf file
names(nc$var)


'MRA'

In [16]:
#list names of dimensions in netcdf file
names(nc$dim)


  1. 'lon'
  2. 'lat'
  3. 'depth'
  4. 'time'

Lets say that you want to extract the marine reservoir ages at a specific location for which you have the longitude, latitude and depth (e.g. -55oN, -70oE, 3000m). The following is the code for how to extract such data.


In [17]:
#Lets have a look at the matrix containing the variable of interest. In this case marine reservoir ages ("MRA)
nc_var <- ncvar_get( nc, varid="MRA" )
#list how many dimensions the matrix has
dim(nc_var)


  1. 144
  2. 72
  3. 22

In [19]:
#Note how this compares to the number of entries in each dimension
length(nc$dim$lon$vals)
length(nc$dim$lat$vals)
length(nc$dim$depth$vals)


144
72
22

In [41]:
#The matrix containing our variable is made up of the following [lon,lat,depth]
#Lets try to extract the data for our core site
#First define the variables
input_lat = -55.1
input_lon = -70
input_depth = 1250

#Now find the location in the matrix that corresponds to our data. 
#It is likely that your core is not at the exact location as each data point in the cdf file, 
#so you will have to find the nearest grid point
#Find correct colours for Interpolated_masterfile
nc_lat<-nc$dim$lat$vals
nc_lon<-nc$dim$lon$vals
nc_depth<-nc$dim$depth$vals

#This is written in a loop to make it easier when you have more than one site
index_vals=NULL
for(i in 1:length(input_lat)){
    lat_index<-which(abs(nc_lat-input_lat[i])==min(abs(nc_lat-input_lat[i])))
    #longitudes may need correcting from -180 to 180 ---> 0 to 360
    input_lon2<-ifelse(input_lon[i]< min(nc$dim$lon$vals), input_lon[i]+360, input_lon[i])
    lon_index<-which(abs(nc_lon-input_lon2)==min(abs(nc_lon-input_lon2)))
    depth_index<-which(abs(nc_depth-input_depth[i])==min(abs(nc_depth-input_depth[i])))
    a<-data.frame(lat_index=lat_index,lon_index=lon_index,depth_index=depth_index)
    index_vals<-rbind(index_vals,a)
}
index_vals
#Now use these index values to find the RMA at the core site by using the variable matrix
MRA_output=NULL
for(i in 1:nrow(index_vals)){
    MRA<-nc_var[index_vals$lon_index[i],index_vals$lat_index[i],index_vals$depth_index[i]]
    MRA_output<-rbind(MRA_output,MRA)
}
MRA_output


lat_indexlon_indexdepth_index
59 11915
MRA1475.878

The same principle can be used to extract marine reservoir ages from multiple sites. You can import in an excel sheet containing all of your longitudes, latitudes and depths, and output the data as a csv file.


In [44]:
#This package lets you read in excel docs
require(gdata)
input_cores<- read.xls("All_chilean_margin_cores.xlsx", sheet=1, header=TRUE)
#See the top few lines of your excel file
head(input_cores)


CoresLat..oN.Long..oE.WD..m.RecoveryMax.age..based.on.MS.X
PS97/139 -52.44267-52.44267 640.0 4.54 30?
PS97/138 -52.61633-52.61633 839.8 2.71 20
PS97/137 -52.65950-52.659501027.6 8.50 25
PS97/024 -54.58800-54.588001278.0 1.60 -
PS97/023 -54.68100-54.681001597.8 1.83 -
PS97/026 -54.68067-54.680671604.3 6.08 30

In [96]:
#Define the input variables
input_lat = input_cores$Lat..oN.
input_lon = input_cores$Long..oE.
input_depth = input_cores$WD..m.

#Again apply the function to find the index locations of each site within the variable matrix
index_vals=data.frame(lat_index=numeric(0),lon_index=numeric(0),depth_index=numeric(0))
for(i in 1:length(input_lat)){
    lat_index<-which(abs(nc_lat-input_lat[i])==min(abs(nc_lat-input_lat[i])))
    #longitudes may need correcting from -180 to 180 ---> 0 to 360
    input_lon2<-ifelse(input_lon[i]< min(nc$dim$lon$vals), input_lon[i]+360, input_lon[i])
    lon_index<-which(abs(nc_lon-input_lon2)==min(abs(nc_lon-input_lon2)))
    depth_index<-which(abs(nc_depth-input_depth[i])==min(abs(nc_depth-input_depth[i])))
    a <- data.frame(lat_index=lat_index,lon_index=lon_index,depth_index=depth_index)
    index_vals<-rbind(index_vals,a)
}

#Now use these index values to find the RMA at the core site by using the variable matrix
MRA_output=NULL
for(i in 1:nrow(index_vals)){
    MRA<-nc_var[index_vals$lon_ind[i],index_vals$lat_ind[i],index_vals$depth_ind[i]]
    MRA_output<-rbind(MRA_output,MRA)
}

#Add the output to the original datafile
input_cores["MRA"]<- MRA_output

#Display datafile
input_cores

#Output as csv file
write.csv(input_cores,"input_cores_with MRA.csv")


CoresLat..oN.Long..oE.WD..m.RecoveryMax.age..based.on.MS.XMRA
PS97/139 -52.44267 -52.44267 640.0 4.54 30? 1062.611
PS97/138 -52.61633 -52.61633 839.8 2.71 20 1178.181
PS97/137 -52.65950 -52.65950 1027.6 8.50 25 1310.342
PS97/024 -54.58800 -54.58800 1278.0 1.60 - 1384.752
PS97/023 -54.68100 -54.68100 1597.8 1.83 - 1472.770
PS97/026 -54.68067 -54.68067 1604.3 6.08 30 1472.770
PS97/022 -54.70050 -54.70050 1615.9 2.67 - 1472.770
PS97/025 -54.70050 -54.70050 1620.4 5.43 25 1472.770
PS97/129 -53.32150 -53.32150 1870.2 7.32 25 1522.970
PS97/128 -53.63433 -53.63433 2313.4 10.69 20 1526.670
PS97/027 -54.38483 -54.38483 2341.8 2.01 <20 1563.332
PS97/111 -54.38467 -54.38467 2364.0 9.93 18 missing Holocene?1563.332
PS97/122 -54.09683 -54.09683 2557.9 10.77 ? 1555.605
PS97/112 -54.57900 -54.57900 3866.9 14.58 - NA
PS97/114 -54.57883 -54.57883 3869.3 22.37 - NA