Learn R Programming

oce (version 0.2-1)

read.adv: Read an ADV data file

Description

Read an ADV data file, producing an object of type adv.

Usage

read.adv(file, from=1, to, by=1, tz=getOption("oceTz"),
  type=c("nortek", "sontek", "sontek.adr", "sontek.text"),
  header=TRUE,
  latitude=NA, longitude=NA,
  start, deltat,
  debug=getOption("oceDebug"), monitor=TRUE, history)
read.adv.nortek(file, from=1, to, by=1, tz=getOption("oceTz"), 
  type="vector",
  header=TRUE,
  latitude=NA, longitude=NA,
  debug=getOption("oceDebug"), monitor=TRUE, history)
read.adv.sontek.serial(file, from=1, to, by=1, tz=getOption("oceTz"),
  type="default",
  latitude=NA, longitude=NA,
  start, deltat,
  debug=getOption("oceDebug"), monitor=TRUE, history)
read.adv.sontek.adr(file, from=1, to, by=1, tz=getOption("oceTz"),
  header=TRUE, 
  latitude=NA, longitude=NA,
  type="",
  debug=getOption("oceDebug"), monitor=TRUE, history)
read.adv.sontek.text(basefile, from=1, to, by=1, tz=getOption("oceTz"),
  coordinateSystem="xyz",
  transformationMatrix,
  latitude=NA, longitude=NA,
  debug=getOption("oceDebug"), history)

Arguments

file
a connection or a character string giving the name of the file to load. It is also possble to supply a vector of filenames, for the case of data split into files by a data logger, and in that case, header must be FALSE
basefile
character string naming the base of filenames to load (used only by read.adv.sontek.text). The actual filenames are constructed by appending ".hd1" and ".ts1" to the base name.
from
index number of the first profile to be read, or the time of that profile, as created with as.POSIXct (hint: use tz="UTC"). This argument is ignored if header==FALSE
to
indication of the last profile to read, in a format matching that of from. This is ignored if header==FALSE.
by
an indication of the stride length to use while walking through the file. This is ignored if header==FALSE. Otherwise, if this is an integer, then by-1 profiles are skipped between each pair of profiles that is rea
header
a boolean indicating whether the file contains a header at the start. (This will not be the case for files that are created by data loggers that chop the raw data up into a series of sub-files, e.g. once per hour.)
latitude
optional signed number indicating the latitude in degrees North.
longitude
optional signed number indicating the longitude in degrees East.
start
the time of the first sample, typically created with as.POSIXct. This is mandatory if header is FALSE. This may be a vector of times, if filename is a
deltat
the time between samples. (This is mandatory if header=FALSE.)
coordinateSystem
character string indicating coordinate system, one of "beam", "xyz", "enu" or "other".
transformationMatrix
transformation matrix to use in converting beam coordinates to xyz coordinates. This will over-ride the matrix in the file header, if there is one. An example is rbind(c(2.710, -1.409, -1.299), c(0.071, 2.372, -2.442), c(0.344, 0.3
type
character string indicating type of file (ignored at present).
tz
character string indicating time zone to be assumed in the data.
debug
a flag that turns on debugging. The value indicates the depth within the call stack to which debugging applies. For example, read.adv.nortek() calls read.header.nortek(), so that read.adv.nortek(...,debug=2)
monitor
boolean, set to TRUE to provide an indication of every data burst read.
history
if provided, the action item to be stored in the log. This parameter is typically only provided for internal calls; the default that it provides is better for normal calls by a user.

Value

  • An object of class "adv", which contains measurements made with an ADV device. This is a list containing lists named metadata, data, and history. The data list contains lists ts, potentially (for Nortek Vector units) tsSlow, and ma (matrices of velocity, etc). These are as adp objects, except for the presence of tsSlow, for timeseries that vary on a slow timescale, e.g. on Nortek Vector units, tsSlow holds heading, pitch, roll, and temperature, while ts holds only pressure.

Special considerations for NorTek files.

  1. The full file is first read into a buffer.
  2. Next, velocity chunks (at which velocities are stored, but not heading, etc.), are located within the buffer by usingmatchBytes(buf, 0xa5, 0x10).BUG:the checksum provided in bytes 23 and 24 of these chunks should be examined to discard matches that occur randomly (with probability 1:65025) but this is not done in the present version of theread.adv.nortekfunction.
  3. System chunks (which hold heading, pitch, etc.) are found withmatchBytes(buf, 0xa5, 0x11, 0x0e).
  4. Times from the system chunks are mapped to velocity chunks byassuminga constant sampling rate for each chunk. If this assumption is incorrect, then the times in thedata$ts$timevector will be incorrect, although the values in thedata$ts$pressurevector will be correct.
  5. Unlike related functions,read.adv.nortekreads and decodes every system chunk, even if abyargument is specified. This makes this function slow, because decoding times is a slow operation. (About 60 percent of the execution time is spent callingISOdatetime.)

Special considerations for Sontek files.

The binary format is inferred from Appendix 2.2.3 of the Sontek ADV operation Manual, Firmware Version 4.0 (Oct 1997), with the following exceptions and notes.

  1. The documentation says sampling rate is in units of 0.1Hz, but a test file indicates that it is in 0.01 Hz.
  2. Bursts are recognized by byte sequences, as documented on page 95 of [1]. In each case, a signalling byte is to be followed by a certain number of bytes, and so this code checks for two-byte sequences. The are as follows:
    • c(0x81,0x12)for an ADV with no optional sensors installed.
    • c(0x83,0x18)if a compass/tilt sensor is installed, but no temperature or pressor sensors.
    • c(0x85,0x16)if temperature and/or pressure sensors are installed, but no compass/tilt sensor.
    • c(0x87,0x1c)if a compass/tilt sensor is installed in addition to temperature and/or pressure sensors.
    Bug:only the second-last of these is handled in the present version of the package.

Details

Reads a binary-format ADV file. This is straightforward for files with headers, since the headers contain all the information required for further processing.

Files without headers may be created in experiments in which a data logger was set up to monitor the serial data stream from an instrument. The lack of header information places a burden on the user, who must supply such basic information as the times of observations, the instrument orientation, the instrument coordinate system, etc. Example 3 below shows how to deal with such files. Three things should be noted.

  1. The use must choose the appropriateread.advvariant corresponding to the instrument in question. (This is necessary becausemagic, which is used by the genericread.oceroutine, cannot determine the type of instrument by examining a file that lacks a header.)
  2. The call to thereadfunction must include a start time (start) and the number of seconds between data (deltat), again, because the instrument data stream may lack those things when the device is set to a serial mode. Also, of course, it is necessary to setheader=FALSEin the function call.
  3. Once the file has been read in, the user will be obliged to specify other information, for the object to be well-formed. For example, thereadfunction will have no way of knowing the instrument orientation, the coordinate system being used, the transformation matrix to go from"beam"to"xyz"coordinates, or the instrument heading, pitch, and roll, to go from"xyz"coordinates to"enu"coordinates. Such things are illustrated in example 3 below.

References

1. SonTek/YSI ADVField/Hydra Acoustic Doppler Velocimeter (Field) Technical Documentation (Sept 1, 2001).

See Also

Objects of class adv may be plotted with plot.adv or summarized with summary.adv. Coordinate transformations are done with beamToXyzAdv, xyzToEnuAdv, and enuToOtherAdv, in that order.

Examples

Run this code
library(oce)
opar <- par(no.readonly = TRUE)
dir <- "/data/archive/sleiwex/2008/moorings/"

# Example 1
# Nortek binary file, daily at 1/2 hour decimation
d <- read.oce(
  "/data/archive/sleiwex/2008/moorings/m05/adv/nortek_1943/raw/adv_nortek_1943.vec",
  from=as.POSIXct("2008-06-26 00:00:00", tz="UTC"),
  to=as.POSIXct("2008-06-27 00:00:00", tz="UTC"),
  by="00:30:00")
plot(d, which=c(1:3,15))      # beams plus pressure

# Example 2
# Sontek adr file, with method to estimate turbulent dissipation
d <- read.adv.sontek.adr(
  "/data/archive/sleiwex/2008/moorings/m03/adv/sontek_b373h/raw/adv_sontek_b373h.adr",
  from=as.POSIXct("2008-07-01 15:30:00",tz="UTC"),
  to=as.POSIXct("2008-07-01 16:00:00",tz="UTC"))
w <- ts(d$data$ma$v[,3], deltat=1/d$metadata$sampling.rate) # z component
par(mfrow=c(2,2))
par(mgp=getOption("oceMgp"))
par(mar=c(3,3,2,1))
plot(w)
plot(d$data$ts$time, sqrt(d$data$ma$v[,1]^2+d$data$ma$v[,2]^2),
    type='l', xlab="Time [s]", ylab="Horizontal velocity [m/s]")
U <- mean(sqrt(d$data$ma$v[,1]^2 + d$data$ma$v[,2]^2))
abline(h=U, col='red')
mtext(sprintf("U=%.2fm/s", U), side=4, at=U)
s <- spectrum(w, spans=c(3,5,7), plot=FALSE)  # just guessing on spans
plot(log10(s$freq), log10(s$spec), type='l', xlab="f [Hz]", ylab="E", asp=1)
for (a in seq(-20, 10, 1))
    abline(a, -5/3, col='lightgray')     # slope if turbulent
k <- 2 * pi * s$freq / U
plot(log10(k), log10(k^(5/3)*s$spec), type='l', 
     xlab="k [radian/m]", ylab=expression(k^(5/3)*E), asp=1)
alpha <- 0.4                    # a 3D Kolmogorov coefficient
epsilon <- (median(k^(5/3)*s$spec)/alpha)^(3/2) # median might ignore low-freq
abline(h=log10(alpha * epsilon^(2/3)), col="red")
mtext(sprintf("%.0e W/kg", epsilon), side=4, at=log10(alpha * epsilon^(2/3)))
grid()
par(opar)

# Example 3
# Sontek ADV dataset, chopped into one-hour files by a data logger.
library(oce)
table <- loggerToc("/data/archive/sleiwex/2008/moorings/m05/adv/sontek_202h/raw",
                   from=as.POSIXct("2008-07-01 00:00:00", tz="UTC"),
                   to=as.POSIXct("2008-07-01 2:00:00", tz="UTC"))
d <- read.adv.sontek.serial(file=table$filename, start=table$startTime, deltat=1/10)
d <- oceEdit(d, "coordinateSystem", "xyz") # original coordinate
d <- oceEdit(d, "oceCoordinate", "xyz")    # present coordinate
# Note that the transformation matrix varies from instrument to instrument.
d <- oceEdit(d, "transformationMatrix", rbind(c(11033,-8503,-5238),
                                              c(347,-32767,9338),
                                              c(-1418, -1476, -1333)) / 4096)
d <- oceEdit(d, "orientation", "upward")
d <- oceEdit(d, "heading", 0)
d <- oceEdit(d, "pitch", 0)
d <- oceEdit(d, "roll", 0)
d <- oceEdit(d, "serial.number", "202h")
enu <- xyzToEnuAdv(d)
plot(enu, which=c("u1", "u2", "u3", "temperature"))

Run the code above in your browser using DataLab