knitr::opts_chunk$set(collapse = TRUE)
library(units)
units_options(negative_power = TRUE, parse = TRUE, group = c("(", ")"))

Introduction

This vignette describes the use of the lisst package to read, process and visualize data recorded by the Laser In-Situ Scattering and Transmissometry (LISST) instruments, manufactured by Sequoia Scientific, Inc. The package was created to have a single framework of functions and structures to work with different LISST models, simplifying analysis task when dealing with multiple instruments or upgrade to a new model. It was also the intention to provide additional utilities as data types (VSF), subseting and plotting.

The oce pakage also provides functions for visualition of LISST data, but is limited to the LISST-100(X) and to processed data (particle size distribution) as produced by the LISST-SOP.

Internally, the LISST data is represented as a data.frame with metadata stored as attributes. The metadata contains all information necessary for processing and plotting, such as model and instrument specific information, background scattering and size and angle ranges of each detector ring. Each column of the data.frame - the core of the lisst object - is stored as a units object, with the exception of those related to time.

The usage of the package functions will be illustrated with two examples: (1) a day mooring of a LISST-200X at the Spuikom lake in Ostend, Belgium; and (2) a surface sample with a LISST-100X in the Donkmeer lake, Belgium. The latter sections will present a more detailed discussion on the data representation and the functions provided by the package.

LISST-200X Mooring example

A LISST-200X (SN 2028) from the Flanders Marine Institute (VLIZ, in flemish) was moored from ~9:00 to 16:00 (local time) at the VLIZ monitoring buoy in the center of the Spuikom, in Ostend, Belgium. The data collection was planned to provide information on temporal changes in particle size distribution and concentration during a day campaign of optical measurements in the lake. Start and end conditions were set to the external swtich, with an average of 10 samples every 30 second, and no path reduction module (PRM) was used.

The binary file recorded by the instrument was processed with the LISST SOP to retrieve the particle size distribution and concentration in ppm with a random shape particle model. Our first task is to import the processed file into R.

library(lisst)

fl200 <- system.file("extdata", "sp_april_rs.csv", package = "lisst")
l200p <- read_lisst(fl200)

Because no PRM was used, it is not necessary to specify the water path length between the source and detector and the function will use the standard path length of the instrument (with a warning). If necessary, it can be specified with argument 'pl' (in meters).

We can have a first look at the data in the lisst object. All data columns are kept, their contents indicated by descriptive short names and their units printed along with their values. Every data row has a time stamp in standard POSIX format.

head(l200p, n = 2)

Lets inspect the data in a more convinient way, using a Hovmöller diagram:

lhov(l200p, by = 'time', norm = F)

The instrument was keept on recording much beyond the sampling period, so we will subset to keep only the records for when we know the instrument was in the water. We can do this using ISO-8601 standard notation for time (and range), as implemented for time subsetting in package xts. Since the time zone of the instrument was UTC, we will use a subset of two hours (CEST = UTC+2).

l200p <- l200p['2018-04-19 07:30/2018-04-19 14:00', ]
lhov(l200p, by = 'time', norm = F)

The upper panel show what appears to be a diel cycle, with increase in the total volume of particles. From the size bins in the middle panel, we see that this increase seems restricted to the larger population that is apparently increasing in size. We can separate those components by summing the values of the bins of interest. For this data is sufficient to sum two sets of bins, from 1:14 and from 25:36. If in doubt, the size ranges of bins can be retrieved with the function 'lbinr'.

plotBins(l200p, bins = list(1:14, 25:36), by = 'time', col = c("blue", "red"))
binr  <- lbinr(l200p)
r1    <- range(binr[1:14,])
r2    <- range(binr[25:36,])
ltext <- c(eval(substitute(expression(x-y~mu*m), list(x = r1[1], y = r1[2]))),
           eval(substitute(expression(x-y~mu*m), list(x = r2[1], y = r2[2]))))
legend('topleft', legend = ltext, lty = 1, col = c("blue", 'red'), bty = 'n', cex = 0.8)

Reading data

The new models of the LISST instrument keep track of the instrument information (e.g., model, instrument calibration constants) in the recorded data, but the older LISST-100(X) models don't. The lisst package reproduces the behaivour of the new models, by first registering the instrument specific information in an internal data base with the function lisst_reg, and by adding all relevant information in sperate attributes of the lisst object uppon read with the read_lisst function. In that way, only the instrument serial number has be informed for the read_lisst function to know which instrument it is working with. And since all information is stored in the object, additional processing deals only with the object. Here is an example on how to register a LISST, for the LISST-100X SN1298:

#path  <- system.file("extdata", package = "lisst")
#model <- 100
#lisst_reg(model, path)

The registration need only to be done once, and is saved to the package data, such that it will be available for any R session in the same computer. The LISST-200X can be registered in the same way, but argument path must be the path to a binary data file from which the informations will be extracted. Once the LISST is registered, reading an data file is simple and can be performed in diferent ways:

#sn    <- 1298
#pl    <- 0.05
#yr    <- 2018 
#zscat <- system.file("extdata", "bg_20180326.asc", package = "lisst")

# For a processed file:
#flp   <- system.file("extdata", "DN_27_rs.asc", package = "lisst")
#lop   <- read_lisst(flp, sn, pl, zscat, yr)

# For a binary file:
#flb   <- system.file("extdata", "DN_27.DAT", package = "lisst")
#lob   <- read_lisst(flb, sn, pl, zscat, yr)

As the example shows, the function will determine the file type automaticly, based on its extension. In the example, the path length (pl, m) used and the year of first measurement (yr, required for LISST-100(x)) are provided, besides the background data file path (zscat). The first two can be omitted, and, with a warning, the function will use the standard path length for the instrument and apply a 'best guess' for yr (read the simple logic for this in the documentation of lgdate). The background file can also be omitted when reading a processed file or when reading a binary file when the requested output is raw digital counts (out = 'raw'). In the last case, however, further processing of the data (e.g., to VSF) will not be possible. Another variation that is worth noting is how to read a file for an instrument that is not registered - this is limited to the same cases when zscat can be omitted, and instead of providing sn, a model is sufficient.

#lom <- read_lisst(flp, pl = pl, yr = yr, model = "100CX")

As a final note, when reading a processed file or when reading a binary file as calibrated units (out = 'cal', the default for binary files) the lisst object will have an additional column, with date/time in POSIXct format.

The lisst object

The lisst object is a data.frame in wich the variables are of class units, and with attributes that hold information on the data and instrument. Those attributes are not expected to be manipulated directly by the user. It has essentially the same structure as the output of the LISST-SOP, except for the Time column. There is, however, a difference in the data read by read_lisst from the one produced by the LISST-SOP: uppon reading, the optical transmission and the beam attenuation are corrected to add effect of pure water. A correction is also applied in the rings digital counts for the binary data.

#lop[15, , drop = FALSE]
#lob[15, , drop = FALSE]

Processing

As of this version, is not yet possible to directly invert the PSD from the scattering data in the binary files. But is possible to convert between representations of the PSD (volume concentration x particle number concentration), different levels of processing of the binary data (digital counts x corrected digital counts x calibrated values) and retrieving the particle Volume Scattering Function form the calibrated values.

# Converting from vol conc to n conc:
#lop[15, 1:3, drop = FALSE]
#lget(lop, 'pnc')[15, 1:3, drop = FALSE]

# Converting from cal to VSF:
#lob[15, 1:3, drop = FALSE]
#lget(lob, 'vsf')[15, 1:3, drop = FALSE]

Is also possible to extract PSD model parameters. At the curent version, only the Junge model is available:

# Extract the Junge slope for a PSD:
#lfit(lop)[15:17]

Visualizing

The visualization use the common R plot function, with different plot types dependent on lisst object type. The units used in the axis can also be modified, but note that unit conversion is performed automaticly by the units package, such that if the original data units cannot be converted into the requested units, it will generate an error. Here is an example on the visualization of the particle VSF, the approximate particle phase function (normalization by c, not b), the number concentration and the volume concentration.

#lov <- lgetvsf(lob)
#par(mfcol = c(2, 2))
#plot(lov[40:144, ])
#plot(lop[40:144, ], type = 'pnc')
#plot(lov[40:144, ], type = 'pf', xu = 'degree')
#plot(lop[40:144, ], type = 'vol')

The most useful plot function however is the lhov, that produces a Hovmöller diagram per sample, time or depth, with automatic binning to regular intervals if ordinate dimension is irregular (most likelly to happen to depth ordinate, since time will be fixed intervals except when two lisst objects with different sampling intervals are combined). It is possible to normalize the data by the sum of teh values for all detectors and so separate variations in concentration from variations in distribution shape.

#lov <- lget(lob, 'vsf')
#lhov(lob, by = 'sample')
#lhov(lob, by = 'sample', norm = FALSE)


AlexCast/lisst documentation built on July 17, 2021, 12:58 a.m.