require(oce)
require(ncdf4)
##read.adp.easy
#'ADCP Processing step 2.0
#'
#'@family processing
#'
#'
#'Load adp data into R with list that includes all metadata from mooring sheets
#'#' returns an object of class adp (from oce package) uses
#'\code{\link[oce:read.adp]{read.adp}}
#'
#'@param file raw ADCP file (.000 format)
#'@param metadata csv metadata file from template
#'
#'@export
#'
read.adp.easy <- function(file, metadata){
if (missing(metadata)){
warning('no metadata supplied')
}
metad <- read.csv(metadata, header = TRUE)
mn <- as.character(metad[,1])
mv <- as.character(metad[,2])
md <- as.list(mv)
names(md) <- mn
adp <- read.adp(file, latitude = as.numeric(md[['latitude']]), longitude = as.numeric(md[['longitude']]) ) #insert lat and lon from mooring logs
if (!missing(md)) {
for (m in seq_along(md)) {
adp <- oceSetMetadata(adp, names(md)[m], md[[m]], note = NULL)
}
adp@metadata$source <- 'raw'
adp@metadata$latitude <- as.numeric(adp[['latitude']])
adp@metadata$longitude <- as.numeric(adp[['longitude']])
adp@processingLog <- processingLogAppend(adp@processingLog, 'metadata read in from log sheet')
return(adp)
}
}
##read metadata
#' ADCP process step 2.1
#'
#'@family processing
#' Read in all metadata from csv template to adp object, sourced from log sheets
#'
#' @param file csv file name
#' @param obj adp oce object to assign metadata to
#'
#'@export
#'
read.meta <- function(file, obj){
md <- read.csv(file, header = TRUE)
mn <- as.character(md[,1])
mv <- as.character(md[,2])
meta <- as.list(mv)
names(meta) <- mn
for (m in seq_along(meta)) {
obj <- oceSetMetadata(obj, names(meta)[m], meta[[m]], note = NULL)
}
return(obj)
}
###applyMAgneticDeclination
#' ADCP Processing step 3.2
#'
#'@family processing
#'
#' apply magnetic declination to ADCP data uses
#' \code{\link[oce:magneticField]{magneticField}} to calculate declination and
#' \code{\link[oce:enuToOther]{enuToOTher}} to apply variation to data set
#'
#' @param x adp object from oce-class
#' @param lat latitude
#' @param lon longitude
#' @param st start/ deployment time
#' @param et end/ recovery time
#' @param type average or interpolated
#'
#'
#'
#' @return adp object with magnetic declination applied given coordinates
#'
#' If type == average, an average is taken from start and end time
#' declinations and applied uniformly
#'
#' If type == interpolate, the rate of declination is used over time series
#'@export
#'
applyMagneticDeclinationAdp <- function(x, lat = x[['latitude']], lon = x[['longitude']], st = x[['time_coverage_start']], et = x[['time_coverage_end']],tz = 'UTC', type = 'average'){
if (!inherits(x, "adp")){
stop("method is only for objects of class '", "adp", "'")
}
if (is.na(lat) | is.na(lon)){
warning('No latitude or longitude values provided!')
}
if (is.null(st) | is.null(et)){
warning('deployment and recovery times not provided!')
}
if (type =='average'){
#ifs for different time formats? tz argument?
if (!is.na(lat) & !is.na(lon)){
if(!is.null(st) & !is.null(et)){
s <- as.POSIXct(st, tz = tz)
e <- as.POSIXct(et, tz = tz)
a <- magneticField(lon, lat, s)
b <- magneticField(lon, lat, e)
c <- round(mean(c(a$declination, b$declination)),digits = 2)
coord <- x@metadata$oceCoordinate
if (coord == 'enu'){
x <- enuToOther(x, heading = c)
x@metadata$magnetic_variation <- c
x@metadata$oceCoordinate <- 'enu'
}
if (coord != 'enu'){
warning('Function cannot handle objects in ', coord, 'Object returned as is ; please convert to enu first')
}
}
else {
warning('Missing required arguments! No processing performed!')
}
x@processingLog <- processingLogAppend(x@processingLog, value = paste0('magnetic variation, using average applied; declination =', c, 'degrees') )
}
if (type == 'interpolate'){
t <- x[['time']]
coord <- x@metadata$oceCoordinate
mf <- NULL
for (i in 1: length(t)){
mf[[i]] <- magneticField(lon, lat, t[[i]])
}
dec <- NULL
for( i in 1: length(mf)){
dec[[i]] <- mf[[i]]$declination
}
f <- approx(x = dec, y = t, method = 'linear')
if (coord != 'enu'){
warning('Function cannot handle objects in ', coord, 'Object returned as is ; please convert to enu first')
}
if(coord == 'enu'){
x <- enuToOther(x, heading = f$x)
x@metadata$magnetic_variation <- avg(f$x)
x@metadata$oceCoordinate <- 'enu'
x@processingLog <- processingLogAppend(x@processingLog, value = paste0('magnetic variation applied; using interpolation. Declination average =', avg(f$x), 'degrees') )
}
}
return(x)
}
}
#'ADCP Processing step 3.3 Limit depth by rmax
#'
#'@family processing
#'
#'Use maximum acceptable range values to determine acceptable depth values Uses
#'Teledyne RDI equation, Rmax = Dcos(x)
#'
#'@param x oce object of class adp to be limited
#'@param lat latitude of instrument during sampling
#'
#'
#'@export
#'
limit_depthbyrmax <- function(x, lat = x[['latitude']]){
if (!inherits(x, "adp")){
stop("method is only for objects of class '", "adp", "'")
}
d <- x[['depth']]
deg2rad <- function(deg) {(deg * pi) / (180)}
rmax <- d *(cos(deg2rad(x@metadata$beamAngle)))
if(!missing(lat)){
d <- swDepth(x@data$pressure, latitude = lat, eos = getOption("oceEOS", default = "gsw"))
d[d < rmax] <- NA
mdt <- round(mean(d), digits = 2)
x@metadata$sensor_depth <- mdt
x@metadata$depthMean <- mdt
x@data$depth <- d
}
if (missing(lat)){
if(!is.na(x@metadata$latitude)){
lat <- x@metadata$latitude
d <- swDepth(x@data$pressure, latitude = lat, eos = getOption("oceEOS", default = "gsw"))
d[d < rmax] <- NA
mdt <- round(mean(x@data$depth, na.rm = TRUE), digits = 2)
x@metadata$sensor_depth <- mdt
x@metadata$depthMean <- mdt
x@data$depth <- d
}
if (is.na(x@metadata$latitude)){
warning('No latitude provided; returning object as is')
stop()
}
adp@processingLog <- processingLogAppend(adp@processingLog, paste0('depth values adjusted to sea water depth using pressure and latitude'))
adp@processingLog <- processingLogAppend(adp@processingLog, paste0('depth limited by maximum acceptable distance, calulated with Rmax = Dcos(x)'))
adp@processingLog <- processingLogAppend(adp@processingLog, paste0('Sensor depth and mean depth set to ', mdt , ' based on trimmed depth values'))
return(x)
}
}
#'@title limit depth by time
#'
#'@family processing
#'
#'@description Uses deployment and recovery times to limit depth within times
#' that insturment was actively and properly sampliing
#'
#'@param adp oce object of class adp to be limited
#'
#' requires certain meta data features to compute including pressure, latitude,
#' time, time_coverage_start, time_coverage_end
#'
#'@export
#'
#'
limit_depthbytime <- function(adp, tz = 'UTC'){
if (!inherits(adp, "adp")){
stop("method is only for objects of class '", "adp", "'")
}
adp[['depth']] <- swDepth(adp[['pressure']], latitude = adp[['latitude']], eos = getOption("oceEOS", default = "gsw"))
depth <- adp[['depth']]
depth[as.POSIXct(adp[['time']], tz) < as.POSIXct(adp[['time_coverage_start']], tz) | as.POSIXct(adp[['time']], tz) > as.POSIXct(adp[['time_coverage_end']], tz)] <- NA
mdt <- round(mean(depth, na.rm = TRUE), digits = 2)
adp@metadata$sensor_depth <- mdt
adp@metadata$depthMean <- mdt
adp@data$depth <- depth
adp@processingLog <- processingLogAppend(adp@processingLog, paste0('depth limited by deployment (', adp[['time_coverage_start']], ') and recovery (', adp[['time_coverage_end']], ') times'))
adp@processingLog <- processingLogAppend(adp@processingLog, paste0('Sensor depth and mean depth set to ', mdt , ' based on trimmed depth values'))
return(adp)
}
#time cut off
#'
#'ADCP Processing step 3.4
#'
#'@family processing
#'
#'@description Function limits variable (time, salinity, pressure, temperature,
#' pitch, roll, heading) from before deployment and after recovery of ADCP
#'
#'@param x adp object from oce-class adp
#'@param tz time zone, default is 'UTC'
#'@param dt deployment time of ADCP, default pulls value from metadata (time_coverage_start)
#'@param rt recovery time of ADCP, default pulls value from metadata (time_coverage_end)
#'
#'@return adp object with velocities limited to active ADCP measurement times
#' (after deployment and before recovery)
#'
#'@export
#'
#'
limit_time <- function(x, tz = 'UTC', dt = x[['time_coverage_start']], rt = x[['time_coverage_end']]){
if (!inherits(x, "adp")){
stop("method is only for objects of class '", "adp", "'")
}
#FIX ME : if deployment or recovery time is out of bounds
if(!missing(dt)){
t1 <- as.POSIXct(dt, tz = tz)
t <- x[['time', "numeric"]]
t <- as.POSIXct(t, tz = tz)
x[['v']][t < t1] <- NA
x[['pressure']][t < t1] <- NA
x[['salinity']][t < t1] <- NA
x[['temperature']][t < t1] <- NA
x[['pitch']][t < t1] <- NA
x[['roll']][t < t1] <- NA
x[['heading']][t < t1] <- NA
}
else if(missing(dt)){
if (!is.null(x@metadata$time_coverage_start)){
dt <- x@metadata$time_coverage_start
t1 <- as.POSIXct(dt, tz = tz)
t <- x[['time', "numeric"]]
t <- as.POSIXct(t, tz = tz)
x[['v']][t < t1] <- NA
x[['pressure']][t < t1] <- NA
x[['salinity']][t < t1] <- NA
x[['temperature']][t < t1] <- NA
x[['pitch']][t < t1] <- NA
x[['roll']][t < t1] <- NA
x[['heading']][t < t1] <- NA
}
if (is.null(x@metadata$time_coverage_start)){
warning('No deployment Time provided!')
}
if(!missing(rt)){
t2 <- as.POSIXct(rt, tz = tz)
x[['v']][t > t2] <- NA
x[['pressure']][t > t2] <- NA
x[['salinity']][t > t2] <- NA
x[['temperature']][t > t2] <- NA
x[['pitch']][t > t2] <- NA
x[['roll']][t > t2] <- NA
x[['heading']][t > t2] <- NA
}
else if (missing(rt))
if (!is.null(x@metadata$time_coverage_end)){
t2 <- as.POSIXct(rt, tz = tz)
x[['v']][t > t2] <- NA
x[['pressure']][t > t2] <- NA
x[['salinity']][t > t2] <- NA
x[['temperature']][t > t2] <- NA
x[['pitch']][t > t2] <- NA
x[['roll']][t > t2] <- NA
x[['heading']][t > t2] <- NA
}
if (is.null(x@metadata$time_coverage_end)){
warning('No recovery time provided!')
}
adp@processingLog <- processingLogAppend(adp@processingLog, paste0('Data has been cut off before deployment at ', dt, ' and after recovery at ', rt))
return(x)
}
}
####create flag####
#' ADCP processing Step 3.5
#'
#'@family processing
#'
#' adpFlag function flag an adp object based on a series of parameters including
#' percent good, and error velocity.
#'
#' This function also defaults to flagging depth values based on the Teledyne
#' RDI standard
#'
#' Rmax = Dcosx where Rmax is the maximum acceptable distance range from the
#' ADCP, D is total depth and x is the beam angle of the ADCP.
#'
#' This function also flags data outside the deployment and recovery time
#' bounds.
#'
#' Sets any data not flagged by this processing to 'good' flag value
#'
#' This function uses \code{\link[oce:initializeFlags]{initializeFlags}} to
#' initialize blank flagging scheme for values to be inserted in Then
#' \code{\link[oce: setFlags]{setFlags}} to set flag values based on desired
#' scheme
#'
#' @param adp, an adp object, oce-class
#' @param flagScheme, scheme of flags that will be followed, BODC, MEDS, etc
#' @param pg, The minimum percent good for evaluating beams one + four of the
#' adcp (BIO standard is 25)
#' @param er, Maximum error velocity for evaluating adcp data (BIO standard is
#' 0.46)
#'
#'@export
#'
####adcp process function
adpFlag <- function(adp, pg = adp[['percentgd_threshold']], er= adp[['error_threshold']]){
require(oce)
if (!inherits(x = adp, "adp")){
stop("method is only for objects of class '", "adp", "'")
}
deg2rad <- function(deg) {(deg * pi) / (180)}
rmax <- adp[['depth']] *(cos(deg2rad(adp[['beamAngle']])))
#create matrix of maximum acceptable depth
r <- matrix(rmax, ncol=length(adp[['distance']]), nrow=length(rmax))
#create matrix of distance (adp to surface)
dist <- adp[['distance']]
t <- adp[['time']]
d <- t(matrix(dist, ncol = length(t), nrow = length(dist)))
#read in pg per beam
g <- adp[['g', "numeric"]]
#combine beam 1 and 4
lowpg <- g[,,1]+g[,,4]
#extract error velocities
ERRV <- adp[['v']][,,4]
#create logical array of flagged values based on low percent good, high error velocity or surface contamination
dim = dim(adp[['v']])
flag <- array(FALSE, dim= dim)
for (i in 1:3)
flag[,,i] <- (lowpg< pg) | (abs(ERRV) > er) | r < d | adp[['time']] < adp[['time_coverage_start']] | adp[['time']] > adp[['time_coverage_end']]
#initialize and set flag scheme
adp <- initializeFlags(adp, name = 'v', value = 0)
#set adp flags where logical array = TRUE, flagged based on error, percent good or Rmax, value = 4 (see flag scheme, BODC)
adp <- setFlags(adp, name = 'v', i= flag, value = 4)
good <- adp[['flags']][['v']] == 0
adp <- setFlags(adp, name = 'v', i = good, value = 1)
adp@processingLog <- processingLogAppend(adp@processingLog, 'Quality control flags set based on flag scheme L20 from BODC')
return(adp)
}
##creating standard format file names
#' @title File naming format
#'
#'@family general
#'
#' @description pulls metadata from an adp oce object and creates a file name in
#' standard BIO format
#'
#' @param adp an oce class - adp object
#'
#' required metadata : cruise number, mooring number, serial number, sampling
#' interval!! Make sure all metadata is present when experiencing problems
#'
#'@export
#'
name.file <- function(adp){
name <- paste('MADCPS', adp[['experiment']], adp[['event_number']], adp[['serialNumber']], adp[['sampling_interval']], sep = '_')
name
}
####odf2adp####
####odf missing bin#####
#' ADCP Processing ODF to NetCDF
#'
#' Reads in a set of odf files and compiles into adp object, is capable of
#' recognizing missing bins or missing odf files and inserting NA's in
#' appropriate slot of data varibales
#'
#'@family odf
#' @description Converting individual odf bins to Net cdf standard format
#' @param files list of odf files
#' @param metadata any extra metadata to be added to net cdf as list form
#' @export
#'
#'
odf2adp <- function(files, metadata) {
require(oce)
require(abind)
files <- if (is.list(files)) unlist(files) else files
nd <- length(files)
## read the first one to get length of time:
d <- read.odf(files[1])
nt <- length(d[['time']])
vars <- names(d@data)
vars <- vars[-which(vars == 'time')]
for (vr in vars) {
assign(vr, array(NA, dim=c(nt, nd)))
}
depth <- NULL
for (f in 1:length(files)) {
d <- read.odf(files[f])
t <- d[['time']]
depth[f] <- d[['depthMin']]
for (vr in vars) {
eval(parse(text=paste0(vr, "[, f] <- d[['", vr, "']]")))
}
}
## need to sort the depths because of file sorting ...
o <- order(depth, decreasing = TRUE)
depth <- depth[o]
for (vr in vars) {
eval(parse(text=paste0(vr, "<- ", vr, "[, o]")))
}
#pre 2000 ODFs do not include vertical or error velocity
# if(is.null(w)){
# r <- length(u[,1])
# c <- length(u[1,])
# w <- matrix(data = NA, nrow = r, ncol = c)
# }
distance <- max(depth) - depth
adp <- as.adp(t, distance, v=abind(u, v, w, error, along=3), a=a, q=unknown)
for (m in names(d@metadata)) {
if (m != 'units' & m != 'flags' & m != 'dataNamesOriginal') {
adp <- oceSetMetadata(adp, m, d[[m]], note = NULL)
}
}
## depthMinMax
adp <- oceSetMetadata(adp, 'depthMin', min(depth))
adp <- oceSetMetadata(adp, 'depthMax', max(depth))
## add in any extra supplied metadata items
if (!missing(metadata)) {
for (m in seq_along(metadata)) {
adp <- oceSetMetadata(adp, names(metadata)[m], metadata[[m]], note = NULL)
}
}
adp@metadata$source <- 'odf'
adp@processingLog <- processingLogAppend(adp@processingLog, 'Creation : Data and metadata read into adp object from ODF file')
return(adp)
}
#'ADCP Processing step 4.1
#'
#'@family processing
#'@family NC
#'
#'
#'@description Exports an adp object to a net cdf using variables and metadata
#' within adp combined with optional additional metatdata see details in
#' \code{\link[ncdf4:ncdf4]{ncdf4}} package
#'
#'@param obj an adp object from the oce class
#'@param name name of the NetCDF file to be produced
#'@param metadata csv file listing metadata names and values to be inserted into
#' global attributes of net CDF
#'
#'@export
oceNc_create <- function(adp, name, metadata){
if (!inherits(adp, "adp")){
stop("method is only for objects of class '", "adp", "'")
}
if (missing(metadata)){
warning('no metadata supplied')
}
#file name and path
ncpath <- "./"
ncname <- name
ncfname <- paste(ncpath, ncname, ".nc", sep = "")
####setting dimensions and definitions####
#dimension variables from adp object
time <- as.POSIXct(adp[['time']], tz = 'UTC', origin = '1970-01-01 00:00:00')
dist <- adp[['distance', 'numeric']]
lon <- adp[['longitude']]
lat <- adp[['latitude']]
#create dimensions
timedim <- ncdim_def("time", "seconds since 1970-01-01T00:00:00Z", as.double(time)) #time formatting FIX
distdim <- ncdim_def("distance", "metres", as.double(dist))
stationdim <- ncdim_def("station", "", as.numeric(adp[['mooring_number']]))
londim <- ncdim_def("lon", "degrees_east" , as.double(lon))
latdim <- ncdim_def("lat", "degrees_north", as.double(lat))
dimnchar <- ncdim_def('nchar', '', 1:23, create_dimvar = FALSE)
#set fill value
FillValue <- 1e35
if (adp@metadata$source == 'raw'){
#define variables
dlname <- 'lon'
lon_def <- ncvar_def(longname= "longitude", units = 'degrees_east', dim = stationdim, name = dlname, prec = 'double')
dlname <- 'lat'
lat_def <- ncvar_def( longname = 'latitude', units = 'degrees_north', dim = stationdim, name = dlname, prec = 'double')
dlname <- "eastward_sea_water_velocity"
u_def <- ncvar_def("EWCT", "m/sec", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "northward_sea_water_velocity"
v_def <- ncvar_def("NSCT", "m/sec", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "upward_sea_water_velocity"
w_def <- ncvar_def("VCSP", "m/sec", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "time_02"
t_def <- ncvar_def("ELTMEP01", "seconds since 1970-01-01T00:00:00Z", list( stationdim, timedim), FillValue, dlname, prec = 'double')
dlname <- "error_velocity_in_sea_water"
e_def <- ncvar_def("ERRV", "m/sec", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "ADCP_echo_intensity_beam_1"
b1_def <- ncvar_def("BEAM_01", "counts", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "ADCP_echo_intensity_beam_2"
b2_def <- ncvar_def("BEAM_02", "counts", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "ADCP_echo_intensity_beam_3"
b3_def <- ncvar_def("BEAM_03", "counts", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "ADCP_echo_intensity_beam_4"
b4_def <- ncvar_def("BEAM_04", "counts", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "ADCP_correlation_magnitude_beam_1"
cm1_def <- ncvar_def("CMAG_01", "counts", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "ADCP_correlation_magnitude_beam_2"
cm2_def <- ncvar_def("CMAG_02", "counts", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "ADCP_correlation_magnitude_beam_3"
cm3_def <- ncvar_def("CMAG_03", "counts", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "ADCP_correlation_magnitude_beam_4"
cm4_def <- ncvar_def("CMAG_04", "counts", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "percent_good_beam_1"
pg1_def <- ncvar_def("PGDP_01", "percent", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "percent_good_beam_2"
pg2_def <- ncvar_def("PGDP_02", "percent", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "percent_good_beam_3"
pg3_def <- ncvar_def("PGDP_03", "percent", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "percent_good_beam_4"
pg4_def <- ncvar_def("PGDP_04", "percent", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "pitch"
p_def <- ncvar_def("PTCH", "degrees", list( timedim, stationdim), FillValue, dlname, prec = "float")
dlname <- "roll"
r_def <- ncvar_def("ROLL", "degrees", list( timedim, stationdim ), FillValue, dlname, prec = "float")
dlname <- "height of sea surface"
hght_def <- ncvar_def("hght", "m", list( distdim, stationdim ), FillValue, dlname, prec = "float")
dlname <- "ADCP Transducer Temp."
Tx_def <- ncvar_def("Tx", "degrees celsius", list( timedim, stationdim), FillValue, dlname, prec = "float")
dlname <- "instrument depth"
D_def <- ncvar_def("DEPH", "m", list(timedim, stationdim), FillValue, dlname, prec = "float")
dlname <- "heading"
head_def <- ncvar_def("HEAD", "degrees", list(timedim, stationdim), FillValue, dlname, prec = "float")
dlname <- "pressure"
pres_def <- ncvar_def("PRES", "decibars", list(timedim, stationdim), FillValue, dlname, prec = "float")
dlname <- "speed of sound"
svel_def <- ncvar_def("SVEL", "m/s", list(timedim, stationdim), FillValue, dlname, prec = "float")
dlname <- "time_string"
ts_def <- ncvar_def("DTUT8601", units = "",dim = list( dimnchar, timedim), missval = NULL, name = dlname, prec = "char")
FillValue <- 0
dlname <- "quality_flag u"
qc_u_def <- ncvar_def("EWCT_QC", "", list(timedim, distdim, stationdim), FillValue, dlname, prec = "integer")
dlname <- "quality_flag v"
qc_v_def <- ncvar_def("NSCT_QC", "", list(timedim, distdim, stationdim), FillValue, dlname, prec = "integer")
dlname <- "quality_flag w"
qc_w_def <- ncvar_def("VCSP_QC", "", list(timedim, distdim, stationdim), FillValue, dlname, prec = "integer")
####writing net CDF####
#write out definitions to new nc file
ncout <- nc_create(ncfname, list(u_def, v_def, w_def, e_def, t_def, b1_def, b2_def, b3_def, b4_def, cm1_def, cm2_def, cm3_def, cm4_def, pg1_def, pg2_def, pg3_def, pg4_def, p_def, r_def, hght_def, Tx_def, D_def, qc_u_def, qc_v_def, qc_w_def, lon_def, lat_def, head_def, pres_def, svel_def, ts_def), force_v4 = TRUE)
}
if (adp@metadata$source == 'odf'){
#define variables
dlname <- 'lon'
lon_def <- ncvar_def(longname= "longitude", units = 'degrees_east', dim = stationdim, name = dlname, prec = 'double')
dlname <- 'lat'
lat_def <- ncvar_def( longname = 'latitude', units = 'degrees_north', dim = stationdim, name = dlname, prec = 'double')
dlname <- "eastward_sea_water_velocity"
u_def <- ncvar_def("EWCT", "m/sec", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "northward_sea_water_velocity"
v_def <- ncvar_def("NSCT", "m/sec", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "upward_sea_water_velocity"
w_def <- ncvar_def("VCSP", "m/sec", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "time_02"
t_def <- ncvar_def("ELTMEP01", "seconds since 1970-01-01T00:00:00Z", list( stationdim, timedim), FillValue, dlname, prec = "double")
dlname <- "error_velocity_in_sea_water"
e_def <- ncvar_def("ERRV", "m/sec", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "ADCP_echo_intensity_beam_1"
b1_def <- ncvar_def("BEAM_01", "counts", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "percent_good_beam_1"
pg1_def <- ncvar_def("PGDP_01", "percent", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "time_string"
ts_def <- ncvar_def("DTUT8601", units = "",dim = list(dimnchar, timedim), missval = NULL, name = dlname, prec = "char")
####writing net CDF####
#write out definitions to new nc file
ncout <- nc_create(ncfname, list(u_def, v_def, w_def, e_def, t_def, b1_def, pg1_def, lon_def, lat_def, ts_def), force_v4 = TRUE)
}
#insert variables into nc file
ncvar_put(ncout, u_def, adp[['v']][,,1])
ncvar_put(ncout, v_def, adp[['v']][,,2])
ncvar_put(ncout, w_def, adp[['v']][,,3])
ncvar_put(ncout, e_def, adp[['v']][,,4])
ncvar_put(ncout, t_def, as.POSIXct(adp[['time']], tz = 'UTC', origin = '1970-01-01 00:00:00'))
ncvar_put(ncout, lon_def, adp[['longitude']])
ncvar_put(ncout, lat_def, adp[['latitude']])
if (adp@metadata$source == 'raw'){
ncvar_put(ncout, b1_def, adp[['a', 'numeric']][,,1])
ncvar_put(ncout, b2_def, adp[['a', 'numeric']][,,2])
ncvar_put(ncout, b3_def, adp[['a', 'numeric']][,,3])
ncvar_put(ncout, b4_def, adp[['a', 'numeric']][,,4])
ncvar_put(ncout, cm1_def, adp[['q', 'numeric']][,,1])
ncvar_put(ncout, cm2_def, adp[['q', 'numeric']][,,2])
ncvar_put(ncout, cm3_def, adp[['q', 'numeric']][,,3])
ncvar_put(ncout, cm4_def, adp[['q', 'numeric']][,,4])
ncvar_put(ncout, pg1_def, adp[['g', 'numeric']][,,1])
ncvar_put(ncout, pg2_def, adp[['g', 'numeric']][,,2])
ncvar_put(ncout, pg3_def, adp[['g', 'numeric']][,,3])
ncvar_put(ncout, pg4_def, adp[['g', 'numeric']][,,4])
ncvar_put(ncout, p_def, adp[['pitch']])
ncvar_put(ncout, r_def, adp[['roll']])
ncvar_put(ncout, hght_def, (adp[['distance']] - adp[['sensor_depth']]))
ncvar_put(ncout, Tx_def, adp[['temperature']])
ncvar_put(ncout, D_def, adp[['depth']])
ncvar_put(ncout, qc_u_def, adp@metadata$flags$v[,,1])
ncvar_put(ncout, qc_v_def, adp@metadata$flags$v[,,2])
ncvar_put(ncout, qc_w_def, adp@metadata$flags$v[,,3])
ncvar_put(ncout, head_def, adp[['heading']])
ncvar_put(ncout, pres_def, adp[['pressure']])
ncvar_put(ncout, svel_def, adp[['soundSpeed']])
ncvar_put(ncout, ts_def, adp[['time']])
}
if (adp@metadata$source == 'odf'){
ncvar_put(ncout, b1_def, adp[['a', 'numeric']])
ncvar_put(ncout, pg1_def, adp[['q', 'numeric']])
ncvar_put(ncout, ts_def, adp[['time']])
}
####metadata####
ncatt_put(ncout, 'station', attname = 'cf_role',attval = 'timeseries_id')
ncatt_put(ncout, 'time', attname = 'cf_role', attval = 'profile_id')
ncatt_put(ncout, 'station', 'standard_name', 'platform_name')
ncatt_put(ncout, 'time' , 'calendar', 'gregorian')
ncatt_put(ncout, 'time_string', 'note', 'time values as ISO8601 string, YY-MM-DD hh:mm:ss')
ncatt_put(ncout, 'time_string', 'time_zone', 'UTC')
ncatt_put(ncout, 0, 'processing_history',adp[['processing_history']])
ncatt_put(ncout, 0, "time_coverage_duration", (tail(adp[['time']], n = 1) - adp[['time']][[1]]))
ncatt_put(ncout, 0, "time_coverage_duration_units", "days")
ncatt_put(ncout, 0, "cdm_data_type", "station")
ncatt_put(ncout, 0, "alternate_pressure_values", adp[['alternate_pressure_values']])
ncatt_put(ncout, 0, "alternate_pressure_file", adp[['alternate_pressure_file']])
ncatt_put(ncout, 0, "vertical_separation", adp[['vertical_separation']])
ncatt_put(ncout, 0, "title", adp[['title']])
if (adp@metadata$source == 'raw'){
##QC VARIABLE
ncatt_put(ncout, 'EWCT', 'ancillary_variables', 'EWCT_QC')
ncatt_put(ncout, 'NSCT', 'ancillary_variables', 'NSCT_QC')
ncatt_put(ncout, 'VCSP', 'ancillary_variables', 'VCSP_QC')
####pulled from adp object####
ncatt_put(ncout, 0, "mooring_number", adp[['mooring_number']])
# deprecated --- Diana Cardoso 06/01/2018
#ncatt_put(ncout, 0, "deployment_date", adp[['deployment_time']])
#ncatt_put(ncout, 0, "recovery_date", adp[['recovery_time']])
ncatt_put(ncout, 0, "firmware_version", adp[['firmwareVersion']])
ncatt_put(ncout, 0, "frequency", adp[['frequency']])
ncatt_put(ncout, 0, "beam_pattern", adp[['beamPattern']])
ncatt_put(ncout, 0, "janus", adp[['numberOfBeams']])
ncatt_put(ncout, 0, "pings_per_ensemble", adp[['pingsPerEnsemble']])
ncatt_put(ncout, 0, "valid_correlation_range", adp[['lowCorrThresh']])
ncatt_put(ncout, 0, "minmax_percent_good", adp[['percentGdMinimum']])
ncatt_put(ncout, 0,"minmax_percent_good", "100")
ncatt_put(ncout, 0, "error_velocity_threshold", adp[['errorVelocityMaximum']])
ncatt_put(ncout, 0, "transmit_pulse_length_cm", adp[['xmitPulseLength']]*100)
ncatt_put(ncout, 0, "false_target_reject_values", adp[['falseTargetThresh']])
ncatt_put(ncout, 0, "serial_number", adp[['serialNumber']])
# deprecated --- Diana Cardoso 06/01/2018
#ncatt_put(ncout, 0, "transform", adp[['oceCoordinate']])
ncatt_put(ncout, 0, "data_type", adp[['instrumentType']])
ncatt_put(ncout, 0, "data_subtype", adp[['data_subtype']])
ncatt_put(ncout, 0, "coord_system", adp[['oceCoordinate']])
ncatt_put(ncout, 0, "longitude", adp[['longitude']])
ncatt_put(ncout, 0, "latitude", adp[['latitude']])
ncatt_put(ncout, 0, "magnetic_variation", adp[['magnetic_variation']])
ncatt_put(ncout, 0, "platform", adp[['platform']])
ncatt_put(ncout, 0, "sounding", adp[['sounding']])
ncatt_put(ncout, 0, "chief_scientist", adp[['chief_scientist']])
ncatt_put(ncout, 0, "water_depth", adp[['sounding']])
ncatt_put(ncout, 0, "delta_t_sec",adp[['sampling_interval']])
ncatt_put(ncout, 0, "pred_accuracy", adp[['velocityResolution']]*1000)
ncatt_put(ncout, "station", 'longitude', adp[['longitude']])
ncatt_put(ncout, "station", 'latitude', adp[['latitude']])
ncatt_put(ncout, "DEPH", "xducer_offset_from_bottom", as.numeric(adp[['sounding']]) - adp[['sensor_depth']])
ncatt_put(ncout, "DEPH", "bin_size", adp[['cellSize']])
ncatt_put(ncout, "EWCT", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "EWCT", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "EWCT", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "NSCT", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "NSCT", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "NSCT", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "VCSP", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "VCSP", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "VCSP", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "ERRV", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "ERRV", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "ERRV", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "BEAM_01", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "BEAM_01", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "BEAM_01", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "BEAM_02", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "BEAM_02", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "BEAM_02", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "BEAM_03", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "BEAM_03", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "BEAM_03", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "BEAM_04", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "BEAM_04", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "BEAM_04", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "CMAG_01", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "CMAG_01", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "CMAG_01", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "CMAG_02", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "CMAG_02", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "CMAG_02", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "CMAG_03", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "CMAG_03", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "CMAG_03", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "CMAG_04", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "CMAG_04", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "CMAG_04", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "PGDP_01", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "PGDP_01", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "PGDP_01", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "PGDP_02", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "PGDP_02", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "PGDP_02", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "PGDP_03", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "PGDP_03", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "PGDP_03", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "PGDP_04", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "PGDP_04", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "PGDP_04", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "HEAD", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "HEAD", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "HEAD", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "PRES", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "PRES", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "PRES", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "SVEL", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "SVEL", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "SVEL", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "EWCT", "generic_name", "u")
ncatt_put(ncout, "NSCT", "generic_name", "v")
ncatt_put(ncout, "VCSP", "generic_name", "w")
ncatt_put(ncout, "ERRV", "generic_name", "w") #issue in current NC protocol
ncatt_put(ncout, "BEAM_01", "generic_name", "AGC")
ncatt_put(ncout, "BEAM_02", "generic_name", "AGC")
ncatt_put(ncout, "BEAM_03", "generic_name", "AGC")
ncatt_put(ncout, "BEAM_04", "generic_name", "AGC")
ncatt_put(ncout, "CMAG_01", "generic_name", "CM")
ncatt_put(ncout, "CMAG_02", "generic_name", "CM")
ncatt_put(ncout, "CMAG_03", "generic_name", "CM")
ncatt_put(ncout, "CMAG_04", "generic_name", "CM")
ncatt_put(ncout, "PGDP_01", "generic_name", "PGd")
ncatt_put(ncout, "PGDP_02", "generic_name", "PGd")
ncatt_put(ncout, "PGDP_03", "generic_name", "PGd")
ncatt_put(ncout, "PGDP_04", "generic_name", "PGd")
ncatt_put(ncout, "hght", "generic_name", "height")
ncatt_put(ncout, "hght", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "hght", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "hght", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "DEPH", "generic_name", "depth")
ncatt_put(ncout, "DEPH", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "DEPH", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "DEPH", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "Tx", "generic_name", "temp")
ncatt_put(ncout, "Tx", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "Tx", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "Tx", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "EWCT_QC", "comment", "Quality flag resulting from quality control")
ncatt_put(ncout, "EWCT_QC", "flag_meanings",adp[['flag_meaning']])
ncatt_put(ncout, "EWCT_QC", "flag_values",c(0:9))
ncatt_put(ncout, "EWCT_QC", "References", adp[['flag_references']])
ncatt_put(ncout, "NSCT_QC", "comment", "Quality flag resulting from quality control")
ncatt_put(ncout, "NSCT_QC", "flag_meanings", adp[['flag_meaning']])
ncatt_put(ncout, "NSCT_QC", "flag_values",c(0:9))
ncatt_put(ncout, "NSCT_QC", "References", adp[['flag_references']])
ncatt_put(ncout, "VCSP_QC", "comment", "Quality flag resulting from quality control")
ncatt_put(ncout, "VCSP_QC", "flag_meanings", adp[['flag_meaning']])
ncatt_put(ncout, "VCSP_QC", "flag_values",c(0:9))
ncatt_put(ncout, "VCSP_QC", "References", adp[['flag_references']])
#CF conventions
ncatt_put(ncout, 0, 'Conventions', 'CF-1.6')
ncatt_put(ncout, 0, "creator_type", "person")
ncatt_put(ncout, 0, "program", adp[['program']])
ncatt_put(ncout, 0, "sea_name", adp[['sea_name']])
ncatt_put(ncout, 0, "time_coverage_start", adp[['time_coverage_start']])
ncatt_put(ncout, 0, "time_coverage_end", adp[['time_coverage_end']])
ncatt_put(ncout, 0, "geospatial_lat_min", adp[['latitude']])
ncatt_put(ncout, 0, "geospatial_lat_max", adp[['latitude']])
ncatt_put(ncout, 0, "geospatial_lat_units", "degrees_north")
ncatt_put(ncout, 0, "geospatial_lon_min", adp[['longitude']])
ncatt_put(ncout, 0, "geospatial_lon_max", adp[['longitude']])
ncatt_put(ncout, 0, "geospatial_lon_units", "degrees_east")
if (adp[['orientation']] == 'up'){
ncatt_put(ncout, 0, "geospatial_vertical_min", adp[['sensor_depth']] + max(adp[['distance']], na.rm = TRUE))
ncatt_put(ncout, 0, "geospatial_vertical_max", adp[['sensor_depth']] + min(adp[['distance']], na.rm = TRUE))
}
if (adp[['orientation']] == 'down'){
ncatt_put(ncout, 0, "geospatial_vertical_min", adp[['sensor_depth']] + min(adp[['distance']], na.rm = TRUE))
ncatt_put(ncout, 0, "geospatial_vertical_max", adp[['sensor_depth']] + max(adp[['distance']], na.rm = TRUE))
}
ncatt_put(ncout, 0, "geospatial_vertical_units", "metres")
ncatt_put(ncout, 0, "geospatial_vertical_positive", 'down')
ncatt_put(ncout, 0, "institution", adp[['institution']])
ncatt_put(ncout, 0, "project", adp[['project']])
ncatt_put(ncout, 0, "history", adp[['history']])
ncatt_put(ncout, 0 , "flag_meanings", adp[['flag_meaning']])
ncatt_put(ncout, 0 , "flag_values", c(0:9))
ncatt_put(ncout, 0, "source", "R code: adcpProcess, github:")
ncatt_put(ncout, 0, "date_modified", date())
ncatt_put(ncout,0, "_FillValue", "1e35")
ncatt_put(ncout, 0, "featureType", "timeSeriesProfile") #link to oce object? ..... if adp == timeSeriesProfile
ncatt_put
#BODC P01 names
ncatt_put(ncout, "EWCT", "sdn_parameter_urn", "SDN:P01::LCEWAP01")
ncatt_put(ncout, "NSCT", "sdn_parameter_urn", "SDN:P01::LCNSAP01")
ncatt_put(ncout, "VCSP", "sdn_parameter_urn", "SDN:P01::LRZAAP01")
ncatt_put(ncout, "ERRV", "sdn_parameter_urn", "SDN:P01::LERRAP01")
ncatt_put(ncout, "BEAM_01", "sdn_parameter_urn", "SDN:P01::TNIHCE01")
ncatt_put(ncout, "BEAM_02", "sdn_parameter_urn", "SDN:P01::TNIHCE02")
ncatt_put(ncout, "BEAM_03", "sdn_parameter_urn", "SDN:P01::TNIHCE03")
ncatt_put(ncout, "BEAM_04", "sdn_parameter_urn", "SDN:P01::TNIHCE04")
ncatt_put(ncout, "PGDP_01", "sdn_parameter_urn", "SDN:P01::PCGDAP00")
ncatt_put(ncout, "PGDP_02", "sdn_parameter_urn", "SDN:P01::PCGDAP02")
ncatt_put(ncout, "PGDP_03", "sdn_parameter_urn", "SDN:P01::PCGDAP03")
ncatt_put(ncout, "PGDP_04", "sdn_parameter_urn", "SDN:P01::PCGDAP04")
#ncatt_put(ncout, "hght", "sdn_parameter_urn", "SDN:P01::")
ncatt_put(ncout, "DEPH", "sdn_parameter_urn", "SDN:P01::ADEPZZ01")
ncatt_put(ncout, "Tx", "sdn_parameter_urn", "SDN:P01::TEMPPR01")
#ncatt_put(ncout, "time_02", "sdn_parameter_urn", "SDN:P01::")
ncatt_put(ncout, "PTCH", "sdn_parameter_urn", "SDN:P01::PTCHEI01")
ncatt_put(ncout, "ROLL", "sdn_parameter_urn", "SDN:P01::ROLLFEI01")
ncatt_put(ncout, "lon", "sdn_parameter_urn", "SDN:P01::ALONZZ01")
ncatt_put(ncout, "lat", "sdn_parameter_urn", "SDN:P01::ALATZZ01")
ncatt_put(ncout, "HEAD", "sdn_parameter_urn", "SDN:P01::HEADCM01")
ncatt_put(ncout, "PRES", "sdn_parameter_urn", "SDN:P01::PRESPR01")
ncatt_put(ncout, "SVEL", "sdn_parameter_urn", "SDN:P01::SVELCV01")
ncatt_put(ncout, "ELTMEP01", "sdn_parameter_urn", "SDN:P01::ELTMEP01")
ncatt_put(ncout, "time_string", "sdn_parameter_urn", "SDN:P01::DTUT8601")
ncatt_put(ncout, "EWCT", "sdn_parameter_name", "Eastward current velocity (Eulerian) in the water body by moored acoustic doppler current profiler (ADCP)")
ncatt_put(ncout, "NSCT", "sdn_parameter_name", "Northward current velocity (Eulerian) in the water body by moored acoustic doppler current profiler (ADCP)")
ncatt_put(ncout, "VCSP", "sdn_parameter_name", "Upward current velocity in the water body by moored acoustic doppler current profiler (ADCP)")
ncatt_put(ncout, "ERRV", "sdn_parameter_name", "Current velocity error in the water body by moored acoustic doppler current profiler (ADCP)")
ncatt_put(ncout, "BEAM_01", "sdn_parameter_name", "Echo intensity from the water body by moored acoustic doppler current profiler (ADCP) beam 1")
ncatt_put(ncout, "BEAM_02", "sdn_parameter_name", "Echo intensity from the water body by moored acoustic doppler current profiler (ADCP) beam 2")
ncatt_put(ncout, "BEAM_03", "sdn_parameter_name", "Echo intensity from the water body by moored acoustic doppler current profiler (ADCP) beam 3")
ncatt_put(ncout, "BEAM_04", "sdn_parameter_name", "Echo intensity from the water body by moored acoustic doppler current profiler (ADCP) beam 4")
ncatt_put(ncout, "PGDP_01", "sdn_parameter_name", "Acceptable proportion of signal returns by moored acoustic doppler current profiler (ADCP) beam 1")
ncatt_put(ncout, "PGDP_02", "sdn_parameter_name", "Acceptable proportion of signal returns by moored acoustic doppler current profiler (ADCP) beam 2")
ncatt_put(ncout, "PGDP_03", "sdn_parameter_name", "Acceptable proportion of signal returns by moored acoustic doppler current profiler (ADCP) beam 3")
ncatt_put(ncout, "PGDP_04", "sdn_parameter_name", "Acceptable proportion of signal returns by moored acoustic doppler current profiler (ADCP) beam 4")
ncatt_put(ncout, "DEPH", "sdn_parameter_name", "Depth below surface of the water body")
ncatt_put(ncout, "Tx", "sdn_parameter_name", "Temperature of the water body")
ncatt_put(ncout, "PTCH", "sdn_parameter_name", "Orientation (pitch) of measurement platform by inclinometer")
ncatt_put(ncout, "ROLL", "sdn_parameter_name", "Orientation (roll angle) of measurement platform by inclinometer (second sensor)")
ncatt_put(ncout, "lon", "sdn_parameter_name", "Longitude east")
ncatt_put(ncout, "lat", "sdn_parameter_name", "Latitude north")
ncatt_put(ncout, "HEAD", "sdn_parameter_name", "Orientation (horizontal relative to true north) of measurement device {heading}")
ncatt_put(ncout, "PRES", "sdn_parameter_name", "Pressure (spatial co-ordinate) exerted by the water body by profiling pressure sensor and corrected to read zero at sea level")
ncatt_put(ncout, "SVEL", "sdn_parameter_name", "Sound velocity in the water body by computation from temperature and salinity by unspecified algorithm")
ncatt_put(ncout, 'ELTMEP01', "sdn_parameter_name", "Elapsed time (since 1970-01-01T00:00:00Z)")
ncatt_put(ncout, 'time_string', "sdn_parameter_name", "String corresponding to format 'YYYY-MM-DDThh:mm:ss.sssZ' or other valid ISO8601 string")
ncatt_put(ncout, "EWCT", "sdn_uom_urn", "SDN:P06::UVAA")
ncatt_put(ncout, "NSCT", "sdn_uom_urn", "SDN:P06::UVAA")
ncatt_put(ncout, "VCSP", "sdn_uom_urn", "SDN:P06::UVAA")
ncatt_put(ncout, "ERRV", "sdn_uom_urn", "SDN:P06::UVAA")
ncatt_put(ncout, "BEAM_01", "sdn_uom_urn", "SDN:P06::UCNT")
ncatt_put(ncout, "BEAM_02", "sdn_uom_urn", "SDN:P06::UCNT")
ncatt_put(ncout, "BEAM_03", "sdn_uom_urn", "SDN:P06::UCNT")
ncatt_put(ncout, "BEAM_04", "sdn_uom_urn", "SDN:P06::UCNT")
ncatt_put(ncout, "PGDP_01", "sdn_uom_urn", "SDN:P06::UPCT")
ncatt_put(ncout, "PGDP_02", "sdn_uom_urn", "SDN:P06::UPCT")
ncatt_put(ncout, "PGDP_03", "sdn_uom_urn", "SDN:P06::UPCT")
ncatt_put(ncout, "PGDP_04", "sdn_uom_urn", "SDN:P06::UPCT")
ncatt_put(ncout, "hght", "sdn_uom_urn", "SDN:P06::ULAA")
ncatt_put(ncout, "DEPH", "sdn_uom_urn", "SDN:P06:ULAA")
ncatt_put(ncout, "Tx", "sdn_uom_urn", "SDN:P06::UPAA")
ncatt_put(ncout, "PTCH", "sdn_uom_urn", "SDN:P06:UAAA")
ncatt_put(ncout, "ROLL", "sdn_uom_urn", "SDN:P06:UAAA")
ncatt_put(ncout, "lon", "sdn_uom_urn", "SDN:P06::DEGE")
ncatt_put(ncout, "lat", "sdn_uom_urn", "SDN:P06:DEGN")
ncatt_put(ncout, "HEAD", "sdn_uom_urn", "SDN:P06:UAAA")
ncatt_put(ncout, "PRES", "sdn_uom_urn", "SDN:P06:UPDB")
ncatt_put(ncout, "SVEL", "sdn_uom_urn", "SDN:P06:UVAA")
ncatt_put(ncout, "ELTMEP01", "sdn_uom_urn", "SDN:P06::UTBB")
ncatt_put(ncout, "time_string", "sdn_uom_urn", "SDN:P06::TISO")
ncatt_put(ncout, "EWCT", "sdn_uom_name", "Metres per second")
ncatt_put(ncout, "NSCT", "sdn_uom_name", "Metres per second")
ncatt_put(ncout, "VCSP", "sdn_uom_name", "Metres per second")
ncatt_put(ncout, "ERRV", "sdn_uom_name", "Metres per second")
ncatt_put(ncout, "BEAM_01", "sdn_uom_name", "Counts")
ncatt_put(ncout, "BEAM_02", "sdn_uom_name", "Counts")
ncatt_put(ncout, "BEAM_03", "sdn_uom_name", "Counts")
ncatt_put(ncout, "BEAM_04", "sdn_uom_name", "Counts")
ncatt_put(ncout, "PGDP_01", "sdn_uom_name", "Percent")
ncatt_put(ncout, "PGDP_02", "sdn_uom_name", "Percent")
ncatt_put(ncout, "PGDP_03", "sdn_uom_name", "Percent")
ncatt_put(ncout, "PGDP_04", "sdn_uom_name", "Percent")
ncatt_put(ncout, "hght", "sdn_uom_name", "Metres")
ncatt_put(ncout, "DEPH", "sdn_uom_name", "Metres")
ncatt_put(ncout, "Tx", "sdn_uom_name", "Celsius degree")
ncatt_put(ncout, "PTCH", "sdn_uom_name", "Degrees")
ncatt_put(ncout, "ROLL", "sdn_uom_name", "Degrees")
ncatt_put(ncout, "lon", "sdn_uom_name", "Degrees east")
ncatt_put(ncout, "lat", "sdn_uom_name", "Degrees north")
ncatt_put(ncout, "HEAD", "sdn_uom_name", "Degrees")
ncatt_put(ncout, "PRES", "sdn_uom_name", "Decibars")
ncatt_put(ncout, "SVEL", "sdn_uom_name", "Metres per second")
ncatt_put(ncout, "ELTMEP01", "sdn_uom_name", "Seconds")
ncatt_put(ncout, "time_string", "sdn_uom_name", "ISO8601")
#CF standard names
ncatt_put(ncout, "EWCT", "standard_name", "eastward_sea_water_velocity")
ncatt_put(ncout, "NSCT", "standard_name", "northward_sea_water_velocity")
ncatt_put(ncout, "VCSP", "standard_name", "upward_sea_water_velocity")
ncatt_put(ncout, "ELTMEP01", "standard_name", "time")
ncatt_put(ncout, "lat", "standard_name", "latitude")
ncatt_put(ncout, "lon", "standard_name", "longitude")
ncatt_put(ncout, "DEPH", "standard_name", "depth")
ncatt_put(ncout, "PTCH", "standard_name", "platform_pitch_angle")
ncatt_put(ncout, "ROLL", "standard_name", "platform_roll_angle")
ncatt_put(ncout, "PRES", "standard_name", "sea_water_pressure")
ncatt_put(ncout, "SVEL", "standard_name", "speed_of_sound_in_sea_water")
}
if (adp@metadata$source == 'odf'){
ncatt_put(ncout, 0, "mooring_number", adp[['mooring_number']])
# deprecated --- Diana Cardoso 06/01/2018
#ncatt_put(ncout, 0, "deployment_date", adp[['deployment_time']])
#ncatt_put(ncout, 0, "recovery_date", adp[['recovery_time']])
ncatt_put(ncout, 0, "firmware_version", adp[['firmwareVersion']])
ncatt_put(ncout, 0, "frequency", adp[['frequency']])
ncatt_put(ncout, 0, "beam_pattern", adp[['beamPattern']])
ncatt_put(ncout, 0, "janus", adp[['numberOfBeams']])
ncatt_put(ncout, 0, "pings_per_ensemble", adp[['pingsPerEnsemble']])
ncatt_put(ncout, 0, "valid_correlation_range", adp[['lowCorrThresh']])
ncatt_put(ncout, 0, "minmax_percent_good", adp[['percentGdMinimum']])
ncatt_put(ncout, 0,"minmax_percent_good", "100")
ncatt_put(ncout, 0, "error_velocity_threshold", adp[['errorVelocityMaximum']])
ncatt_put(ncout, 0, "transmit_pulse_length_cm", adp[['xmitPulseLength']])
ncatt_put(ncout, 0, "false_target_reject_values", adp[['falseTargetThresh']])
ncatt_put(ncout, 0, "serial_number", adp[['serialNumber']])
#deprecated --- Diana Cardoso 06/01/2018
#ncatt_put(ncout, 0, "transform", adp[['oceCoordinate']])
ncatt_put(ncout, 0, "data_type", adp[['instrumentType']])
ncatt_put(ncout, 0, "data_subtype", adp[['model']])
ncatt_put(ncout, 0, "coord_system", adp[['oceCoordinate']])
ncatt_put(ncout, 0, "longitude", adp[['longitude']])
ncatt_put(ncout, 0, "latitude", adp[['latitude']])
ncatt_put(ncout, 0, "magnetic_variation", adp[['magneticVariation']])
ncatt_put(ncout, 0, "platform", adp[['platform']])
ncatt_put(ncout, 0, "sounding", adp[['sounding']])
ncatt_put(ncout, 0, "chief_scientist", adp[['chief_scientist']])
#deprecated Mathieu Ouillet June 20 2018
#ncatt_put(ncout, 0, "data_origin", adp[['institution']])
ncatt_put(ncout, 0, "water_depth", adp[['water_depth']])
ncatt_put(ncout, 0, "delta_t_sec",adp[['sampling_interval']])
ncatt_put(ncout, 0, "pred_accuracy", adp[['velocityResolution']])
#FIXME: should be pulled from odf...not in object... issue with oce read.odf
ncatt_put(ncout, "distance", "xducer_offset_from_bottom", adp[['depth_off_bottom']])
ncatt_put(ncout, "distance", "bin_size", adp[['cellSize']])
ncatt_put(ncout, "EWCT", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "EWCT", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "EWCT", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "NSCT", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "NSCT", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "NSCT", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "VCSP", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "VCSP", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "VCSP", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "ERRV", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "ERRV", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "ERRV", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "BEAM_01", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "BEAM_01", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "BEAM_01", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "PGDP_01", "sensor_type", adp[['instrumentType']])
ncatt_put(ncout, "PGDP_01", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "PGDP_01", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "EWCT", "generic_name", "u")
ncatt_put(ncout, "NSCT", "generic_name", "v")
ncatt_put(ncout, "VCSP", "generic_name", "w")
ncatt_put(ncout, "ERRV", "generic_name", "w") #issue in current NC protocol
ncatt_put(ncout, "BEAM_01", "generic_name", "AGC")
ncatt_put(ncout, "PGDP_01", "generic_name", "PGd")
#CF
ncatt_put(ncout, 0, 'Conventions', 'CF-1.6')
ncatt_put(ncout, 0, "creator_type", "person")
ncatt_put(ncout, 0, "creator_institution", adp[['institution']])
ncatt_put(ncout, 0, "program", adp[['program']])
ncatt_put(ncout, 0, "sea_name", adp[['sea_name']])
ncatt_put(ncout, 0, "time_coverage_start", adp[['deployment_time']])
ncatt_put(ncout, 0, "time_coverage_end", adp[['recovery_time']])
ncatt_put(ncout, 0, "geospatial_lat_min", adp[['latitude']])
ncatt_put(ncout, 0, "geospatial_lat_max", adp[['latitude']])
ncatt_put(ncout, 0, "geospatial_lat_units", "degrees_north")
ncatt_put(ncout, 0, "geospatial_lon_min", adp[['longitude']])
ncatt_put(ncout, 0, "geospatial_lon_max", adp[['longitude']])
ncatt_put(ncout, 0, "geospatial_lon_units", "degrees_east")
if (adp[['orientation']] == 'up'){
ncatt_put(ncout, 0, "geospatial_vertical_min", adp[['sensor_depth']] + max(adp[['distance']], na.rm = TRUE))
ncatt_put(ncout, 0, "geospatial_vertical_max", adp[['sensor_depth']] + min(adp[['distance']], na.rm = TRUE))
}
if (adp[['orientation']] == 'down'){
ncatt_put(ncout, 0, "geospatial_vertical_min", adp[['sensor_depth']] + min(adp[['distance']], na.rm = TRUE))
ncatt_put(ncout, 0, "geospatial_vertical_max", adp[['sensor_depth']] + max(adp[['distance']], na.rm = TRUE))
}
ncatt_put(ncout, 0, "geospatial_vertical_units", "metres")
ncatt_put(ncout, 0, "geospatial_vertical_positive", adp[['orientation']]) #eg up or down
ncatt_put(ncout, 0, "institution", adp[['institution']])
ncatt_put(ncout, 0, "creator_name", adp[['creator_name']])
ncatt_put(ncout, 0, "creator_url", adp[['creator_url']])
ncatt_put(ncout, 0, "creator_email", adp[['creator_email']])
ncatt_put(ncout, 0, "project", adp[['project']])
ncatt_put(ncout, 0, "processing_history", adp[['processing_history']])
ncatt_put(ncout, 0 , "flag_meanings", adp[['flag_meaning']])
ncatt_put(ncout, 0 , "flag_values", c(0:9))
ncatt_put(ncout, 0, "source", "R code: adcpProcess, github:")
ncatt_put(ncout, 0, "date_modified", date())
ncatt_put(ncout,0, "_FillValue", "1e35")
ncatt_put(ncout, 0, "featureType", "timeSeriesProfile") #link to oce object? ..... if adp == timeSeriesProfile
#BODC P01 names
ncatt_put(ncout, "EWCT", "sdn_parameter_urn", "SDN:P01::LCEWAP01")
ncatt_put(ncout, "NSCT", "sdn_parameter_urn", "SDN:P01::LCNSAP01")
ncatt_put(ncout, "VCSP", "sdn_parameter_urn", "SDN:P01::LRZAAP01")
ncatt_put(ncout, "ERRV", "sdn_parameter_urn", "SDN:P01::LERRAP01")
ncatt_put(ncout, "BEAM_01", "sdn_parameter_urn", "SDN:P01::THINCE01")
ncatt_put(ncout, "PGDP_01", "sdn_parameter_urn", "SDN:P01::PCGDAP00")
ncatt_put(ncout, "lon", "sdn_parameter_urn", "SDN:P01::ALONZZ01")
ncatt_put(ncout, "lat", "sdn_parameter_urn", "SDN:P01::ALATZZ01")
ncatt_put(ncout, "EWCT", "sdn_parameter_name", "Eastward current velocity (Eulerian) in the water body by moored acoustic doppler current profiler (ADCP)")
ncatt_put(ncout, "NSCT", "sdn_parameter_name", "Northward current velocity (Eulerian) in the water body by moored acoustic doppler current profiler (ADCP)")
ncatt_put(ncout, "VCSP", "sdn_parameter_name", "Upward current velocity in the water body by moored acoustic doppler current profiler (ADCP)")
ncatt_put(ncout, "ERRV", "sdn_parameter_name", "Current velocity error in the water body by moored acoustic doppler current profiler (ADCP)")
ncatt_put(ncout, "BEAM_01", "sdn_parameter_name", "Echo intensity from the water body by moored acoustic doppler current profiler (ADCP) beam 1")
ncatt_put(ncout, "PGDP_01", "sdn_parameter_name", "Acceptable proportion of signal returns by moored acoustic doppler current profiler (ADCP) beam 1")
ncatt_put(ncout, "lon", "sdn_parameter_name", "Longitude east")
ncatt_put(ncout, "lat", "sdn_parameter_name", "Latitude north")
#P06
ncatt_put(ncout, "EWCT", "sdn_uom_urn", "SDN:P06::UVAA")
ncatt_put(ncout, "NSCT", "sdn_uom_urn", "SDN:P06::UVAA")
ncatt_put(ncout, "VCSP", "sdn_uom_urn", "SDN:P06::UVAA")
ncatt_put(ncout, "ERRV", "sdn_uom_urn", "SDN:P06::UVAA")
ncatt_put(ncout, "BEAM_01", "sdn_uom_urn", "SDN:P06::UCNT")
ncatt_put(ncout, "PGDP_01", "sdn_uom_urn", "SDN:P06::UPCT")
ncatt_put(ncout, "lon", "sdn_uom_urn", "SDN:P06::DEGE")
ncatt_put(ncout, "lat", "sdn_uom_urn", "SDN:P06:DEGN")
ncatt_put(ncout, "EWCT", "sdn_uom_name", "Metres per second")
ncatt_put(ncout, "NSCT", "sdn_uom_name", "Metres per second")
ncatt_put(ncout, "VCSP", "sdn_uom_name", "Metres per second")
ncatt_put(ncout, "ERRV", "sdn_uom_name", "Metres per second")
ncatt_put(ncout, "BEAM_01", "sdn_uom_name", "Counts")
ncatt_put(ncout, "PGDP_01", "sdn_uom_name", "Percent")
ncatt_put(ncout, "lon", "sdn_uom_name", "Degrees east")
ncatt_put(ncout, "lat", "sdn_uom_name", "Degrees north")
#CF standard names
ncatt_put(ncout, "EWCT", "standard_name", "eastward_sea_water_velocity")
ncatt_put(ncout, "NSCT", "standard_name", "northward_sea_water_velocity")
ncatt_put(ncout, "VCSP", "standard_name", "upward_sea_water_velocity")
ncatt_put(ncout, "lat", "standard_name", "latitude")
ncatt_put(ncout, "lon", "standard_name", "longitude")
}
if(!is.null(adp[['publisher_name']])){
ncatt_put(ncout, 0, "publisher_name", adp[['publisher_name']])
}
if(!is.null(adp[['publisher_url']])){
ncatt_put(ncout, 0, "publisher_url", adp[['publisher_url']])
}
if(!is.null(adp[['publisher_email']])){
ncatt_put(ncout, 0, "publisher_email", adp[['publisher_email']])
}
####
ncatt_put(ncout, "EWCT", "data_max", max(adp[['v']][,,1], na.rm = TRUE))
ncatt_put(ncout, "EWCT", "data_min", min(adp[['v']][,,1], na.rm = TRUE))
ncatt_put(ncout, "EWCT", "valid_max", 1000)
ncatt_put(ncout, "EWCT", "valid_min", -1000)
ncatt_put(ncout, "NSCT", "data_max", max(adp[['v']][,,2], na.rm = TRUE))
ncatt_put(ncout, "NSCT", "data_min", min(adp[['v']][,,2], na.rm = TRUE))
ncatt_put(ncout, "NSCT", "valid_max", 1000)
ncatt_put(ncout, "NSCT", "valid_min", -1000)
ncatt_put(ncout, "VCSP", "data_max", max(adp[['v']][,,3], na.rm = TRUE))
ncatt_put(ncout, "VCSP", "data_min", min(adp[['v']][,,3], na.rm = TRUE))
ncatt_put(ncout, "VCSP", "valid_max", 1000)
ncatt_put(ncout, "VCSP", "valid_min", -1000)
ncatt_put(ncout, "ERRV", "data_max", max(adp[['v']][,,4], na.rm = TRUE))
ncatt_put(ncout, "ERRV", "data_min", min(adp[['v']][,,4], na.rm = TRUE))
ncatt_put(ncout, "ERRV", "valid_max", 2000)
ncatt_put(ncout, "ERRV", "valid_min", -2000)
if(adp@metadata$source == 'raw'){
ncatt_put(ncout, "BEAM_01", "data_min", min(adp[['a', 'numeric']][,,1], na.rm= TRUE))
ncatt_put(ncout, "BEAM_01", "data_max", max(adp[['a', 'numeric']][,,1], na.rm= TRUE))
ncatt_put(ncout, "BEAM_02", "data_min", min(adp[['a' ,'numeric']][,,2], na.rm= TRUE))
ncatt_put(ncout, "BEAM_02", "data_max", max(adp[['a', 'numeric']][,,2], na.rm= TRUE))
ncatt_put(ncout, "BEAM_03", "data_min", min(adp[['a', 'numeric']][,,3], na.rm= TRUE))
ncatt_put(ncout, "BEAM_03", "data_max", max(adp[['a', 'numeric']][,,3], na.rm= TRUE))
ncatt_put(ncout, "BEAM_04", "data_min", min(adp[['a', 'numeric']][,,4], na.rm= TRUE))
ncatt_put(ncout, "BEAM_04", "data_max", max(adp[['a', 'numeric']][,,4], na.rm= TRUE))
ncatt_put(ncout, "CMAG_01", "data_min", min(adp[['q', 'numeric']][,,1], na.rm= TRUE))
ncatt_put(ncout, "CMAG_01", "data_max", max(adp[['q', 'numeric']][,,1], na.rm= TRUE))
ncatt_put(ncout, "CMAG_02", "data_min", min(adp[['q' ,'numeric']][,,2], na.rm= TRUE))
ncatt_put(ncout, "CMAG_02", "data_max", max(adp[['q', 'numeric']][,,2], na.rm= TRUE))
ncatt_put(ncout, "CMAG_03", "data_min", min(adp[['q', 'numeric']][,,3], na.rm= TRUE))
ncatt_put(ncout, "CMAG_03", "data_max", max(adp[['q', 'numeric']][,,3], na.rm= TRUE))
ncatt_put(ncout, "CMAG_04", "data_min", min(adp[['q', 'numeric']][,,4], na.rm= TRUE))
ncatt_put(ncout, "CMAG_04", "data_max", max(adp[['q', 'numeric']][,,4], na.rm= TRUE))
ncatt_put(ncout, "PGDP_01", "data_min", min(adp[['g', 'numeric']][,,1], na.rm= TRUE))
ncatt_put(ncout, "PGDP_01", "data_max", max(adp[['g', 'numeric']][,,1], na.rm= TRUE))# eg min 25 % good
ncatt_put(ncout, "PGDP_02", "data_min", min(adp[['g', 'numeric']][,,2], na.rm= TRUE))
ncatt_put(ncout, "PGDP_02", "data_max", max(adp[['g' ,'numeric']][,,2], na.rm= TRUE))
ncatt_put(ncout, "PGDP_03", "data_min", min(adp[['g' ,'numeric']][,,3], na.rm= TRUE))
ncatt_put(ncout, "PGDP_03", "data_max", max(adp[['g', 'numeric']][,,3], na.rm= TRUE))
ncatt_put(ncout, "PGDP_04", "data_min", min(adp[['g', 'numeric']][,,4], na.rm= TRUE))
ncatt_put(ncout, "PGDP_04", "data_max", max(adp[['g', 'numeric']][,,4], na.rm= TRUE))
ncatt_put(ncout, "hght", "data_min", min(adp[['depth', 'numeric']]))
ncatt_put(ncout, "hght", "data_max", max(adp[['depth', 'numeric']]))
ncatt_put(ncout, "DEPH", "data_min", min(adp[['depth']]))
ncatt_put(ncout, "DEPH", "data_max", max(adp[['depth']]))
ncatt_put(ncout, "Tx", "data_min", min(adp[['temperature']]))
ncatt_put(ncout, "Tx", "data_max", max(adp[['temperature']]))
ncatt_put(ncout, "PTCH", "data_min", min(adp[['pitch']]))
ncatt_put(ncout, "PTCH", "data_max", max(adp[['pitch']]))
ncatt_put(ncout, "ROLL", "data_min", min(adp[['roll']]))
ncatt_put(ncout, "ROLL", "data_max", max(adp[['roll']]))
ncatt_put(ncout, "HEAD", "data_min", min(adp[['heading']]))
ncatt_put(ncout, "HEAD", "data_max", max(adp[['heading']]))
ncatt_put(ncout, "PRES", "data_min", min(adp[['pressure']]))
ncatt_put(ncout, "PRES", "data_max", max(adp[['pressure']]))
ncatt_put(ncout, "SVEL", "data_min", min(adp[['soundSpeed']]))
ncatt_put(ncout, "SVEL", "data_max", max(adp[['soundSpeed']]))
}
if( adp@metadata$source == 'odf'){
ncatt_put(ncout, "BEAM_01", "data_min", min(adp[['a', 'numeric']], na.rm= TRUE))
ncatt_put(ncout, "BEAM_01", "data_max", max(adp[['a', 'numeric']], na.rm= TRUE))
ncatt_put(ncout, "PGDP_01", "data_min", min(adp[['q', 'numeric']], na.rm= TRUE))
ncatt_put(ncout, "PGDP_01", "data_max", max(adp[['q', 'numeric']], na.rm= TRUE))
}
if (!missing(metadata)) {
metad <- read.csv(metadata, header = TRUE)
mn <- as.character(metad[,1])
mv <- as.character(metad[,2])
md <- as.list(mv)
names(md) <- mn
for (m in seq_along(md)) {
ncatt_put(ncout, 0, names(md)[m], md[[m]])
}
nc_close(ncout)
}
}
####adpCombine####
####create netCDF from combined sources####
#from ODF : processed data (u, v, w, werr, beam01, pgdp01, time)
#from archivede netCDF : metadata
#from RAW file: beam2-4, pgdp2-4, ptch, roll, hght, tx, d, heading, pressure, soundspeed
#instrument metadata
#combine all file sources into single adp object
#adp: from ODF list (odf2adp)
#raw file
#archive netCDF
#added metadata to meet standards
#'
#'
#'
#'ADCP Combine
#'
#'@family odf
#'@family NC
#'@family processing
#'
#'@description Combines archived data and metadata from raw, odf and netCDF
#' sources into adp object which can be exported as netCDF or saved
#'
#' @details If either netCDF or Raw file is unavailable this function can still
#' run, however if only ODF files are available please use only
#' \code{\link[ADCP:odf2adp]{odf2adp}} to combine odf files If netCDF file is
#' missing some metadata may be required to be added manually. If raw file is
#' missing dataset will not be complete but will include null values where
#' set is missing data. Either way the object produced can still be passed to
#' \code{\link[ADCP:adpNC]{adpNC()}} for export.
#'
#'@details \bold{a) Raw file (.000)}
#'
#'Contains:
#'
#'
#' \bold{Data:} heading, pressure, sound speed data, BEAM_02-_04, PGDP_02-_04,
#' PTCH, ROLL, HGHT, Tx, D( D is not actually equal to depth values recorded in
#' raw file but calculated using swDepth from recorded pressure values)
#'
#'
#'\bold{ Metadata: } firmwareVersion, frequency, beamPattern, orientation, beamAngle,
#' numberOfBeams (janus), pingsPerEnsemble, velocityResolution (pred_accuracy),
#' lowCorrThresh (valid_correlation_range), percentGdMinimum
#' (minmax_percent_good), errorVelocityMaximum (error_velocity_threshold),
#' xmitPulseLength (transmit_pulse_length), falseTargetThresh
#' (false_target_reject_values), serialNumber, instrumentType(data_type),
#' bin1Distance
#'
#'
#' b) \bold{Archived netCDF}
#'
#' Contains:
#'
#'
#' \bold{ Data:} BEAM_02-_04, PGDP_02-_04, PTCH, ROLL, HGHT, Tx, D
#' ***note this DATA is pulled from the RAW file in case NC file is corrupted or missing
#'
#'
#' \bold{Metadata: }creation_date, start_time, stop_time, inst_type, history,
#' , , , transform,
#' data_subtype, coord_system, water_mass, , , ,
#' var_fill, experiment, project, descript, data_cmnt, fill_flag, ,
#' magnetic_variation, , delta_t_sec, time_between_ping_groups, depth:
#' xducer_offset_from_bottom, depth: bin_size
#'
#'
#'
#' \bold{c) Archived ODFs (series for each mooring)}
#'
#' Contains:
#'
#' \bold{Data:} PROCESSED EWCT, NSCT, VCSP, ERRV, BEAM_01 (!which is
#' actually the average echo intensity), PGDP_04, time, distance
#'
#'
#' \bold{ Metadata:} units (v, distance), cellSize, numberOfBeams, orientation,
#' model, type, serialNumber, ship (platform), scientist
#' (chief_scientist), institution (data_origin), cruise (cruise_name), station (mooring),
#' countryInstituteCode, cruiseNumber, startTime, latitude, longitude,
#' waterDepth, sounding
#'
#'
#'\bold{ Note:} The time offset is a major source of error, not all files were
#' produced in the same format some times may have no offset, some files
#' may have offset up to a few hours. Be careful when selecting a value for
#' dt, if NULL is not working please investigate within the ODF and raw
#' files to calculate or attempt to match the times.
#'
#'@param adp an adp object sourced from ODF files using
#' \code{\link[ADCP:odf2adp]{odf2adp}}
#'@param raw a raw ADCP file (.000)
#'@param ncin an archived netCDF file (.nc)
#' @param dt The time offset to be applied to raw data in order to match times
#' produced in ODF files. If left NULL the script will use the default action
#' used in the program which wrote the ODF files which is to add 1/2 the
#' sampling interval to each time value. Where sampling interval =
#' pingsPerEnsemble * ensembleInterval
#'
#'@export
#'
#'
####adpCombine####
adpCombine <- function(adp, raw, ncin = '', dt = NULL){
if(!is.null(raw)){
a <- read.adp(raw)
#####pull metadata from RAW####
firmware_version <- a[['firmwareVersion']]
frequency <- a[['frequency']]
beam_pattern <- a[['beamPattern']]
orientation <- a[['orientation']]
beam_angle <- a[['beamAngle']]
janus <- a[['numberOfBeams']]
pings_per_ensemble <- a[['pingsPerEnsemble']]
pred_accuracy <- (a[['velocityResolution']]*1000)
valid_correlation_range <- a[['lowCorrThresh']]
minmax_percent_good <- a[['percentGdMinimum']]
error_velocity_threshold <- a[['errorVelocityMaximum']]
#time_between_ping_groups <- a[['']]
transmit_pulse_length_cm <-( a[['xmitPulseLength']]*100)
false_target_reject_values <- a[['falseTargetThresh']]
serial_number <- a[['serialNumber']]
data_type <- a[['instrumentType']]
bin1Distance <- a[['bin1Distance']]
adp <- oceSetMetadata(adp, 'firmware_version', firmware_version, note = NULL)
adp <- oceSetMetadata(adp, 'frequency', frequency, note = NULL)
adp <- oceSetMetadata(adp, 'beam_pattern' , beam_pattern, note = NULL)
adp <- oceSetMetadata(adp, 'orientation', orientation, note = NULL)
adp <- oceSetMetadata(adp, 'beam_angle', beam_angle, note = NULL)
adp <- oceSetMetadata(adp, 'janus', janus, note = NULL)
adp <- oceSetMetadata(adp, 'pings_per_ensemble', pings_per_ensemble, note = NULL)
adp <- oceSetMetadata(adp, 'pred_accuracy', pred_accuracy, note = NULL)
adp <- oceSetMetadata(adp, 'valid_correlation_range', valid_correlation_range, note = NULL)
adp <- oceSetMetadata(adp, 'minmax_percent_good', minmax_percent_good, note = NULL)
adp <- oceSetMetadata(adp, 'error_velocity_threshold', error_velocity_threshold, note = NULL)
#adp <- oceSetMetadata(adp, 'time_between_ping_groups', , note = NULL)
adp <- oceSetMetadata(adp, 'transmit_pulse_length_cm', transmit_pulse_length_cm, note = NULL)
adp <- oceSetMetadata(adp, 'false_target_reject_values', false_target_reject_values, note = NULL)
adp <- oceSetMetadata(adp, 'serial_number', serial_number, note = NULL)
adp <- oceSetMetadata(adp, 'data_type', data_type, note = NULL)
adp <- oceSetMetadata(adp, 'bin1Distance', bin1Distance, note = NULL)
}else{
warning("No raw file provided, please ensure metadata is complete!")
if(!missing(ncin)){
ni <- nc_open(ncin)
firmware_version <- ncatt_get(ni, 0, 'firmware_version')
frequency <- ncatt_get(ni,0, 'frequency')
beam_pattern <- ncatt_get(ni, 0,"beam_pattern")
orientation <- ncatt_get(ni, 0,"orientation")
beam_angle <- ncatt_get(ni,0, "beam_angle")
janus <- ncatt_get(ni,0, "janus")
pings_per_ensemble <- ncatt_get(ni,0, 'pings_per_ensemble')
pings_per_ensemble <- as.numeric(pings_per_ensemble$value)
pred_accuracy <- ncatt_get(ni,0, 'pred_accuracy')
valid_correlation_range <- ncatt_get(ni,0, 'valid_correlation_range')
minmax_percent_good <- ncatt_get(ni,0, 'minmax_percent_good' )
error_velocity_threshold <- ncatt_get(ni, 0, 'error_velocity_threshold')
transmit_pulse_length_cm <- ncatt_get(ni, 0, 'transmit_pulse_length_cm')
false_target_reject_values <- ncatt_get(ni, 0, 'false_target_reject_values')
serial_number <- ncatt_get(ni, 0, 'ADCP_serial_number')
data_type <- ncatt_get(ni, 0, 'DATA_TYPE')
depth <- FALSE
if (length(grep(names(ni$var), pattern = 'D_3')) >0){
D <- ncvar_get(ni, 'D_3')
depth <- TRUE
# changed from D_3 to depth to accomodate older files where there is no depth variable
#reverted back to D_3, depth axis represent bin depth not instrument depth which is what is needed
}
Tx <- ncvar_get(ni, 'Tx_1211')
nc_close(ni)
adp <- oceSetMetadata(adp, 'firmware_version', firmware_version$value, note = NULL)
adp <- oceSetMetadata(adp, 'frequency', frequency$value, note = NULL)
adp <- oceSetMetadata(adp, 'beam_pattern' , beam_pattern$value, note = NULL)
adp <- oceSetMetadata(adp, 'orientation', orientation$value, note = NULL)
adp <- oceSetMetadata(adp, 'beam_angle', beam_angle$value, note = NULL)
adp <- oceSetMetadata(adp, 'janus', janus$value, note = NULL)
adp <- oceSetMetadata(adp, 'pings_per_ensemble', pings_per_ensemble, note = NULL)
adp <- oceSetMetadata(adp, 'pred_accuracy', pred_accuracy$value, note = NULL)
adp <- oceSetMetadata(adp, 'valid_correlation_range', valid_correlation_range$value, note = NULL)
adp <- oceSetMetadata(adp, 'minmax_percent_good', minmax_percent_good$value, note = NULL)
adp <- oceSetMetadata(adp, 'error_velocity_threshold', error_velocity_threshold$value, note = NULL)
#adp <- oceSetMetadata(adp, 'time_between_ping_groups', , note = NULL)
adp <- oceSetMetadata(adp, 'transmit_pulse_length_cm', transmit_pulse_length_cm$value, note = NULL)
adp <- oceSetMetadata(adp, 'false_target_reject_values', false_target_reject_values$value, note = NULL)
adp <- oceSetMetadata(adp, 'serial_number', serial_number$value, note = NULL)
adp <- oceSetMetadata(adp, 'data_type', data_type$value, note = NULL)
adp <- oceSetMetadata(adp, 'bin1Distance', adp[['cellSize']]/2, note = NULL)
}else{
warning(
"Please provide metadata: firmware_version, frequency, beam_pattern, orientation,
beam_angle, janus, pings_per_ensemble, pred_accuracy, valid_correlation_range, minmax_percent_good
, error_velocity_threshold, transmit_pulse_length_cm, false_target_reject_Values, serial_number
, data_type, bin1Distance"
)
}
}
#####pull metadata from archive NC####
if(!missing(ncin)){
ni <- nc_open(ncin)
#pull log sheet metadata from incoming netCDF
title <- ncatt_get(ni, 0, "title")
creation_date <- ncatt_get(ni, 0, 'CREATION_DATE')
time_coverage_start <- ncatt_get(ni, 0, 'start_time')
time_coverage_end <- ncatt_get(ni, 0, 'stop_time')
inst_type <- ncatt_get(ni, 0, 'INST_TYPE')
historyadp <- ncatt_get(ni, 0, 'history')
#deprecated - Diana Cardoso June 15 2018
#starting_water_layer <- ncatt_get(ni, 0, 'starting_water_layer')
#ending_water_layer <- ncatt_get(ni, 0, 'ending_water_layer')
#depth_note <- ncatt_get(ni, 0, 'depth_note')
# deprecated --- Diana Cardoso 06/01/2018
#transform <- ncatt_get(ni, 0, 'transform')
data_subtype <- ncatt_get(ni, 0, 'DATA_SUBTYPE')
coord_system <- ncatt_get(ni, 0, 'COORD_SYSTEM')
water_mass <- ncatt_get(ni, 0, 'WATER_MASS')
#deprecated Diana Cardoso June 15 2018
#pos_const <- ncatt_get(ni, 0, 'POS_CONST')
#depth_const <- ncatt_get(ni, 0, 'DEPTH_CONST')
#drifter <- ncatt_get(ni, 0, 'DRIFTER')
FillValue <- ncatt_get(ni, 0, 'VAR_FILL')
experiment <- ncatt_get(ni, 0, 'EXPERIMENT')
project <- ncatt_get(ni, 0, 'PROJECT')
description <- ncatt_get(ni, 0, 'DESCRIPT')
data_comment <- ncatt_get(ni, 0, 'DATA_CMNT')
fill_flag <- ncatt_get(ni, 0, 'FILL_FLAG')
#deprecated Diana Cardoso June 15 2018
#composite <- ncatt_get(ni, 0, 'COMPOSITE')
magnetic_variation <- ncatt_get(ni, 0, 'magnetic_variation')
delta_t_sec <- ncatt_get(ni, 0, 'DELTA_T_sec')
ping_interval <- ncatt_get(ni, 0, 'time_between_ping_groups')
data_origin <- ncatt_get(ni, 0, 'DATA_ORIGIN')
xducer_offset_from_bottom <- ncatt_get(ni, 'depth', 'xducer_offset_from_bottom')
bin_size <- ncatt_get(ni, 'depth', 'bin_size')
nc_close(ni)
adp <- oceSetMetadata(adp, 'creation_date', creation_date$value, note = NULL)
adp <- oceSetMetadata(adp, 'institution', data_origin$value, note = NULL)
adp <- oceSetMetadata(adp, 'time_coverage_start', time_coverage_start$value, note = NULL)
adp <- oceSetMetadata(adp, 'time_coverage_end', time_coverage_end$value, note = NULL)
adp <- oceSetMetadata(adp, 'inst_type', inst_type$value, note = NULL)
adp <- oceSetMetadata(adp, 'history', historyadp$value, note = NULL)
#deprecated - diana cardoso June 15 2018
#adp <- oceSetMetadata(adp, 'starting_water_layer', starting_water_layer$value)
#adp <- oceSetMetadata(adp, 'ending_water_layer', ending_water_layer$value)
#adp <- oceSetMetadata(adp, 'depth_note', depth_note$value)
# deprecated --- Diana Cardoso 06/01/2018
#adp <- oceSetMetadata(adp, 'transform', transform$value)
adp <- oceSetMetadata(adp, 'data_subtype', data_subtype$value, note = NULL)
adp <- oceSetMetadata(adp, 'coord_system', coord_system$value, note = NULL)
adp <- oceSetMetadata(adp, 'water_mass', water_mass$value, note = NULL)
#deprecated Diana Cardoso - June 15 2018
#adp <- oceSetMetadata(adp, 'pos_const', pos_const$value)
#adp <- oceSetMetadata(adp, 'depth_const', depth_const$value)
#adp <- oceSetMetadata(adp, 'drifter', drifter$value)
#adp <- oceSetMetadata(adp, 'composite', composite$value)
adp <- oceSetMetadata(adp, 'FillValue', FillValue$value, note = NULL)
adp <- oceSetMetadata(adp, 'experiment', experiment$value, note = NULL)
adp <- oceSetMetadata(adp, 'project', project$value, note = NULL)
adp <- oceSetMetadata(adp, 'description', description$value, note = NULL)
adp <- oceSetMetadata(adp, 'data_comment', data_comment$value, note = NULL)
adp <- oceSetMetadata(adp, 'fill_flag', fill_flag$value, note = NULL)
adp <- oceSetMetadata(adp, 'magnetic_variation', magnetic_variation$value, note = NULL)
adp <- oceSetMetadata(adp, 'delta_t_sec', delta_t_sec$value, note = NULL)
adp <- oceSetMetadata(adp, 'xducer_offset_from_bottom', xducer_offset_from_bottom$value, note = NULL)
adp <- oceSetMetadata(adp, 'bin_size', bin_size$value, note = NULL)
adp <- oceSetMetadata(adp, 'ping_interval', ping_interval$value, note = NULL)
adp <- oceSetMetadata(adp, 'sample_interval', pings_per_ensemble * ping_interval$value, note = NULL)
adp <- oceSetMetadata(adp, 'title', title$value, note = NULL)
#set metadata source
if (!is.null(raw)){
adp <- oceSetMetadata(adp, 'source', 'netCDF, Raw, ODF combined')
}else{
adp <- oceSetMetadata(adp, 'source', 'netCDF, ODF combined')
}
}
if(missing(ncin)){
warning('NC file not provided, object is missing metadata')
warning(
' please provide creation_date, start_time, stop_time, inst_type, history, , , , transform,
data_subtype, coord_system, water_mass, , , ,
var_fill, experiment, project, descript, data_cmnt, fill_flag, ,
magnetic_variation, , delta_t_sec, time_between_ping_groups, depth:
xducer_offset_from_bottom, depth: bin_size'
)
adp<- oceSetMetadata(adp, 'source', 'Raw, ODF combined')
}
if (!is.null(raw)){
#####pull data from raw file#####
a <- read.adp(raw)
BEAM_01 <- a[['a', 'numeric']][,,1]
BEAM_02 <- a[['a', 'numeric']][,,2]
BEAM_03 <- a[['a', 'numeric']][,,3]
BEAM_04 <- a[['a', 'numeric']][,,4]
PGDP_01 <- a[['g', 'numeric']][,,1]
PGDP_02 <- a[['g', 'numeric']][,,2]
PGDP_03 <- a[['g', 'numeric']][,,3]
CMAG_01 <- a[['q', 'numeric']][,,1]
CMAG_02 <- a[['q', 'numeric']][,,2]
CMAG_03 <- a[['q', 'numeric']][,,3]
CMAG_04 <- a[['q', 'numeric']][,,4]
PTCH <- a[['pitch']]
ROLL <- a[['roll']]
HGHT <- a[['distance']]
Tx <- a[['temperature']]
D <- swDepth(pressure = a[['pressure']], latitude = adp[['latitude']], eos = 'gsw')
HEAD <- a[['heading']]
PRES <- a[['pressure']]
SVEL <- a[['soundSpeed']]
#####limit dimensions to match odf files####
####apply time offset####
if (is.null(dt)){
t <- ( a[['time']] + (adp[['sample_interval']]/2))
a <- oceSetData(a, 'time', t)
}else{
t <- (a[['time']] + dt)
a <- oceSetData(a, 'time', t)
}
#limit by time
limitmat <- matrix(0, nrow = length(a[['time']]), ncol = length(a[['distance']]))
limitvec <- matrix(0, ncol = length(a[['time']]))
#create 'flag mask' where 4 = bad value (outside bounds)
limitmat[as.POSIXct(a[['time']], tz = 'UTC') < as.POSIXct(adp[['time']][[1]], tz = 'UTC') | as.POSIXct(a[['time']], tz = 'UTC') > as.POSIXct(adp[['time']][[length(adp[['time']])]], tz = 'UTC')] <- 4
limitvec[as.POSIXct(a[['time']], tz = 'UTC') < as.POSIXct(adp[['time']][[1]], tz = 'UTC') | as.POSIXct(a[['time']], tz = 'UTC') > as.POSIXct(adp[['time']][[length(adp[['time']])]], tz = 'UTC')] <- 4
#limit time variable
a[['time']][limitvec == 4] <- NA
#check in progress
if(length(na.omit(a[['time']])) != length(adp[['time']])){
warning("time vectors do not match in length, attempt to rectify, please confirm!")
l <- length(adp[['time']])
tt <- na.omit(a[['time']])
length(tt) <- l
tt[l] <- adp[['time']][l]
g <- grep(limitvec, pattern = 4)
b <- g[ g > 0.5*length(limitvec)][1]
limitvec[b] <- 0
limitmat[b, ] <- 0
# p <- length(limitvec[1:(0.5*length(limitvec))][limitvec == 4])
a <- oceSetData(a, 'time', tt)
# o <- p+l
# browser()
# limitvec[o] <- 0
# limitmat[o,] <- 0
}
#limit other transferable data
PTCH[limitvec == 4] <- NA
ROLL[limitvec == 4] <- NA
Tx[limitvec == 4] <- NA
D[limitvec == 4] <- NA
HEAD[limitvec == 4] <- NA
PRES[limitvec == 4] <- NA
SVEL[limitvec == 4] <- NA
BEAM_01[limitmat == 4] <- NA
BEAM_02[limitmat == 4] <- NA
BEAM_03[limitmat == 4] <- NA
BEAM_04[limitmat == 4] <- NA
PGDP_01[limitmat == 4] <- NA
PGDP_02[limitmat == 4] <- NA
PGDP_03[limitmat == 4] <- NA
CMAG_01[limitmat == 4] <- NA
CMAG_02[limitmat == 4] <- NA
CMAG_03[limitmat == 4] <- NA
CMAG_04[limitmat == 4] <- NA
####Check distances match####
if (length(a[['distance']]) != length(adp[['distance']])){
warning('ADP DISTANCE VECTORS DO NOT MATCH, DOUBLE CHECK FOR MISSING BINS!')
}
#####insert into adp####
#create an array
x <- nrow(adp[['a']])
y <- ncol(adp[['a']])
z <- 4
aa <- array(dim = c(x, y, z))
#combine beams into a single array using dimensions of odf data
aa[,,1] <- na.omit(BEAM_01[, 1:length(adp[['distance']])])
aa[,,2] <- na.omit(BEAM_02[, 1:length(adp[['distance']])])
aa[,,3] <- na.omit(BEAM_03[, 1:length(adp[['distance']])])
aa[,,4] <- na.omit(BEAM_04[, 1:length(adp[['distance']])])
#put array into adp object
adp <- oceSetData(adp, 'a', aa, note = NULL)
#create a array
l <- nrow(adp[['q']])
m <- ncol(adp[['q']])
n <- 4
gg <- array(dim = c(l, m, n))
#combine beams into a single array using dimensions of odf data
gg[,,1] <- na.omit(PGDP_01[, 1:length(adp[['distance']])])
gg[,,2] <- na.omit(PGDP_02[, 1:length(adp[['distance']])])
gg[,,3] <- na.omit(PGDP_03[, 1:length(adp[['distance']])])
gg[,,4] <- adp[['q', 'numeric']]
#put array into adp object
adp <- oceSetData(adp, 'g', gg, note = NULL)
#add correlation magnitude array
qq <- array(dim = c(l, m, n))
qq[,,1] <- na.omit(CMAG_01[, 1:length(adp[['distance']])])
qq[,,2] <- na.omit(CMAG_02[, 1:length(adp[['distance']])])
qq[,,3] <- na.omit(CMAG_03[, 1:length(adp[['distance']])])
qq[,,4] <- na.omit(CMAG_04[, 1:length(adp[['distance']])])
adp <- oceSetData(adp, 'q', qq, note = NULL)
#insert other data
adp <- oceSetData(adp, 'pitch', na.omit(PTCH), note = NULL)
adp <- oceSetData(adp, 'roll', na.omit(ROLL), note = NULL)
adp <- oceSetData(adp, 'hght', (HGHT[ 1:length(adp[['distance']])]), note = NULL)
adp <- oceSetData(adp, 'temperature', na.omit(Tx), note = NULL)
adp <- oceSetData(adp, 'depth', na.omit(D), note = NULL)
adp <- oceSetData(adp, 'heading', na.omit(HEAD), note = NULL)
adp <- oceSetData(adp, 'pressure', na.omit(PRES), note = NULL)
adp <- oceSetData(adp, 'soundSpeed', na.omit(SVEL), note = NULL)
}else{
l <- matrix(NA, ncol = length(adp[['time']]))
if (depth == TRUE){
adp <- oceSetData(adp, 'depth', D)
} else{
adp <- oceSetData(adp, 'depth', l, note = NULL)
}
adp <- oceSetData(adp, 'temperature', Tx)
#match dims with NAs
aa <- array(NA, dim = list(length(adp[['a']][,1]), length(adp[['a']][1,]), 3))
ar <- abind(aa, adp[['a']], along = 3)
adp <- oceSetData(adp, 'a', ar)
gg <- array(NA, dim = list(length(adp[['q']][,1]), length(adp[['q']][1,]), 3))
gr <- abind(gg, adp[['q']], along = 3)
adp <- oceSetData(adp, 'g', gr)
qq <- array(NA, dim = dim(adp[['g']]))
adp <- oceSetData(adp, 'q', qq)
adp <- oceSetData(adp, 'pitch', l, note = NULL)
adp <- oceSetData(adp, 'roll', l, note = NULL)
adp <- oceSetData(adp, 'hght', l, note = NULL)
adp <- oceSetData(adp, 'heading',l, note = NULL)
adp <- oceSetData(adp, 'pressure', l, note = NULL)
adp <- oceSetData(adp, 'soundSpeed',l, note = NULL)
}
####set sensor_depth
adp <- oceSetMetadata(adp, 'sensor_depth', mean(adp[['depth']], na.rm= TRUE), note = NULL)
###fix event qualifier pulled from odf
adp <- oceSetMetadata(adp, 'eventQualifier', adp[['serialNumber']], note = NULL)
##update processingLog
adp@processingLog <- processingLogAppend(adp@processingLog, 'adp object combined from raw file, odf files and netCDF file, metadata and varibale data pulled from various sources')
return(adp)
}
####create netCDF file from combined adp source####
#' NetCDF creation from adp object
#'
#'@family NC
#'
#' @description Creates standardized netCDF file from adp object (produced from
#' \code{\link[ADCP:adpCombine]{adpCombine}})
#'
#' Standardized name of file can be created with:
#' (\code{\link[ADCP:name.file]{name.file}})
#'
#' product will meet CF compliance, ERDDAP standards, BODC/SDN, and DFO/MEDS
#' standards
#'
#' @param adp an adp object
#' @param name text string which will name netCDF file
#'
#' @export
#'
adpNC <- function(adp, name){
require(lubridate)
if (!inherits(adp, "adp")){
stop("method is only for objects of class '", "adp", "'")
}
if(missing(name)){
name <- paste('MADCP', adp[['experiment']], adp[['station']], adp[['serial_number']], adp[['delta_t_sec']], sep = '_')
}
#file name and path
ncpath <- "./"
ncfname <- paste(ncpath, name, ".nc", sep = "")
####setting dimensions and definitions####
#dimension variables from adp object
time <- as.POSIXct(adp[['time']], tz = 'UTC', origin = '1970-01-01 00:00:00')
dist <- adp[['distance', 'numeric']]
lon <- adp[['longitude']]
lat <- adp[['latitude']]
#create dimensions
timedim <- ncdim_def("time", "seconds since 1970-01-01T00:00:00Z", as.double(time)) #time formatting FIX
distdim <- ncdim_def("distance", "metres", as.double(dist))
stationdim <- ncdim_def("station", "counts", as.numeric(adp[['station']]))
londim <- ncdim_def("lon", "degrees_east" , as.double(lon))
latdim <- ncdim_def("lat", "degrees_north", as.double(lat))
dimnchar <- ncdim_def('nchar', '', 1:23, create_dimvar = FALSE)
#set fill value
FillValue <- 1e35
#####define variables####
dlname <- 'lon'
lon_def <- ncvar_def(longname= "longitude", units = 'degrees_east', dim = stationdim, name = dlname, prec = 'double')
dlname <- 'lat'
lat_def <- ncvar_def( longname = 'latitude', units = 'degrees_north', dim = stationdim, name = dlname, prec = 'double')
dlname <- "eastward_sea_water_velocity"
u_def <- ncvar_def("EWCT", "m/sec", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "northward_sea_water_velocity"
v_def <- ncvar_def("NSCT", "m/sec", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "upward_sea_water_velocity"
w_def <- ncvar_def("VCSP", "m/sec", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "time_02"
t_def <- ncvar_def("ELTMEP01", "seconds since 1970-01-01T00:00:00Z", list( stationdim, timedim), FillValue, dlname, prec = "double")
dlname <- "error_velocity_in_sea_water"
e_def <- ncvar_def("ERRV", "m/sec", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "ADCP_echo_intensity_beam_1"
b1_def <- ncvar_def("BEAM_01", "counts", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "ADCP_echo_intensity_beam_2"
b2_def <- ncvar_def("BEAM_02", "counts", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "ADCP_echo_intensity_beam_3"
b3_def <- ncvar_def("BEAM_03", "counts", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "ADCP_echo_intensity_beam_4"
b4_def <- ncvar_def("BEAM_04", "counts", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "ADCP_correlation_magnitude_beam_1"
cm1_def <- ncvar_def("CMAG_01", "counts", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "ADCP_correlation_magnitude_beam_2"
cm2_def <- ncvar_def("CMAG_02", "counts", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "ADCP_correlation_magnitude_beam_3"
cm3_def <- ncvar_def("CMAG_03", "counts", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "ADCP_correlation_magnitude_beam_4"
cm4_def <- ncvar_def("CMAG_04", "counts", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "percent_good_beam_1"
pg1_def <- ncvar_def("PGDP_01", "percent", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "percent_good_beam_2"
pg2_def <- ncvar_def("PGDP_02", "percent", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "percent_good_beam_3"
pg3_def <- ncvar_def("PGDP_03", "percent", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "percent_good_beam_4"
pg4_def <- ncvar_def("PGDP_04", "percent", list(timedim, distdim, stationdim), FillValue, dlname, prec = "float")
dlname <- "pitch"
p_def <- ncvar_def("PTCH", "degrees", list( timedim, stationdim), FillValue, dlname, prec = "float")
dlname <- "roll"
r_def <- ncvar_def("ROLL", "degrees", list( timedim , stationdim), FillValue, dlname, prec = "float")
dlname <- "average height of sea surface above each bin"
hght_def <- ncvar_def("hght", "m", list( distdim, stationdim ), FillValue, dlname, prec = "float")
dlname <- "ADCP Transducer Temp."
Tx_def <- ncvar_def("Tx", "degrees", list( timedim , stationdim), FillValue, dlname, prec = "float")
dlname <- "instrument depth"
D_def <- ncvar_def("DEPH", "m", list(timedim, stationdim), FillValue, dlname, prec = "float")
dlname <- "heading"
head_def <- ncvar_def("HEAD", "degrees", list(timedim, stationdim), FillValue, dlname, prec = "float")
dlname <- "pressure"
pres_def <- ncvar_def("PRES", "decibars", list(timedim, stationdim), FillValue, dlname, prec = "float")
dlname <- "speed of sound"
svel_def <- ncvar_def("SVEL", "m/s", list(timedim, stationdim), FillValue, dlname, prec = "float")
dlname <- "time_string"
ts_def <- ncvar_def("DTUT8601", units = "",dim = list( dimnchar, timedim), missval = NULL, name = dlname, prec = "char")
#####write out definitions to new nc file####
ncout <- nc_create(ncfname, list(u_def, v_def, w_def, e_def, t_def, b1_def, b2_def, b3_def, b4_def, cm1_def, cm2_def, cm3_def, cm4_def, pg1_def, pg2_def, pg3_def, pg4_def, p_def, r_def, hght_def, Tx_def, D_def, lon_def, lat_def, head_def, pres_def, svel_def, ts_def), force_v4 = TRUE)
ncvar_put(ncout, u_def, adp[['v']][,,1])
ncvar_put(ncout, v_def, adp[['v']][,,2])
ncvar_put(ncout, w_def, adp[['v']][,,3])
ncvar_put(ncout, e_def, adp[['v']][,,4])
ncvar_put(ncout, t_def, as.POSIXct(adp[['time']], tz = 'UTC', origin = '1970-01-01 00:00:00'))
ncvar_put(ncout, lon_def, adp[['longitude']])
ncvar_put(ncout, lat_def, adp[['latitude']])
ncvar_put(ncout, b1_def, adp[['a', 'numeric']][,,1])
ncvar_put(ncout, b2_def, adp[['a', 'numeric']][,,2])
ncvar_put(ncout, b3_def, adp[['a', 'numeric']][,,3])
ncvar_put(ncout, b4_def, adp[['a', 'numeric']][,,4])
ncvar_put(ncout, pg1_def, adp[['g', 'numeric']][,,1])
ncvar_put(ncout, pg2_def, adp[['g', 'numeric']][,,2])
ncvar_put(ncout, pg3_def, adp[['g', 'numeric']][,,3])
ncvar_put(ncout, pg4_def, adp[['g', 'numeric']][,,4])
ncvar_put(ncout, cm1_def, adp[['q', 'numeric']][,,1])
ncvar_put(ncout, cm2_def, adp[['q', 'numeric']][,,2])
ncvar_put(ncout, cm3_def, adp[['q', 'numeric']][,,3])
ncvar_put(ncout, cm4_def, adp[['q', 'numeric']][,,4])
ncvar_put(ncout, p_def, adp[['pitch']])
ncvar_put(ncout, r_def, adp[['roll']])
ncvar_put(ncout, hght_def, ((adp[['sensor_depth']]- adp[['bin1Distance']]) - adp[['distance']]))
ncvar_put(ncout, Tx_def, adp[['temperature']])
ncvar_put(ncout, D_def, adp[['depth']])
ncvar_put(ncout, head_def, adp[['heading']])
ncvar_put(ncout, pres_def, adp[['pressure']])
ncvar_put(ncout, svel_def, adp[['soundSpeed']])
ncvar_put(ncout, ts_def, adp[['time']])
####metadata####
####dimensions####
ncatt_put(ncout, 'station', attname = 'cf_role',attval = 'timeseries_id')
ncatt_put(ncout, 'station', 'longitude', adp[['longitude']])
ncatt_put(ncout, 'station', 'latitiude', adp[['latitude']])
ncatt_put(ncout, 'time', attname = 'cf_role', attval = 'profile_id')
ncatt_put(ncout, 'station', 'standard_name', 'platform_name')
ncatt_put(ncout, 'time' , 'calendar', 'gregorian')
ncatt_put(ncout, 'time_string', 'note', 'time values as ISO8601 string, YY-MM-DD hh:mm:ss')
ncatt_put(ncout, 'time_string', 'time_zone', 'UTC')
ncatt_put(ncout, 'distance', 'axis', 'Z')
ncatt_put(ncout, 'hght', 'axis', 'Z')
ncatt_put(ncout, 'hght', 'positive', 'down')
ncatt_put(ncout, 'time' , 'axis', 'T')
ncatt_put(ncout, 'lat', 'axis', 'Y')
ncatt_put(ncout, 'lon', 'axis', 'X')
####global####
ncatt_put(ncout, 0, "Conventions", 'CF-1.6')
ncatt_put(ncout, 0, "creator_institution", adp[['institution']])
ncatt_put(ncout, 0, 'acknowledgement', adp[['acknowledgement']] )
ncatt_put(ncout, 0, 'comment', adp[['comment']])
ncatt_put(ncout, 0, 'cruise_description', adp[['cruise_description']])
ncatt_put(ncout, 0, 'date_created', as.character(Sys.Date())) #issue with sys date being output as numeric
ncatt_put(ncout, 0, 'keywords', 'Oceans > Ocean Circulation > Ocean Currents')
ncatt_put(ncout, 0, 'keywords_vocabulary', 'GCMD Science Keywords')
ncatt_put(ncout, 0, 'model', adp[['model']])
ncatt_put(ncout, 0, 'sampling_interval', adp[['samplingInterval']])
ncatt_put(ncout, 0, 'standard_name_vocabulary', 'CF v.52')
ncatt_put(ncout, 0, 'title', adp[['title']])
#ncatt_put(ncout, 0, 'blanking_distance', adp[['blanking_distance']])
ncatt_put(ncout, 0, 'country_code', adp[['countryInstituteCode']])
ncatt_put(ncout, 0, 'cruise_number', adp[['cruiseNumber']])
ncatt_put(ncout, 0, 'summary', adp[['summary']])
ncatt_put(ncout, 0, "mooring_number", adp[['station']])
#Note from Mathieu: naming authority should be reverse DNS naming scheme (eg. gov.noaa.ncei), unable to find applicable name for BIO - DFO, left blank for now
# ncatt_put(ncout, 0, "naming_authority", 'MEDS, BODC, CF')
ncatt_put(ncout, 0, "comment", "Data has been combined from archived ODF files")
#FIX ME CHANGE TO ISO8601
ncatt_put(ncout, 0, "time_coverage_duration", paste0("P", round(tail(adp[['time']], n = 1) - adp[['time']][[1]], digits = 3), "D"))
# ncatt_put(ncout, 0, "time_coverage_duration_units", "days") #unnessecary with time_coverage_duration format
ncatt_put(ncout, 0, "cdm_data_type", "station")
ncatt_put(ncout, 0, "sea_name", adp[['sea_name']])
ncatt_put(ncout, 0, "publisher_name", adp[['publisher_name']])
ncatt_put(ncout, 0, "publisher_email", "BIO.Datashop@dfo-mpo.gc.ca")
ncatt_put(ncout, 0, "processing_history", adp[['processing_history']])
# deprecated --- Diana Cardoso 06/01/2018
#ncatt_put(ncout, 0, "deployment_date", adp[['deployment_date']])
#ncatt_put(ncout, 0, "recovery_date", adp[['recovery_date']])
ncatt_put(ncout, 0, "firmware_version", adp[['firmware_version']])
ncatt_put(ncout, 0, "frequency", paste0(adp[['frequency']], " Khz"))
ncatt_put(ncout, 0, "beam_pattern", adp[['beam_pattern']])
ncatt_put(ncout, 0, "janus", adp[['janus']])
ncatt_put(ncout, 0, "pings_per_ensemble", adp[['pings_per_ensemble']])
ncatt_put(ncout, 0, "valid_correlation_range", adp[['valid_correlation_range']])
ncatt_put(ncout, 0,"minmax_percent_good", "0-100")
ncatt_put(ncout, 0, "error_velocity_threshold", paste0(adp[['error_velocity_threshold']], " mm/s"))
ncatt_put(ncout, 0, "transmit_pulse_length_cm", adp[['transmit_pulse_length_cm']])
ncatt_put(ncout, 0, "false_target_reject_values", adp[['false_target_reject_values']])
ncatt_put(ncout, 0, "serial_number", adp[['serial_number']])
# deprecated --- Diana Cardoso 06/01/2018
#ncatt_put(ncout, 0, "transform", adp[['transform']])
ncatt_put(ncout, 0, "data_type", adp[['data_type']])
ncatt_put(ncout, 0, "data_subtype", adp[['data_subtype']])
ncatt_put(ncout, 0, "coord_system", adp[['coord_system']])
ncatt_put(ncout, 0, "longitude", adp[['longitude']])
ncatt_put(ncout, 0, "latitude", adp[['latitude']])
ncatt_put(ncout, 0, "magnetic_variation", adp[['magnetic_variation']])
ncatt_put(ncout, 0, "platform", adp[['ship']])
ncatt_put(ncout, 0, "sounding", adp[['sounding']])
ncatt_put(ncout, 0, "chief_scientist", adp[['scientist']])
ncatt_put(ncout, 0, "water_depth", adp[['sounding']])
ncatt_put(ncout, 0, "delta_t_sec",adp[['delta_t_sec']])
ncatt_put(ncout, 0, "pred_accuracy", adp[['pred_accuracy']])
ncatt_put(ncout, 0, "history", adp[['history']])
#deprecated Diana Cardoso- June 15 2018
#ncatt_put(ncout, 0, "starting_water_layer", adp[['starting_water_layer']])
#ncatt_put(ncout, 0, "ending_water_layer", adp[['ending_water_layer']])
#ncatt_put(ncout, 0, "pos_const", adp[['pos_const']])
#ncatt_put(ncout, 0, "depth_const", adp[['depth_const']])
#ncatt_put(ncout, 0, "drifter", adp[['drifter']])
ncatt_put(ncout, 0, "experiment", adp[['experiment']])
ncatt_put(ncout, 0, "cruise_name", adp[['cruise']])
####variables####
ncatt_put(ncout, "DEPH", "xducer_offset_from_bottom", adp[['xducer_offset_from_bottom']])
ncatt_put(ncout, "DEPH", "bin_size", adp[['bin_size']])
ncatt_put(ncout, "EWCT", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "EWCT", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "EWCT", "serial_number", adp[['serial_number']])
ncatt_put(ncout, "NSCT", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "NSCT", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "NSCT", "serial_number", adp[['serial_number']])
ncatt_put(ncout, "VCSP", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "VCSP", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "VCSP", "serial_number", adp[['serial_number']])
ncatt_put(ncout, "ERRV", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "ERRV", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "ERRV", "serial_number", adp[['serial_number']])
ncatt_put(ncout, "BEAM_01", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "BEAM_01", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "BEAM_01", "serial_number", adp[['serial_number']])
ncatt_put(ncout, "BEAM_02", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "BEAM_02", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "BEAM_02", "serial_number", adp[['serial_number']])
ncatt_put(ncout, "BEAM_03", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "BEAM_03", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "BEAM_03", "serial_number", adp[['serial_number']])
ncatt_put(ncout, "BEAM_04", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "BEAM_04", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "BEAM_04", "serial_number", adp[['serial_number']])
ncatt_put(ncout, "CMAG_01", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "CMAG_01", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "CMAG_01", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "CMAG_02", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "CMAG_02", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "CMAG_02", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "CMAG_03", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "CMAG_03", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "CMAG_03", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "CMAG_04", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "CMAG_04", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "CMAG_04", "serial_number", adp[['serialNumber']])
ncatt_put(ncout, "PGDP_01", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "PGDP_01", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "PGDP_01", "serial_number", adp[['serial_number']])
ncatt_put(ncout, "PGDP_02", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "PGDP_02", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "PGDP_02", "serial_number", adp[['serial_number']])
ncatt_put(ncout, "PGDP_03", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "PGDP_03", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "PGDP_03", "serial_number", adp[['serial_number']])
ncatt_put(ncout, "PGDP_04", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "PGDP_04", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "PGDP_04", "serial_number", adp[['serial_number']])
ncatt_put(ncout, "EWCT", "generic_name", "u")
ncatt_put(ncout, "NSCT", "generic_name", "v")
ncatt_put(ncout, "VCSP", "generic_name", "w")
ncatt_put(ncout, "ERRV", "generic_name", "w") #issue in current NC protocol
ncatt_put(ncout, "BEAM_01", "generic_name", "AGC")
ncatt_put(ncout, "BEAM_02", "generic_name", "AGC")
ncatt_put(ncout, "BEAM_03", "generic_name", "AGC")
ncatt_put(ncout, "BEAM_04", "generic_name", "AGC")
ncatt_put(ncout, "CMAG_01", "generic_name", "CM")
ncatt_put(ncout, "CMAG_02", "generic_name", "CM")
ncatt_put(ncout, "CMAG_03", "generic_name", "CM")
ncatt_put(ncout, "CMAG_04", "generic_name", "CM")
ncatt_put(ncout, "PGDP_01", "generic_name", "PGd")
ncatt_put(ncout, "PGDP_02", "generic_name", "PGd")
ncatt_put(ncout, "PGDP_03", "generic_name", "PGd")
ncatt_put(ncout, "PGDP_04", "generic_name", "PGd")
ncatt_put(ncout, "hght", "generic_name", "height")
ncatt_put(ncout, "hght", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "hght", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "hght", "serial_number", adp[['serial_number']])
ncatt_put(ncout, "DEPH", "generic_name", "depth")
ncatt_put(ncout, "DEPH", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "DEPH", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "DEPH", "serial_number", adp[['serial_number']])
ncatt_put(ncout, "Tx", "generic_name", "temp")
ncatt_put(ncout, "Tx", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "Tx", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "Tx", "serial_number", adp[['serial_number']])
ncatt_put(ncout, "HEAD", "generic_name", "heading")
ncatt_put(ncout, "HEAD", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "HEAD", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "HEAD", "serial_number", adp[['serial_number']])
ncatt_put(ncout, "PRES", "generic_name", "pressure")
ncatt_put(ncout, "PRES", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "PRES", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "PRES", "serial_number", adp[['serial_number']])
ncatt_put(ncout, "SVEL", "generic_name", "sound speed")
ncatt_put(ncout, "SVEL", "sensor_type", adp[['inst_type']])
ncatt_put(ncout, "SVEL", "sensor_depth", adp[['sensor_depth']])
ncatt_put(ncout, "SVEL", "serial_number", adp[['serial_number']])
####CF conventions & BODC standards####
ncatt_put(ncout, 0, 'Conventions', 'CF-1.6')
ncatt_put(ncout, 0, "creator_type", "person")
ncatt_put(ncout, 0, "program", adp[['description']])
ncatt_put(ncout, 0, "time_coverage_start", strftime(adp[['time']][[1]] , "%Y-%m-%dT%H:%M:%S%z", tz = 'UTC'))
ncatt_put(ncout, 0, "time_coverage_end", strftime(adp[['time']][[length(adp[['time']])]] , "%Y-%m-%dT%H:%M:%S%z", tz = 'UTC'))
ncatt_put(ncout, 0, "geospatial_lat_min", adp[['latitude']])
ncatt_put(ncout, 0, "geospatial_lat_max", adp[['latitude']])
ncatt_put(ncout, 0, "geospatial_lat_units", "degrees_north")
ncatt_put(ncout, 0, "geospatial_lon_min", adp[['longitude']])
ncatt_put(ncout, 0, "geospatial_lon_max", adp[['longitude']])
ncatt_put(ncout, 0, "geospatial_lon_units", "degrees_east")
if (length(grep(adp[['orientation']], pattern = "*down*", ignore.case = TRUE)) >0){
ncatt_put(ncout, 0, "geospatial_vertical_min", adp[['sensor_depth']] )
ncatt_put(ncout, 0, "geospatial_vertical_max", adp[['sensor_depth']] - max(adp[['distance']], na.rm = TRUE))
}
if (length(grep(adp[['orientation']], pattern = "*up*", ignore.case = TRUE)) >0){
ncatt_put(ncout, 0, "geospatial_vertical_min", adp[['sensor_depth']] - max(adp[['distance']], na.rm = TRUE))
ncatt_put(ncout, 0, "geospatial_vertical_max", adp[['sensor_depth']])
}
ncatt_put(ncout, 0, "geospatial_vertical_units", "metres")
ncatt_put(ncout, 0, "geospatial_vertical_positive", 'down')
#Notes from M.O/D.C project should be filled out with more specific name in future, unable to determine for archived files
# ncatt_put(ncout, 0, "project", adp[['project']])
#Notes from Mathieu O. - this is better as individual variable attribute
#ncatt_put(ncout,0, "_FillValue", "1e35")
ncatt_put(ncout, 0, "featureType", "timeSeriesProfile")
ncatt_put(ncout, 0, "date_modified", date())
#added meta to meet conventions (not found in archive) #to be inserted manually
#??????
if(!is.null(adp[['sea_name']])){
ncatt_put(ncout, 0, "sea_name", adp[['sea_name']])
}
if(!is.null(adp[['processing_history']])){
ncatt_put(ncout, 0, "processing_history", adp[['processing_history']])
}
ncatt_put(ncout, 0, "source", "R code: adcpProcess, github:") ##update with link to code
if(!is.null(adp[['publisher_name']])){
ncatt_put(ncout, 0, "publisher_name", adp[['publisher_name']])
}
if(!is.null(adp[['publisher_email']])){
ncatt_put(ncout, 0, "publisher_email", adp[['publisher_email']])
}
ncatt_put(ncout, 0, "institution", "Bedford Institute of Oceanography, DFO")
####BODC P01 names####
ncatt_put(ncout, "EWCT", "sdn_parameter_urn", "SDN:P01::LCEWAP01")
ncatt_put(ncout, "NSCT", "sdn_parameter_urn", "SDN:P01::LCNSAP01")
ncatt_put(ncout, "VCSP", "sdn_parameter_urn", "SDN:P01::LRZAAP01")
ncatt_put(ncout, "ERRV", "sdn_parameter_urn", "SDN:P01::LERRAP01")
ncatt_put(ncout, "BEAM_01", "sdn_parameter_urn", "SDN:P01::TNIHCE01")
ncatt_put(ncout, "BEAM_02", "sdn_parameter_urn", "SDN:P01::TNIHCE02")
ncatt_put(ncout, "BEAM_03", "sdn_parameter_urn", "SDN:P01::TNIHCE03")
ncatt_put(ncout, "BEAM_04", "sdn_parameter_urn", "SDN:P01::TNIHCE04")
ncatt_put(ncout, "PGDP_01", "sdn_parameter_urn", "SDN:P01::PCGDAP00")
ncatt_put(ncout, "PGDP_02", "sdn_parameter_urn", "SDN:P01::PCGDAP02")
ncatt_put(ncout, "PGDP_03", "sdn_parameter_urn", "SDN:P01::PCGDAP03")
ncatt_put(ncout, "PGDP_04", "sdn_parameter_urn", "SDN:P01::PCGDAP04")
#ncatt_put(ncout, "hght", "sdn_parameter_urn", "SDN:P01::")
ncatt_put(ncout, "DEPH", "sdn_parameter_urn", "SDN:P01::ADEPZZ01")
ncatt_put(ncout, "Tx", "sdn_parameter_urn", "SDN:P01::TEMPPR01")
ncatt_put(ncout, "ELTMEP01", "sdn_parameter_urn", "SDN:P01::ELTMEP01")
ncatt_put(ncout, "PTCH", "sdn_parameter_urn", "SDN:P01::PTCHEI01")
ncatt_put(ncout, "ROLL", "sdn_parameter_urn", "SDN:P01::ROLLEI01")
ncatt_put(ncout, "lon", "sdn_parameter_urn", "SDN:P01::ALONZZ01")
ncatt_put(ncout, "lat", "sdn_parameter_urn", "SDN:P01::ALATZZ01")
ncatt_put(ncout, "HEAD", "sdn_parameter_urn", "SDN:P01::HEADCM01")
ncatt_put(ncout, "PRES", "sdn_parameter_urn", "SDN:P01::PRESPR01")
ncatt_put(ncout, "SVEL", "sdn_parameter_urn", "SDN:P01::SVELCV01")
ncatt_put(ncout, "time_string", "sdn_parameter_urn", "SDN:P01::DTUT8601")
ncatt_put(ncout, "EWCT", "sdn_parameter_name", "Eastward current velocity (Eulerian) in the water body by moored acoustic doppler current profiler (ADCP)")
ncatt_put(ncout, "NSCT", "sdn_parameter_name", "Northward current velocity (Eulerian) in the water body by moored acoustic doppler current profiler (ADCP)")
ncatt_put(ncout, "VCSP", "sdn_parameter_name", "Upward current velocity in the water body by moored acoustic doppler current profiler (ADCP)")
ncatt_put(ncout, "ERRV", "sdn_parameter_name", "Current velocity error in the water body by moored acoustic doppler current profiler (ADCP)")
ncatt_put(ncout, "BEAM_01", "sdn_parameter_name", "Echo intensity from the water body by moored acoustic doppler current profiler (ADCP) beam 1")
ncatt_put(ncout, "BEAM_02", "sdn_parameter_name", "Echo intensity from the water body by moored acoustic doppler current profiler (ADCP) beam 2")
ncatt_put(ncout, "BEAM_03", "sdn_parameter_name", "Echo intensity from the water body by moored acoustic doppler current profiler (ADCP) beam 3")
ncatt_put(ncout, "BEAM_04", "sdn_parameter_name", "Echo intensity from the water body by moored acoustic doppler current profiler (ADCP) beam 4")
ncatt_put(ncout, "PGDP_01", "sdn_parameter_name", "Acceptable proportion of signal returns by moored acoustic doppler current profiler (ADCP) beam 1")
ncatt_put(ncout, "PGDP_02", "sdn_parameter_name", "Acceptable proportion of signal returns by moored acoustic doppler current profiler (ADCP) beam 2")
ncatt_put(ncout, "PGDP_03", "sdn_parameter_name", "Acceptable proportion of signal returns by moored acoustic doppler current profiler (ADCP) beam 3")
ncatt_put(ncout, "PGDP_04", "sdn_parameter_name", "Acceptable proportion of signal returns by moored acoustic doppler current profiler (ADCP) beam 4")
ncatt_put(ncout, "DEPH", "sdn_parameter_name", "Depth below surface of the water body")
ncatt_put(ncout, "Tx", "sdn_parameter_name", "Temperature of the water body")
ncatt_put(ncout, "PTCH", "sdn_parameter_name", "Orientation (pitch) of measurement platform by inclinometer")
ncatt_put(ncout, "ROLL", "sdn_parameter_name", "Orientation (roll angle) of measurement platform by inclinometer (second sensor)")
ncatt_put(ncout, "lon", "sdn_parameter_name", "Longitude east")
ncatt_put(ncout, "lat", "sdn_parameter_name", "Latitude north")
ncatt_put(ncout, "HEAD", "sdn_parameter_name", "Orientation (horizontal relative to true north) of measurement device {heading}")
ncatt_put(ncout, "PRES", "sdn_parameter_name", "Pressure (spatial co-ordinate) exerted by the water body by profiling pressure sensor and corrected to read zero at sea level")
ncatt_put(ncout, "SVEL", "sdn_parameter_name", "Sound velocity in the water body by computation from temperature and salinity by unspecified algorithm")
ncatt_put(ncout, 'ELTMEP01', "sdn_parameter_name", "Elapsed time (since 1970-01-01T00:00:00Z)")
ncatt_put(ncout, 'time_string', "sdn_parameter_name", "String corresponding to format 'YYYY-MM-DDThh:mm:ss.sssZ' or other valid ISO8601 string")
ncatt_put(ncout, "EWCT", "sdn_uom_urn", "SDN:P06::UVAA")
ncatt_put(ncout, "NSCT", "sdn_uom_urn", "SDN:P06::UVAA")
ncatt_put(ncout, "VCSP", "sdn_uom_urn", "SDN:P06::UVAA")
ncatt_put(ncout, "ERRV", "sdn_uom_urn", "SDN:P06::UVAA")
ncatt_put(ncout, "BEAM_01", "sdn_uom_urn", "SDN:P06::UCNT")
ncatt_put(ncout, "BEAM_02", "sdn_uom_urn", "SDN:P06::UCNT")
ncatt_put(ncout, "BEAM_03", "sdn_uom_urn", "SDN:P06::UCNT")
ncatt_put(ncout, "BEAM_04", "sdn_uom_urn", "SDN:P06::UCNT")
ncatt_put(ncout, "PGDP_01", "sdn_uom_urn", "SDN:P06::UPCT")
ncatt_put(ncout, "PGDP_02", "sdn_uom_urn", "SDN:P06::UPCT")
ncatt_put(ncout, "PGDP_03", "sdn_uom_urn", "SDN:P06::UPCT")
ncatt_put(ncout, "PGDP_04", "sdn_uom_urn", "SDN:P06::UPCT")
ncatt_put(ncout, "hght", "sdn_uom_urn", "SDN:P06::ULAA")
ncatt_put(ncout, "DEPH", "sdn_uom_urn", "SDN:P06::ULAA")
ncatt_put(ncout, "Tx", "sdn_uom_urn", "SDN:P06::UPAA")
ncatt_put(ncout, "PTCH", "sdn_uom_urn", "SDN:P06:UAAA")
ncatt_put(ncout, "ROLL", "sdn_uom_urn", "SDN:P06:UAAA")
ncatt_put(ncout, "lon", "sdn_uom_urn", "SDN:P06::DEGE")
ncatt_put(ncout, "lat", "sdn_uom_urn", "SDN:P06::DEGN")
ncatt_put(ncout, "HEAD", "sdn_uom_urn", "SDN:P06::UAAA")
ncatt_put(ncout, "PRES", "sdn_uom_urn", "SDN:P06::UPDB")
ncatt_put(ncout, "SVEL", "sdn_uom_urn", "SDN:P06::UVAA")
ncatt_put(ncout, "ELTMEP01", "sdn_uom_urn", "SDN:P06::UTBB")
ncatt_put(ncout, "time_string", "sdn_uom_urn", "SDN:P06::TISO")
ncatt_put(ncout, "EWCT", "sdn_uom_name", "Metres per second")
ncatt_put(ncout, "NSCT", "sdn_uom_name", "Metres per second")
ncatt_put(ncout, "VCSP", "sdn_uom_name", "Metres per second")
ncatt_put(ncout, "ERRV", "sdn_uom_name", "Metres per second")
ncatt_put(ncout, "BEAM_01", "sdn_uom_name", "Counts")
ncatt_put(ncout, "BEAM_02", "sdn_uom_name", "Counts")
ncatt_put(ncout, "BEAM_03", "sdn_uom_name", "Counts")
ncatt_put(ncout, "BEAM_04", "sdn_uom_name", "Counts")
ncatt_put(ncout, "PGDP_01", "sdn_uom_name", "Percent")
ncatt_put(ncout, "PGDP_02", "sdn_uom_name", "Percent")
ncatt_put(ncout, "PGDP_03", "sdn_uom_name", "Percent")
ncatt_put(ncout, "PGDP_04", "sdn_uom_name", "Percent")
ncatt_put(ncout, "hght", "sdn_uom_name", "Metres")
ncatt_put(ncout, "DEPH", "sdn_uom_name", "Metres")
ncatt_put(ncout, "Tx", "sdn_uom_name", "Celsius degree")
ncatt_put(ncout, "PTCH", "sdn_uom_name", "Degrees")
ncatt_put(ncout, "ROLL", "sdn_uom_name", "Degrees")
ncatt_put(ncout, "lon", "sdn_uom_name", "Degrees east")
ncatt_put(ncout, "lat", "sdn_uom_name", "Degrees north")
ncatt_put(ncout, "HEAD", "sdn_uom_name", "Degrees")
ncatt_put(ncout, "PRES", "sdn_uom_name", "Decibars")
ncatt_put(ncout, "SVEL", "sdn_uom_name", "Metres per second")
ncatt_put(ncout, "ELTMEP01", "sdn_uom_name", "Seconds")
ncatt_put(ncout, "time_string", "sdn_uom_name", "ISO8601")
#####CF standard names####
ncatt_put(ncout, "EWCT", "standard_name", "eastward_sea_water_velocity")
ncatt_put(ncout, "NSCT", "standard_name", "northward_sea_water_velocity")
ncatt_put(ncout, "VCSP", "standard_name", "upward_sea_water_velocity")
ncatt_put(ncout, "ELTMEP01", "standard_name", "time")
ncatt_put(ncout, "lat", "standard_name", "latitude")
ncatt_put(ncout, "lon", "standard_name", "longitude")
ncatt_put(ncout, "DEPH", "standard_name", "depth") #should maybe be change to hght
#ncatt_put(ncout, "Tx", "standard_name", "")
ncatt_put(ncout, "PTCH", "standard_name", "platform_pitch_angle")
ncatt_put(ncout, "ROLL", "standard_name", "platform_roll_angle")
ncatt_put(ncout, "PRES", "standard_name", "sea_water_pressure")
ncatt_put(ncout, "SVEL", "standard_name", "speed_of_sound_in_sea_water")
####data max and min####
ncatt_put(ncout, "EWCT", "data_max", max(adp[['v']][,,1], na.rm = TRUE))
ncatt_put(ncout, "EWCT", "data_min", min(adp[['v']][,,1], na.rm = TRUE))
ncatt_put(ncout, "EWCT", "valid_max", 1000)
ncatt_put(ncout, "EWCT", "valid_min", -1000)
ncatt_put(ncout, "NSCT", "data_max", max(adp[['v']][,,2], na.rm = TRUE))
ncatt_put(ncout, "NSCT", "data_min", min(adp[['v']][,,2], na.rm = TRUE))
ncatt_put(ncout, "NSCT", "valid_max", 1000)
ncatt_put(ncout, "NSCT", "valid_min", -1000)
ncatt_put(ncout, "VCSP", "data_max", max(adp[['v']][,,3], na.rm = TRUE))
ncatt_put(ncout, "VCSP", "data_min", min(adp[['v']][,,3], na.rm = TRUE))
ncatt_put(ncout, "VCSP", "valid_max", 1000)
ncatt_put(ncout, "VCSP", "valid_min", -1000)
ncatt_put(ncout, "ERRV", "data_max", max(adp[['v']][,,4], na.rm = TRUE))
ncatt_put(ncout, "ERRV", "data_min", min(adp[['v']][,,4], na.rm = TRUE))
ncatt_put(ncout, "ERRV", "valid_max", 2000)
ncatt_put(ncout, "ERRV", "valid_min", -2000)
ncatt_put(ncout, "BEAM_01", "data_min", min(adp[['a', 'numeric']][,,1], na.rm= TRUE))
ncatt_put(ncout, "BEAM_01", "data_max", max(adp[['a', 'numeric']][,,1], na.rm= TRUE))
ncatt_put(ncout, "BEAM_02", "data_min", min(adp[['a' ,'numeric']][,,2], na.rm= TRUE))
ncatt_put(ncout, "BEAM_02", "data_max", max(adp[['a', 'numeric']][,,2], na.rm= TRUE))
ncatt_put(ncout, "BEAM_03", "data_min", min(adp[['a', 'numeric']][,,3], na.rm= TRUE))
ncatt_put(ncout, "BEAM_03", "data_max", max(adp[['a', 'numeric']][,,3], na.rm= TRUE))
ncatt_put(ncout, "BEAM_04", "data_min", min(adp[['q', 'numeric']][,,4], na.rm= TRUE))
ncatt_put(ncout, "BEAM_04", "data_max", max(adp[['q', 'numeric']][,,4], na.rm= TRUE))
ncatt_put(ncout, "CMAG_01", "data_min", min(adp[['q', 'numeric']][,,1], na.rm= TRUE))
ncatt_put(ncout, "CMAG_01", "data_max", max(adp[['q', 'numeric']][,,1], na.rm= TRUE))
ncatt_put(ncout, "CMAG_02", "data_min", min(adp[['q' ,'numeric']][,,2], na.rm= TRUE))
ncatt_put(ncout, "CMAG_02", "data_max", max(adp[['q', 'numeric']][,,2], na.rm= TRUE))
ncatt_put(ncout, "CMAG_03", "data_min", min(adp[['q', 'numeric']][,,3], na.rm= TRUE))
ncatt_put(ncout, "CMAG_03", "data_max", max(adp[['q', 'numeric']][,,3], na.rm= TRUE))
ncatt_put(ncout, "CMAG_04", "data_min", min(adp[['q', 'numeric']][,,4], na.rm= TRUE))
ncatt_put(ncout, "CMAG_04", "data_max", max(adp[['q', 'numeric']][,,4], na.rm= TRUE))
ncatt_put(ncout, "PGDP_01", "data_min", min(adp[['g', 'numeric']][,,1], na.rm= TRUE))
ncatt_put(ncout, "PGDP_01", "data_max", max(adp[['g', 'numeric']][,,1], na.rm= TRUE))# eg min 25 % good
ncatt_put(ncout, "PGDP_02", "data_min", min(adp[['g', 'numeric']][,,2], na.rm= TRUE))
ncatt_put(ncout, "PGDP_02", "data_max", max(adp[['g' ,'numeric']][,,2], na.rm= TRUE))
ncatt_put(ncout, "PGDP_03", "data_min", min(adp[['g' ,'numeric']][,,3], na.rm= TRUE))
ncatt_put(ncout, "PGDP_03", "data_max", max(adp[['g', 'numeric']][,,3], na.rm= TRUE))
ncatt_put(ncout, "PGDP_04", "data_min", min(adp[['g', 'numeric']][,,4], na.rm= TRUE))
ncatt_put(ncout, "PGDP_04", "data_max", max(adp[['g', 'numeric']][,,4], na.rm= TRUE))
ncatt_put(ncout, "hght", "data_min", min(((adp[['sensor_depth']]- adp[['bin1Distance']]) - adp[['distance']])))
ncatt_put(ncout, "hght", "data_max", max(((adp[['sensor_depth']]- adp[['bin1Distance']]) - adp[['distance']])))
ncatt_put(ncout, "DEPH", "data_min", min(adp[['depth']]))
ncatt_put(ncout, "DEPH", "data_max", max(adp[['depth']]))
ncatt_put(ncout, "Tx", "data_min", min(adp[['temperature']]))
ncatt_put(ncout, "Tx", "data_max", max(adp[['temperature']]))
ncatt_put(ncout, "PTCH", "data_min", min(adp[['pitch']]))
ncatt_put(ncout, "PTCH", "data_max", max(adp[['pitch']]))
ncatt_put(ncout, "ROLL", "data_min", min(adp[['roll']]))
ncatt_put(ncout, "ROLL", "data_max", max(adp[['roll']]))
ncatt_put(ncout, "HEAD", "data_min", min(adp[['heading']]))
ncatt_put(ncout, "HEAD", "data_max", max(adp[['heading']]))
ncatt_put(ncout, "PRES", "data_min", min(adp[['pressure']]))
ncatt_put(ncout, "PRES", "data_max", max(adp[['pressure']]))
ncatt_put(ncout, "SVEL", "data_min", min(adp[['soundSpeed']]))
ncatt_put(ncout, "SVEL", "data_max", max(adp[['soundSpeed']]))
####nc close####
nc_close(ncout)
}
###inserting data from other instruments####
#' Insert data from alternate instrument
#'
#'*PRESSURE
#' Use the measured pressure from an alternate instrument positioned on the same
#' moooring as the ADCP This has benefits of a more accurate pressure reading
#' which can be translated to depth Note: If the pressure sensor is below the
#' ADCP the mooring separation distance (offset) should be negative.
#'
#' Extreme caution should be used when applying this function to anything other
#' than pressure as there may be significant differences in values despite only
#' a few metres separation.
#'
#' *COMPASS HEADING
#' This function can be used to insert compass headings from an alternate source
#' in extreme high latitude cases. Compass heading data with magnetic
#' declination applied should be in .csv form. Use the argument var = 'heading'.
#' Please double check data after using this function, best done by plotting UV
#' scatter plots or progressive vector plots. Ensure that headings are correct
#' and current directionality is logical.
#' This function is designed to read a csv with columns ensemble number and heading.
#' Please format csv in this way to avoid errors. Please see ADCP processing
#' guide for instructions on how to calculate alternate headings.
#'
#' *NOTE If attempting to use this function and the times of the instruments are
#' at different sampling intervals, it may be necessary to manually insert the
#' data using \code{\link[oce:oceSetData]{oceSetData}}. In this case the user
#' can pull the data into the chosen oce object and edit it manually which may
#' include removing data points or averaging data points to match the sampling
#' interval of the ADCP. There may be other cases where a similar method is
#' required, if there is a consistent specific case which requires an extra
#' function please suggest to developers. More information can also be found in
#' the Moored ADCP processing guide
#' https://gccode.ssc-spc.gc.ca/dfo-mar-odis/MooredDataProcessing/Documentation
#'
#'
#'
#' @param adp adp object into which to insert data
#' @param var variable you wish to pull from other instrument
#' @param file file where data from alternate instrument is stored
#' @param offset the mooring separation between the instruments (in metres)
#'
#' @return adp object with data set completed from alternate sources
#' @export
#'
#' @examples
#'
#' #list odf files
#' odflist <- list.files(path = ".", pattern = "MADCP*...*00.ODF")
#'
#' #read list of odf files into adp object
#' adp <- odf2adp(odflist)
#'
#'
#'
#' #add in raw and netCDF metadata and data to adp objecct
#' raw <- list.files(path = '.', pattern = "*.000")
#' nc <- list.files(path = '.', pattern = "*.nc")
#' adp <- adpCombine(adp, raw, nc)
#'
#'
#' #insert microcat pressure data
#'file <- list.files(path = '.', pattern = "MCTD*...*.ODF")
#' adp <- insertInst(adp, var = 'pressure', file = file)
#'
#'
insertInst <- function(adp, var, file = adp[['alternate_pressure_file']], offset = adp[['vertical_separation']]){
csv <- grep(file, pattern = ".csv")
if (length(csv) > 0 ){
inst <- read.csv(file, header = TRUE)
if( var == 'heading'){
ensemble <- inst[[1]]
heading <- inst[[2]]
if (length(ensemble) != length(adp[['heading']])){
warning("Incorrect dimensions! Please confirm length of heading vector!")
}else{
adp[['heading']] <- heading
adp@processingLog <- processingLogAppend(adp@processingLog, value = paste("Instrument heading inserted from alternate file", file))
return(adp)
}
}
# if (var != 'heading'){
# warning("INVALID VAR INPUT!")
# stop()
# }
}else{
inst <- read.oce(file)
vr <- inst[[var]]
u <- inst@metadata$units[var]
if (var == 'pressure'){
if (offset != 0 ){
vr <- vr + offset #generalized seawater conversion between metres and decibar (1m = 1dbar)
}
}
#check dimensions
if(length(adp[['time']]) != length(vr)){
warning('dimensions are incorrect, attempt to rectify, please confirm')
t <- inst[['time']]
vr[t < adp[['time_coverage_start']]] <- NA
vr[t > adp[['time_coverage_end']]] <- NA
vr <- na.omit(vr)
length(vr) <- length(adp[['time']])
}
adp <- oceSetData(adp, paste(var, 'alternate', sep = '_'), vr, note = NULL)
adp@metadata$units[paste(var, 'alternate', sep = '_')] <- u
adp@processingLog <- processingLogAppend(adp@processingLog, paste(var, '_alternate', ' pulled from ', file, ' with offset of ', offset, 'm.'))
return(adp)
}
}
####export processing log####
#'Export processing log from adp object to be included in netCDF
#'
#'
#'This function can be used to export the processing log recorded in the adp
#'object as a single text string to be included in a netCDF
#'
#'@param adp an oce adp object of ADCP data
#'
#' @return adp object with processingLog as separate character string in adp[['processing_history']]
#' @export
#'
#' @examples
#'
#'
#' adp <- exportPL(adp)
#'
exportPL <- function(adp){
pl <- toString(adp@processingLog$value)
adp@metadata$processing_history <- pl
return(adp)
}
####adjustDepths####
#' Adjust Bin Depths
#'
#'
#' if in processing you have inserted pressure from another instrument and
#' choose to use these new pressure values to calculate bin depths then this
#' function can be used to adjust bin depths based on more accurate pressure
#' readings.
#'
#' Another similar function which can adjust bin depths based on existing
#' pressure data is \code{\link[oce:binMapAdp]{binMapAdp}}
#' which can map adp bins to be at consistent depths with pressure.
#'
#' @param adp an oce object contasining adcp data as well as alternate pressure data from another instrument
#'
#' @export
#'
adjustDepths <- function(adp){
if (!is.null(adp[['pressure_alternate']])){
vsep <- adp[['vertical_separation']]
if (is.null(vsep)){
warning('No vertical separation provided!')
}
pres <- adp[['pressure_alternate']]
presadj <- pres + vsep
adp[['depth']] <- swDepth(pressure = presadj, latitude = adp[['latitude']], eos = 'gsw')
adp@processingLog <- processingLogAppend(adp@processingLog, paste('Depths adjusted based on pressure data from', adp[['alternate_pressure_file']], 'with vertical separation of', adp[['vertical_separation']], sep = ' '))
}
}
####bin map####
#'Bin Map
#'
#'
#'
#' a function to create a bin variable within the adp object which can be mapped onto plots
#' variable contains list of distance from adp to each bin named by bin number
#'
#'Once bin variable has been created use
#'```abline(h = obj[['bin']])```
#'to create horizontal line denoting bins
#'
#'
#' @param obj adp object from oce package
#'
#' @export
binMap <- function(obj){
bin <- list()
bin[[1]] <- obj[['bin1Distance']]
counter <- 1
for (i in 2: length(obj[['distance']])){
bin[[i]] <- bin[[1]] + obj[['cellSize']] * counter
counter <- counter +1
}
names(bin) <- c(1:length(bin))
obj <- oceSetData(obj, 'bin', bin)
return(obj)
}
####flagging specific data points within an adp data set####
#' Flag
#'
#' Flag specific data points within an adp dataset
#'
#' @param adp an adp object from oce
#' @param values a list of values indexing the adp object's velocity by time which you wish to flag
#'
#' @return adp object with complete flag array
#' @export
#'
#' @examples
#'
#' adp <- flag(adp, values = list('time' = c(1, 2, 3, 4, 5, 6)))
#'
flag <- function(adp, values){
if( !is.null(values$time)){
# if ( !is.null( values$depth)){ #FIXME: add index by depth and beam as well?
# if (!is.null (values$beam)){
for ( i in 1: length(values$time)){
f <- values$time[[i]]
# g <- values$depth[[i]]
# h <- values$beam[[i]]
adp[['vFlag']][f, ,] <- 4
}
#}
# else{
# for ( i in 1: length(values$time)){
# f <- values$time[[i]]
# g <- values$depth[[i]]
#
# adp[['vFlag']][f, g, ] <- 4
# }
# }
}
# else{
# for ( i in 1: length(values$time)){
# f <- values$time[[i]]
#
#
# adp[['vFlag']][f, , ] <- 4
# }
# }
for( i in 1:length(values$time)){
adp@processingLog <- processingLogAppend(adp@processingLog, paste('Specific data points flagged based on visual inspection, index of flagged point was, adp[["v"]][', values$time[[i]], ', , ]' , sep = ' '))
}
return(adp)
}
####plotting functions####
####bin by bin plot###
#'
#'Bin by bin plot
#'@family Plot
#'
#'use to plot each "bin" of any chosen variable (u, v, error, echo intensity)
#'to use with adp object example:
#'````plotBin(adp@data$v[,,1])````
#'
#'@param v variable matrix from adcp data, should be 2 dimensional (time, distance or bin)
#'
#'
#'@export
#'
plotBin <- function(v, ...){
for(i in 1:length(v[1, ]))
plot(v[,i], xlab = "time (s)", ylab = "m/s", main = (paste( "Bin", i, ": Depth", round(adp[['depthMean']] - adp[['distance']][i], digits= 0), 'm')), type = 'l', ...)
}
####echo intensity plot####
#' Plot echo intensity
#'@family Plot
#'
#' Creates a time average echo intensity plot by bin number to analyze adcp data.
#'
#' @param adp an oce object with adcp data
#'
#' @return plot of time average echo intensity values by bin with separate beams
#' @export
#'
#' @examples
plot_ei <- function(adp, ...){
#pull echo intensity from adp object
echoint <- adp[['a', 'numeric']]
a1 <- echoint[,,1]
a2 <- echoint[,,2]
a3 <- echoint[,,3]
a4 <- echoint[,,4]
#create time averaged mean values for each bin and beam
a1m <- colMeans(a1, na.rm = TRUE)
a2m <- colMeans(a2, na.rm = TRUE)
a3m <- colMeans(a3, na.rm = TRUE)
a4m <- colMeans(a4, na.rm = TRUE)
#number of bins calculated
bins <- c(1:length(a1m))
#plot means by bin
plot(a1m, bins, xlim = c(0, 255) , type = 'l', xlab = 'Echo Intensity, Counts', ylab = 'Bin Number', ...)
lines(a2m, bins, xlim = c(0,255) , type = 'l', col = 'red', xlab= '', ylab = '' )
lines(a3m, bins, xlim = c(0, 255), type = 'l', col = 'green', xlab = '', ylab = '')
lines(a4m, bins, xlim = c(0, 255), type = 'l', col = 'blue', xlab = '', ylab = '')
legend('topright' , legend = c('Beam 1', 'Beam 2', 'Beam 3', 'Beam 4'), col = c('black', 'red', 'green', 'blue'), lty = 1, cex = 0.6)
}
####progressive vector bin plot####
#' Progressive vector plot
#'@family Plot
#'
#' Default returns depth averaged plot but if specified in control can return plot of specific bin combinations
#'
#' @param x adp object from oce
#' @param control list() with optional object 'bin' which can be used to specify the bins you wish to plot
#'@param xlim limiting values for x axis
#'@param ylim limiting values for y axis
#'
#'
#' @return plot of progressive vectors,
#' @export
#'
#' @examples
#' pvPlot(adp, control = list('bin' = c(1, 5, 7)))
#' pvPlot(adp, control = list('bin' = c(1:length(adp[['distance']]))))
pvPlot <- function(x, control, xlim = c(range(x[['distance']])), ylim = c(range(x[['distance']])), ...){
##oce code
mgp=getOption("oceMgp")
par(mar = c(mgp[1] + 1, mgp[1] + 1, 1, 1))
dt <-
as.numeric(difftime(x@data$time[2], x@data$time[1], units = "sec")) # FIXME: should not assume all equal
mPerKm <- 1000
U <- x@data$v[, , 1]
V <- x@data$v[, , 2]
ttt <- x@data$time
if (!missing(control) && !is.null(control$bin)) {
# if (control$bin < 1)
# stop("cannot have control$bin less than 1, but got ", control$bin)
# max.bin <- dim(x@data$v)[2]
# if (control$bin > max.bin)
# stop("cannot have control$bin larger than ",
# max.bin,
# " but got ",
# control$bin)
#throwing wearnings due to length of control$bin being >1
if( length(control$bin) == 1){
u <-
U[, control$bin] #EAC: bug fix, attempt to subset 2D matrix by 3 dimensions
v <- V[, control$bin]
}
##inserted EAC
if (length(control$bin) >1){
u <- NULL
v <- NULL
for ( i in 1:length(control$bin)){
u[[i]] <- U[, control$bin[[i]]]
v[[i]] <- V[, control$bin[[i]]]
}
bins <- TRUE
}
##
} else {
if (x@metadata$numberOfCells > 1) {
u <- apply(U, 1, mean, na.rm = TRUE)
v <- apply(V, 1, mean, na.rm = TRUE)
} else {
u <- U
v <- V
bins <- FALSE
}
}
u[is.na(u)] <- 0 # zero out missing
v[is.na(v)] <- 0
if (bins == FALSE){
xDist <- integrateTrapezoid(ttt, u, 'cA') / mPerKm
yDist <- integrateTrapezoid(ttt, v, 'cA') / mPerKm
plot(
xDist,
yDist,
xlab = "km",
ylab = "km",
type = 'l',
asp = 1,
col = 'blue',
xlim = xlim,
ylim = ylim,
...
)
}
if(bins == TRUE){
xDist <- NULL
yDist <- NULL
listcol <- 1:150
for ( i in 1:length(control$bin)){
xDist[[i]] <- integrateTrapezoid(ttt, u[[i]], 'cA') / mPerKm
yDist[[i]] <- integrateTrapezoid(ttt, v[[i]], 'cA') / mPerKm
}
for ( i in 1:length(control$bin)){
plot(
xDist[[i]],
yDist[[i]],
xlab = "km",
ylab = "km",
type = 'l',
asp = 1,
col = listcol[[i]],
xlim = xlim,
ylim = ylim,
...
)
par(new = TRUE)
}
legend('topleft', legend = paste('Bin', control$bin, sep = ' '), col = listcol, lty = 1, cex = 0.5)
}
}
#' plotQC
#'
#' Plots which show flagged vs unflagged values of a variety of parameters, can
#' be used to visually check quality control and confirm that flagged values are
#' appropriate
#'
#' @param obj an adp object
#' @param QC the paramater you wish to plot,
#'
#' options are u, v, w, er, ei, pg
#'
#' *u -> eastward velocity component
#' *v -> northward velocity component
#' *w -> upward velocity component
#' *er -> error velocity
#' *ei -> echo intensity (first beam only)
#' *pg -> precent good, sum of 1st and 4th beams
#'
#'
#'
#' @return Plots which show obj (adp) data parameter with flagged values shown
#' in red and black lines showing good values
#'
#' @export
#'
#' @examples
plotQC <- function(obj, QC, ... ){
Bad <- handleFlags(object = adp, flags = 1, actions = list('NA'))
Good <- handleFlags(object = adp, flags = 4, actions = list('NA'))
if( QC == 'u'){
uBad <- Bad[['v']][,,1]
uGood <- Good[['v']][,,1]
for(i in 1:length(obj[['v']][1,,1])){
plot(uGood[,i], xlab = "time (s)", ylab = "m/s", main = (paste( "Bin", i, ": Depth", round(adp[['depthMean']] - adp[['distance']][i], digits= 0), 'm, of U')), type = 'l', ylim = c(-1.5, 1.5))
par(new = TRUE)
plot(uBad[,i], xlab = '', ylab = '', axes = FALSE, col = 'red', type = 'l', ylim = c(-1.5, 1.5))
par(new = TRUE)
mtext(text =paste(round(length(na.omit(uBad[,i]))/ length(uBad[,i]) *100, digits = 2), "% invalid data"), side = 1, cex = 0.8)
}
}
if( QC == 'v'){
vBad <- Bad[['v']][,,2]
vGood <- Good[['v']][,,2]
for(i in 1:length(obj[['v']][1,,1])){
plot(vGood[,i], xlab = "time (s)", ylab = "m/s", main = (paste( "Bin", i, ": Depth", round(adp[['depthMean']] - adp[['distance']][i], digits= 0), 'm, of V')), type = 'l', ylim = c(-1.5, 1.5), ...)
par(new = TRUE)
plot(vBad[,i], xlab = '', ylab = '', axes = FALSE, col = 'red', type = 'l', ylim = c(-1.5, 1.5))
par(new = TRUE)
mtext(text =paste(round(length(na.omit(vBad[,i]))/ length(vBad[,i]) *100, digits = 2), "% invalid data"), side = 1, cex = 0.8)
}
}
if( QC == 'w'){
wBad <- Bad[['v']][,,3]
wGood <- Good[['v']][,,3]
for(i in 1:length(obj[['v']][1,,1])){
plot(wGood[,i], xlab = "time (s)", ylab = "m/s", main = (paste( "Bin", i, ": Depth", round(adp[['depthMean']] - adp[['distance']][i], digits= 0), 'm, of W')), type = 'l', ylim = c(-1.5, 1.5), ...)
par(new = TRUE)
plot(wBad[,i], xlab = '', ylab = '', axes = FALSE, col = 'red', type = 'l', ylim = c(-1.5, 1.5))
par(new = TRUE)
mtext(text =paste(round(length(na.omit(wBad[,i]))/ length(wBad[,i]) *100, digits = 2), "% invalid data"), side = 1, cex = 0.8)
}
}
if( QC == 'er'){
erBad <- Bad[['v']][,,4]
erGood <- Good[['v']][,,4]
for(i in 1:length(obj[['v']][1,,1])){
plot(erGood[,i], xlab = "time (s)", ylab = "m/s", main = (paste( "Bin", i, ": Depth", round(adp[['depthMean']] - adp[['distance']][i], digits= 0), 'm, of ERRV')), type = 'l', ylim = c(-4, 4), ...)
par(new = TRUE)
plot(erBad[,i], xlab = '', ylab = '', axes = FALSE, col = 'red', type = 'l', ylim = c(-4, 4))
par(new = TRUE)
mtext(text =paste(round(length(na.omit(erBad[,i]))/ length(erBad[,i]) *100, digits = 2), "% invalid data"), side = 1, cex = 0.8)
}
}
if( QC == 'ei'){
eiBad <- Bad[['a', 'numeric']][,,1]
eiBad[is.na(Bad[['v']][,,1])] <- NA
eiGood <- Good[['a', 'numeric']][,,1]
eiGood[is.na(Good[['v']][,,1])] <- NA
for(i in 1:length(obj[['a']][1,,1])){
plot(eiGood[,i], xlab = "time (s)", ylab = "Intensity (counts)", main = (paste( "Bin", i, ": Depth", round(adp[['depthMean']] - adp[['distance']][i], digits= 0), 'm, of Echo Intensity (Beam 1)')), type = 'l', ylim = c(0, 255),...)
par(new = TRUE)
plot(eiBad[,i], xlab = '', ylab = '', axes = FALSE, col = 'red', type = 'l', ylim = c(0, 255))
par(new = TRUE)
mtext(text =paste(round(length(na.omit(eiBad[,i]))/ length(eiBad[,i]) *100, digits = 2), "% invalid data"), side = 1, cex = 0.8)
}
}
if( QC == 'pg'){
pgBad <- Bad[['g', 'numeric']][,,1] + Bad[['g', 'numeric']][,,4]
pgBad[is.na(Bad[['v']][,,1])] <- NA
pgGood <- Good[['g', 'numeric']][,,1] + Good[['g', 'numeric']][,,4]
pgGood[is.na(Good[['v']][,,1])] <- NA
for(i in 1:length(obj[['g']][1,,1])){
plot(pgGood[,i], xlab = "time (s)", ylab = "%", main = (paste( "Bin", i, ": Depth", round(adp[['depthMean']] - adp[['distance']][i], digits= 0), 'm, of Percent Good (Beam 1)')), type = 'l', ylim = c(0, 100), ...)
par(new = TRUE)
plot(pgBad[,i], xlab = '', ylab = '', axes = FALSE, col = 'red', type = 'l', ylim = c(0, 100))
par(new = TRUE)
mtext(text =paste(round(length(na.omit(pgBad[,i]))/ length(pgBad[,i]) *100, digits = 2), "% invalid data"), side = 1, cex = 0.8)
}
}
}
####Plot combinations####
#' Start Plots
#'
#' Plots give a first visualization of ADCP data set
#'
#' @param adp an oce adp object
#' @param path file path to which plots will be saved
#'
#'@details
#'Includes each velocity component as well as pressure over time
#'
#' @return a pdf series of plots
#' @export
#'
#' @examples
startPlots <- function(adp, path){
#save all plots to folder
if (!is.null(adp[['mooring_number']])){
mooring <- adp[['mooring_number']]
}
if(!is.null(adp[['mooringNumber']])){
mooring <- adp[['mooringNumber']]
}
if(!is.null(adp[['station']])){
mooring <- adp[['station']]
}
plotpath <- paste0(path, '/Plots/M', mooring)
if (dir.exists(plotpath)){
}else{
dir.create(paste0(path, '/Plots/M', mooring), recursive = TRUE)
}
#general first look plots
pdf( file = paste0(plotpath, '/PreProcessingPlots.pdf'))
plot(adp, which = 1, title = 'EWCT: PreProcessing') #u
mtext('m/s', side = 4)
plot(adp, which = 2, title = 'NSCT: PreProcessing') #v
mtext('m/s', side = 4)
plot(adp, which = 3, title = 'VCSP: PreProcessing') #w
mtext('m/s', side = 4)
plot(adp, which = 4, title = 'ERRV: PreProcessing') #error
mtext('m/s', side = 4)
plot(adp, which = 15, main = 'Pressure: PreProcessing') #pressure
dev.off()
print(paste("PreProcessingPlots.pdf created in", plotpath))
}
#' Bin Plot
#'
#' @param adp an oce adp object
#' @param x the matrix of data to be plotted
#'@param path file path to which plots will be saved
#'
#'@details
#' Series of plots, separated by depth (bins) of a particular parameter in ADCP data
#'
#'
#' @return a pdf with a series of plots
#' @export
#'
#' @examples
#'
#' binPlot(adp, x = adp[['v']][,,1])
binPlot <- function(adp, x, path){
if (!is.null(adp[['mooring_number']])){
mooring <- adp[['mooring_number']]
}
if(!is.null(adp[['mooringNumber']])){
mooring <- adp[['mooringNumber']]
}
if(!is.null(adp[['station']])){
mooring <- adp[['station']]
}
plotpath <- paste0(path, '/Plots/M', mooring)
if (dir.exists(plotpath)){
}else{
dir.create(paste0(path, '/Plots/M', mooring))
}
#save bin plots to pdf
name <- paste('binbybinplot_V_', adp[['cruise_number']],'_', adp[['mooring_number']], '_', '1-50', sep = '') #name pdf
pdf(paste0(plotpath,'/', name, '.pdf') , width = 8, height = 40 ) #save to pdf
par(mfrow = c(15, 1)) #set number of plots per page (rows, columns)
#cat(paste('Bin Plot of mooring', adp[['mooring_number']], 'from cruise', adp[['cruise_number']], 'with data from', adp[['time_coverage_start']], 'to', adp[['time_coverage_end']], sep = ' '))
plotBin(x)
dev.off() #close pdf
print(paste("PreProcessingPlots.pdf created in", plotpath))
}
#' End Plots
#'
#' Post Processing summary plots for ADCP data
#'
#' @param adpClean an adp object with flags set to NA
#' @param path file path to which plots will be saved
#'
#' @return a pdf series of plots including velocity components, pressure and echo intensity
#' @export
#'
#' @examples
endPlots <- function(adpClean, path){
if (!is.null(adpClean[['mooring_number']])){
mooring <- adpClean[['mooring_number']]
}
if(!is.null(adpClean[['mooringNumber']])){
mooring <- adpClean[['mooringNumber']]
}
if(!is.null(adpClean[['station']])){
mooring <- adpClean[['station']]
}
plotpath <- paste0(path, '/Plots/M', mooring)
if (dir.exists(plotpath)){
}else{
dir.create(paste0(path, '/Plots/M', mooring))
}
#check plots
pdf(paste0(plotpath, '/PostProcessing.pdf'))
# looking for any spikes on either end of dataset
plot(adp[['depth']], main = 'Depth: PostProcessing', xlab = 'time (seconds)', ylab = 'Depth (m)', lty = 2)
# looking for pressure spikes on either end
plot(adp, which = 15, main = 'Pressure: PostProcessing')
# plot velocity beams
plot(adpClean, which = 1, title = 'EWCT: PostProcessing')
mtext('m/s', side = 4)
plot(adpClean, which = 2, title = 'NSCT: PostProcessing')
mtext('m/s', side = 4)
plot(adpClean, which = 3, title = 'VCSP: PostProcessing')
mtext('m/s', side = 4)
plot(adpClean, which = 4, title = 'ERRV: PostProcessing')
mtext('m/s', side = 4)
# plot echo intensity
plot_ei(adpClean, main = 'Echo Intensity')
dev.off()
print(paste("PreProcessingPlots.pdf created in", plotpath))
}
#' Quality Control Plots
#'
#' @param adp an oce adp object
#' @param QC the QC parameter you want to inspect, options are listed in details
#' @param path file path to which plots will be saved
#'
#' @details
#' These quality control plots show a comparison between valid and invalid data.
#' Invalid data is determined by the flags within the adp object (which will
#' have been created based on processing procedures). The invalid data is
#' higlighted in red for each bin and a total is shown at the bottom which gives
#' the user a percentage of invalid data (or data flagged), this can allow a
#' user to see if there are particular bins which should be ommitted from the
#' final export data set.
#'
#' options for quality control parameters are u, v, w, er, ei, pg
#'
#' *u -> eastward velocity component
#' *v -> northward velocity component
#' *w -> upward velocity component
#' *er -> error velocity
#' *ei -> echo intensity (first beam only)
#' *pg -> precent good, sum of 1st and 4th beams
#'
#' @return a pdf compilation of plots
#' @export
#'
#' @examples
qcPlots <- function(adp, QC, path){
if (!is.null(adp[['mooring_number']])){
mooring <- adp[['mooring_number']]
}
if(!is.null(adp[['mooringNumber']])){
mooring <- adp[['mooringNumber']]
}
if(!is.null(adp[['station']])){
mooring <- adp[['station']]
}
plotpath <- paste0(path, '/Plots/M', mooring)
if (dir.exists(plotpath)){
}else{
dir.create(paste0(path, '/Plots/M', mooring))
}
name <- paste('binbybinplot', QC, mooring, sep = '_')
# check any other relvant plots to confirm QC before exporting
pdf(paste0(plotpath,'/', name, '_QC.pdf') , width = 8, height = 40 ) #save to pdf
par(mfrow = c(15, 1)) #set number of plots per page (rows, columns)
plotQC(adp, QC = QC)
dev.off() #close pdf
print(paste("PreProcessingPlots.pdf created in", plotpath))
}
#mapPlot check
#' Plot Map
#'
#' @param adp an oce adp object
#'
#' @return a plot of lat and lon from adp object
#' @export
#'
#' @examples
plotMap <- function(adp){
require('maps')
lat <- adp[['latitude']]
lon <- adp[['longitude']]
maps::map(plot = TRUE, xlim = c(lon-20, lon+20), ylim = c(lat-20, lat+20), fill = TRUE, col = 'green')
par(new = TRUE)
points(lon, lat, col = 'red')
}
####GF3 2 P01####
#' GF3 to P01
#'
#' Use this function to map gf3 codes to P01 codes for exporting to netCDF
#'
#' @param gf3 a gf3 standard code paramater
#'
#' @return a matching P01 value with units and standard name (if applicable)
#' @export
#'
#' @examples
as.P01 <- function(gf3){
gf32p01 <- read.csv('c:/Users/ChisholmE/Documents/sample files/GF3 Code Map.csv', header = TRUE)
line <- grep(gf32p01$GF3.code, pattern = gf3)
if (length(line) == 0){
yn <- list()
for (i in 1:length(gf32p01$GF3.code)){
yn[[i]] <- grep( pattern = gf32p01$GF3.code[[i]], x = gf3, value = TRUE)
if(length(yn[[i]] != 0)){
line <- i
}
}
}
if (length(line) == 0){
warning(paste(gf3, 'not recognized in list of GF3 codes!'))
stop()
}
gf3 <- list(gf3 = gf3)
gf3$P01 <- as.character(gf32p01$P01.code[[line]])
gf3$P01name <-as.character(gf32p01$P01..preferred.name[[line]])
gf3$P06 <- as.character(gf32p01$P06.unit.code[[line]])
gf3$P06name <- as.character(gf32p01$P06.unit.name[[line]])
gf3$units <- as.character(gf32p01$units[[line]])
gf3$std <- as.character(gf32p01$standard_name[[line]])
return(gf3)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.