# RSKtools

Current stable version: 3.8.0 (2026-07-10)

RSKtools is a Matlab toolbox designed to help RBR users work with the
"RSK" SQLite data files generated by RBR instruments. This repository
is for the development version of the toolbox -- for the current
stable version go to:

[http://www.rbr-global.com/support/matlab-tools](http://www.rbr-global.com/support/matlab-tools)

Please note, RSKtools requires MATLAB R2013b or later, and we
recommend installing the freely
available [TEOS-10 GSW](http://www.teos-10.org/software.htm)
and
[cmocean](https://www.mathworks.com/matlabcentral/fileexchange/57773-cmocean-perceptually-uniform-colormaps) packages.


## What can RSKtools do?

* Open RSK files:
```matlab
rsk = RSKopen('sample.rsk');
```

* Print instrument information and a list of data channels:
```matlab
RSKprintchannels(rsk)
```

* Read data from RSK files:
```matlab
rsk = RSKreaddata(rsk);
```

* Plot a time series of the data:
```matlab
RSKplotdata(rsk);
```

* Low-pass filter selected channels:
```matlab
rsk = RSKsmooth(rsk,'channel',{'Conductivity','Temperature'},'windowLength',5);
```

* And lots of other stuff like automatic profile detection, sensor time
  alignment, bin averaging, and exporting data to CSV files.

## How do I get set up?

* Unzip the archive (to `~/matlab/RSKtools`, for instance).
* Add the RSKtools folder to your Matlab path by running either of the following at the command prompt:
    * `addpath ~/matlab/RSKtools`
    * `pathtool` and manually add RSKtools directory
* Type `help RSKtools` to get an overview and take a look at the examples.
* Read the [RSKtools User Manual](https://docs.rbr-global.com/rsktools).
* Check out [Getting started](https://rbr-global.com/wp-content/uploads/2024/01/GettingStarted.pdf)
  and [Post-processing](https://rbr-global.com/wp-content/uploads/2024/01/PostProcessing.pdf) for a quick start.

## A note on calculation of salinity

A typical RBR CTD (e.g., Concerto or Maestro) has sensors to measure
*in situ* pressure, temperature, and electrical conductivity. These
three variables are required to calculate seawater salinity, either
using the Practical Salinity Scale (PSS-78,
see
[Unesco, 1981](http://unesdoc.unesco.org/images/0004/000461/046148eb.pdf)),
or Absolute Salinity based on the Thermodynamic Equation of Seawater
2010 (see [IOC, SCOR and IAPSO, 2010](http://www.teos-10.org)).  If
the [TEOS-10 GSW](http://www.teos-10.org/software.htm) or [seawater](http://www.cmar.csiro.au/datacentre/ext_docs/seawater.htm) Matlab 
toolbox is installed, users can call the `RSKtools` function
`RSKderivesalinity` to calculate Practical Salinity and store it as a 
channel in the RSK structure.


## Contribution guidelines

* Feel free to add improvements at any time:
    * by forking and sending a pull request
    * by emailing patches or changes to `support@rbr-global.com`
* Write to `support@rbr-global.com` if you need help

## Changes
* Version 3.8.0 (2026-07-10)
    - New `RSKinairO2calibration` (and the `routines.inairO2calibration` routine) for in-air oxygen optode gain calibration, adding a corrected dissolved-O2 saturation and/or concentration channel
    - New `RSKimportbarometer` for barometric correction of sea pressure, matching Ruskin's barometer feature (RSK-14004…14008): imports an atmospheric-pressure series from a barometer `.rsk`, a `.csv`, a measured pressure channel of the same RSK, or an Nx2 `[utc_ms, dbar]` matrix; source EXCLUSION regions are skipped, marine samples outside the source's time range take the closest reading held constant, and a source that does not overlap the marine data at all is rejected with an error
    - `RSKderiveseapressure` automatically applies the attached barometer's per-sample atmospheric pressure when `patm` is not given; new `RSKremovebarometer` removes every barometer artefact and re-derives sea pressure (and any pre-existing depth) with the constant atmospheric pressure
    - `RSKopen` reads the barometer tables and channel groups; `RSK2RSKFULL` writes them back with the barometer artefacts, matching Ruskin's own output; on v2 (2.18.2) files only the correction's byproducts persist, and `RSK2RSK` warns that an EPdesktop export carries no barometer provenance
    - `RSKopen`/`RSKreaddata` now handle files with no deployment/epoch metadata (e.g. a barometer reference export) by falling back to a wide time window; `RSKderiveseapressure` falls back to the default atmospheric pressure when there is no `ATMOSPHERE` parameter; also fixed `readpowertable` erroring when `firmwareType` is empty
    - User-facing output (log entries, warnings/errors, plot titles, export filenames) now always uses the schedule label, never the numeric schedule id, and omits the qualifier on single-schedule files
    - Fixed a channel/data column index shift when a channel is hidden on pre-3.0.0 schema files
    - Revamped the Sphinx documentation (new theme and RBR branding)
* Version 3.7.0 (2026-06-08)
    - Support for 3.0.0 and 3.2.0 schema RSK files: new metadata/data table structure, multi-schedule data stored per schedule, and a label-based schedule API (functions take a schedule label such as `'s.CTD'` rather than a numeric ID)
    - Multi-schedule support across the toolbox: read, `RSKderive*`, post-processing, region/profile, export, and plot/view functions all operate per schedule
    - Cross-schedule fill so derivations whose inputs live on different schedules (e.g. dissolved O2 saturation, where O2 and temperature are on different schedules) are populated instead of NaN
    - Stricter derive-dependency policy: a required channel that exists but is entirely NaN now raises instead of producing NaN; an absent sea pressure channel is still auto-derived (with a warning); salinity is never auto-derived
    - `RSKderivesalinity` and `RSKderiveseapressure` now return only the RSK structure; `RSKderiveseapressure` accepts a per-schedule atmospheric pressure
    - Now it is possible to specify the channels to read data from for most of the derive functions
    - New `+routines` package of standalone, array-in / array-out processing functions, each in its own versioned file so it can be lifted into another project unchanged
    - New `routines.correcttempADCcal` (removes the periodic once-per-minute A2D self-calibration outliers from a temperature series) and its post-processor `RSKcorrecttempADCcal`, which adds a "Temperature Corrected" channel
    - Added `RSK2RSKFULL` (renamed from `RSK2RSKV300`) for exporting full 3.0.0+ schema RSK files, retaining the original file's metadata while adding the current session's changes (data, channels and regions); also updated `RSK2RSK` to handle different schemas, fixed `CSV2RSK`, and added `scheduleNumber`
    - Updated `RSKderiveBPR` to include updated channel lists
    - Unified the channel naming convention with pyRSKtools; temperature channels are renamed to descriptive names by sensor type
    - Added a `QuickStart`/`Demo.m` mirroring the pyRSKtools demo notebook, runnable end-to-end in MATLAB
    - Added Sphinx documentation and unified the help-text formatting across the toolbox
    - User-facing messages now refer to schedule labels rather than numeric schedule IDs
    - Extended `RSKwarning`/`RSKerror` to accept printf-style arguments
    - Fixed `RSK2RSK` leaving the mode-specific schedule table empty (which made Ruskin throw a cast error when opening an exported file) and not writing `channels.label`
    - Fixed `RSKderiveO2` appending a redundant O2 channel; `RSKcalculateCTlag` now requires conductivity and temperature in a single schedule
    - Detect the burst-data table name (`dataWave`) on v3.2.0 files; fixed the downsample query table name and a `tstamp` read error on the new schema
    - Fixed `RSKderiveseapressure` erroring on a multi-schedule file with no pressure channel
    - Fixed channel order when hidden channels are present, and hidden channels appearing in `RSK.channels`
    - Fixed a bug where channels' derived status were processed improperly
    - Fixed a bug where channels' longname was parsed incorrectly when there were multiple channels of the same type
    - Normalised prose to British English, fixed typos, and corrected docstring/code mismatches

* Version 3.6.0 (2024-01-04)
    - RSKtools support the mksqlite MEX file for macOS with Apple silicon
    - New function `RSKderiveAPT` to derive accelerations and the temperature for the Triax accelerometer
    - RSKtools support case-insensitive input arguments
    - RSKtools support reading unitsPlainText field
    - Bug fix `RSKimages` regarding the selection of unit time for `showGap` option.
    - Bug fix `RSKopen` regarding `readHiddenChannels`
    - Bug fix `RSKcentrebursttimestamp` due to `samplingCount` field change in RSK schema
    - Bug fix for `channelID` updates for all derivation functions
    - Bug fix for `RSKbinaverage` to stop adding one more bin out of the boundary
    - Improve `RSKreadprofiles` to be independent of RSK.region.type
    - Bug fix for `RSKcomputeprofiles`, `RSKdetectprofiles` by considering NaN values in `pressure` channel.
    - Accommodate short name changes for RBRquartz3 Q `period` channels.   

* Version 3.5.3 (2021-09-22)
    - Bug fix reading RSK files without/or unpopulated instrumentChannels table
    - Bug fix reading RSK files without instrumentID columns in instruments table
    - Workaround for Ruskin bug (RSK-8255) with trailing space at the end of channels long names.

* Version 3.5.2 (2021-08-09)
    - Bug fix compatibility with RSK generated by the RBRcervata

* Version 3.5.1 (2021-07-28)
    - Bug fix compatibility with RSK generated by the RBRcervata

* Version 3.5.0 (2020-06-26)

    - New function `RSKderiveA0A` for applying A-zero-A drift correction to BPR data from the RBRquartz BPR|zero.
	- `RSKderiveBPR` now supports RBRquartz instruments with multiple Digiquartz® sensors
	- Quickstart pdfs updated on [(RSKtools support page)](https://rbr-global.com/support/matlab-tools)

* Version 3.4.1 (2020-04-09)

    - `CSV2RSK` is compatible with Wirewalker CSV files downloaded from the RBR data hosting website.
    - `CSV2RSK` and `RSK2RSK` now handle encoding scheme without SIMULINK.
    - `CSV2RSK` and `readsamplingperiod` now supports the directional dependent (DD) CTD sampling mode.
    - `RSKplotdata`, `RSKplotburstdata` and `RSKplotdownsample` now reverse the y-axis for `depth` channel. 
    - `RSKplotdata` `showcast` option now works for both `pressure` and `sea pressure` channels.
    - `RSKtrim` log entry shows time period correctly when `reference` is set to `time`.

* Version 3.4.0 (2020-02-14)

    - All RSKtools functions now require name-value pair format for input arguments except when specifying the RSK structure and filename.
    - More derivation functions now support CSIRO seawater library, including `RSKderivesalinity`, `RSKderivedepth`, `RSKderivebuoyancy`, `RSKderivetheta` and `RSKderivesigma`.
    - New function `RSKderivesoundspeed` to derive speed of sound in seawater.
    - New function `CSV2RSK` to read CSV file into rsk structure.
    - New functions `RSKsettings` and `RSKdefaultsettings` to set up global parameters for RSKtools.
    - New function `RSKprintchannels` to display channel names and units in MATLAB command window.
    - New functions `RSKerror` and `RSKwarning` to better handle error and warning messages.
    - Fixed bug that `RSKderiveO2` could not recognise saturation/concentration channel correctly.
    - Fixed bug that `RSKgenerate2D` required user to specify cast direction when only upcast is available.
    - Fixed bug that `RSKreaddata` could not recognise derived and hidden channels correctly.
    - Export functions now adjust file path separator to be compatible across operating systems.
    - `RSK2RSK` now uses millisecond for sampling period unit.
    - Subfolder `Utilities` renamed to `private`.
    - `Utilities/loadconstants` removed.
    - `RSKreaddata` now handles cases when file type is not available.
    - `RSKderivetheta` and `RSKderivesigma` now check if Absolute Salinity exists before calculation.
    - `RSKderivebuoyancy` now recognises latitude input by `RSKaddstationdata`.

* Version 3.3.0 (2019-11-15)

    - New function `RSKderivesigma` to calculate density anomaly.
    - New function `RSKderivetheta` to calculate potential temperature.
    - New function `RSKderiveSA` to calculate absolute salinity.
    - `RSKderivesalinity` allows to choose seawater or TEOS-10 toolboxes.
    - `RSKderiveBPR` allows coefficients as optional input.
    - `RSKcorrectTM` handles NaN values in temperature channel correctly.
    - `RSKimages`, `RSKplotdownsample` and `RSKplotburstdata` can output axes objects.
    - `RSK2RSK` handles DDsampling (different sampling rate during up and downcasts) correctly.
    - Fixed bug that `RSKimages` won't work for rsk with upcasts only when not specifying cast direction.
    - `RSKreadburstdata` locates pressure channel correctly for multi-channel instruments.
    - Visualisation functions will not output handles when not specified.
    - Removed dependency on `stats` toolbox.
    - Integrated functions for reading different rsk file types into `Utilities/readheader`.
    - Optimised legend location for `RSKplotprofiles`.

* Version 3.2.0 (2019-07-16)

    - New function `RSKcorrecttau` to apply Fozdar et al. (1985) algorithm for sharpening sensor response (e.g., O2).
    - New function `RSKcreate` to convert any data (e.g., other CTDs, gliders, floats) into rsk structure.
    - RSKtools correctly handles cases when the number of downcasts and upcasts is not the same.
    - `RSKaddmetadata` renamed to `RSKaddstationdata`.
    - `RSKaddstationdata` now allows adding station data to time series data.
    - `RSKtrim` now requires `reference` and `range` as mandatory inputs.
    - Simplify `RSK2RSK` schema by removing the events, errors, and downloads tables.
    - `RSKfindprofiles` now uses sea pressure to detect profiles when pressure channel is missing.
    - `RSKplotdata` returns an error when `showcast` is set to true while pressure channel is missing.
    - `RSKopen` now reads instrumentSensors table if it exists.
    - `RSKderivesalinity` now sets sea pressure to 0 dbar when pressure channel is absent.
    - Fixed bug that caused `RSKbinaverage` not to work when bin averaging an upcast by time.
    - Fixed bug that caused `RSK2CSV` and `RSK2ODV` not to work when `profile` field is missing.
    - `Utilities/getchannelindex` now allows multiple channel inputs and outputs.

* Version 3.1.0 (2019-03-04)

    - New function `RSKcentrebursttimestamp` to set the burst timestamps to the centre of each burst period instead of the beginning.
    - `RSKplotprofiles` returns an error for rsk files containing only a pressure channel (e.g., soloD).
    - Fixed bug that caused `readdownsample` not to work when `readHiddenChannels` was set to true.
    - `RSKreaddata` now reads derived channels for RBRcoda T.ODO.
    - `RSKreaddata` now converts `NULL` values into `NaN`s instead of zeros.
    - Improved speed when bin averaging by time with `RSKbinaverage`.
    - `readfirmwarever` and `readsamplingperiod` are now compatible with rsk files generated by `RSK2RSK`.
    - `RSKfindprofiles` only deletes the profile field when new profiles are detected.

* Version 3.0.0 (2018-11-14)

    - New function `RSK2RSK` for writing the RSKtools rsk MATLAB structure into a new rsk file. 
    - New function `RSKcorrectTM` to correct conductivity for the thermal inertia effect.
    - New function `RSKderivebuoyancy` for deriving buoyancy frequency and stability. 
    - New function `RSKderiveO2` for converting between oxygen concentration and saturation.
    - New function `RSKplotTS` for plotting T-S diagrams.
    - New function `RSKgenerate2D` for generating 2D data with time as x-axis and reference channel (e.g., depth) as y-axis.
    - New function `RSKtimeseries2profiles` for organizing a time series into discrete profiles without reading from the rsk file on disk.
    - `RSKreadprofiles` now only reads data from the rsk file on disk.
    - `RSKselectdowncast` and `RSKselectupcast` are replaced by `RSKremovecasts`.
    - Renamed the following functions that are typically called internally:
        * `RSKfirmwarever` to `readfirmwarever`
        * `RSKgetprofiles` to `getprofiles`
        * `RSKreaddownsample` to `readdownsample`
        * `RSKreadevents` to `readevents`
        * `RSKreadgeodata` to `readgeodata`
        * `RSKsamplingperiod` to `readsamplingperiod`
        * `RSKver` to `returnversion`
        * `RSKreadannotations` to `readannotations`
        * `RSKconstants` to `loadconstants`
        * `datenum2RSKtime` to `datenum2rsktime`
        * `RSKtime2datenum` to `rsktime2datenum`
    - Move subfunctions that are mostly for internal use into folder ../rsktools/Utilities/ 
    - Synchronises plot limits using linkaxes in visualisation mode of all post-processing functions.
    - Plot downcast only when both downcast and upcast are processed in visualisation mode.
    - Revise `RSKalignchannel` visualize mode by plotting against time instead of sea pressure.
    - Make x-axis tight in `RSKplotdata` and `RSKimages`.
    - `RSKderiveseapressure` allows variable atmosphere pressure input.
    - Exclude pressure and sea pressure channel from being NaN in `RSKremoveloops`.
    - Input argument `rhc` in `RSKopen` is renamed to `readHiddenChannels`, whose type is changed from numeric (1 or 0) to boolean (true or false).
    - Input argument `showcast` type in `RSKplotdata` is changed from numeric (1 or 0) to boolean (true or false).
    - `RSKplot2D` renamed to `RSKimages`.
    - `RSKimages` (formerly `RSKplot2D`) optional input `interp` renamed as `showgap`.
    - `RSKimages` defaults to operate on all channels.
    - Unit of input argument `threshold` in `RSKimages` is changed from hours to seconds.
    - When bin averaging by time, the `binSize` argument in `RSKbinaverage` is now specified in seconds instead of days.
    - Fixed bug that `RSKreaddata` mislabels channels when reading wave file.

* Version 2.3.1 (2018-06-20)

    - Fixed bug in `RSKcorrecthold` when one channel contains zero value only
    - Changed input variable name pressure to seapressure in `calculatedepth.m`
    - Removed thumbnail data from the rsk structure; use downsample for a quick overview of the dataset

* Version 2.3.0 (2018-05-09)

    - New function `RSK2ODV` for outputting RSK structure into Ocean Data View (ODV) files.
    - New function `RSKaddmetadata` for adding station metadata to profiles.
    - `RSKopen` now reads Ruskin annotations including latitude, longitude, comment, and description.
    - `RSKreadprofiles` assigns latitude, longitude, comment and description annotations into data structure.
    - Fixed bug that `RSKplot2D` was not aligning profile with correct time stamp. 
    - Added option that `RSKplot2D` could determine the length of gap shown on the plot.
    - Visualisation mode added to `RSKalignchannel`,`RSKbinaverage`,`RSKcorrecthold`,`RSKdespike`,`RSKremoveloops`,`RSKsmooth` and `RSKtrim` to show differences before and after alteration of data.
    - `RSKtrim` input `appliedchannel` changed to `channel`.
    - Option to choose cast direction to write with `RSK2CSV`.
    - `RSK2CSV` will write station metadata to the file CSV file header.
    - `showcast` option added in `RSKplotdata` to show cast detection events overlaid on pressure.
    - Added profile number and cast direction as legend in the last subplot in `RSKplotdata`.

* Version 2.2.0 (2018-01-25)
    - New function `RSKcorrecthold` for correcting A2D zero-order hold points.
    - New function `RSKaddchannel` for adding new variable into existing rsk structure.
    - New function `RSKderiveC25` for deriving specific conductivity at 25 degree Celsius.
    - New function `RSKderiveBPR` for deriving pressure and temperature from period data with bottom pressure recorder (BPR) channels.
    - New function `RSK2CSV` for writing logger data to CSV files.
    - New functions `RSKreaddownsample` and `RSKplotdownsample` for reading and plotting downsample data.
    - mksqlite upgraded to Version 2.5
    - Fixed bug that `RSKopen` imports wrong data table when multiple files are opened.
    - Fixed bug that `RSKfindprofile` does not always detect upcast correctly.
    - Added option to specify lag in units of time in `RSKalignchannel`.
    - Option added in `RSKopen` to read hidden channels 
    - `RSKopen` now reads power table for certain logger firmware versions.
    - Added interpolation option in `RSKtrim`.
    - Added `Optode Temperature` channel long name.
    - Improved algorithm for `RSKbinaverage`.
    - Improved algorithm for finding pressure reversals in `RSKremoveloops`.
    - Added `direction` and `profilenumber` fields to `rsk.data` with profiles.
    - `RSKplotprofiles` uses different line styles for upcast and downcast.
    - Added option in `RSKplotprofiles` to plot against total pressure.

* Version 2.1.0 (2017-08-31)
    - New function `RSKtrim` for pruning data
    - Improved vignettes
    - Option to plot against depth in `RSKplotprofiles`
    - Fixed `RSKplotprofiles` for compatibility with pre-R2014b
    - Fixed `RSKcalculateCTlag` and `RSKdespike` for compatibility with pre-R2015a
    - pressureRange option in `RSKcalculateCTlag` now seapressureRange
    - Removed dependence on Financial Toolbox in `RSKbinaverage`
    - Fixed bug occurring when RSK file has multiple dissolved oxygen channels
    - Enumerate channels with duplicate longName

* Version 2.0.0 (2017-07-07)
    - All optional input arguments are name-value pair
    - Rename burstdata field to burstData
    - Add post-processing functions for smoothing, channel alignment, etc.
    - RSKtools data processing log recorded in RSK structure 
    - Add 2D plotting function, `RSKplot2D`
    - RSKplotprofiles contains a subplot for each channel
    - Add option to plot selected channels to plotting functions
    - Plotting functions output handles to line objects for customization
    - Relocate profiling data from the profiles field to the data field
    - Added function to calculate Practical Salinity, `RSKderivesalinity`
    - Added function to calculate sea pressure from total pressure, `RSKderiveseapressure`
    - Added function to calculate depth, `RSKderivedepth`
    - Added function to calculate profiling speed, `RSKderivevelocity`
    - Cast detection function added, `RSKfindprofiles`

* Version 1.5.3 (2017-06-07)
    - Use atmospheric pressure in database if available
    - Improve channel table reading by using instrumentChannels
    - Change geodata warning to a display message
    - Only read current parameter values in parameter table

* Version 1.5.2 (2017-05-23)
    - Update RSKconstants.m
    - Fix bug with opening files that are not in current directory

* Version 1.5.1 (2017-05-18)
    - Add RSKderivedepth function
    - Add RSKderiveseapressure function
    - Add channel longName change for doxy09
    - Add filename check to RSKopen
    - Fix bug with dbInfo 1.13.0
    - Add channel argument to RSKplotdata
    - Fix bug introduced in 1.5.0 in RSKreaddata from dbInfo.version < 1.8.9.

* Version 1.5.0 (2017-03-30)
    - Move salinity derivation from RSKreaddata to RSKderivesalinity
    - Move calibrations table reading from RSKopen to RSKreadcalibrations
    - Add RSKfirmwarever function
    - Add RSKsamplingperiod function
    - Add channel longName change for temp04, temp05, temp10 and temp13
    - Remove dataset and datasetDeployments fields
    - Fix bug with loading geodata
    - Support for RSK v1.13.8


* Version 1.4.6 (2017-01-18)
    - Remove non-marine channels from data table
    - Fix bugs that occurred if RSKreaddata.m is run twice
    - Separate profile metadata reading into a different function in RSKopen.m
    - Add option to enter UTCdelta for geodata
    - Remove channels units and longName from data table
    - Fix bug in data when reading in profile data


* Version 1.4.5 (2016-12-22)
    - Add more support for geodata
    - Add helper files to open different file types
    - Add function to read version of file


* Version 1.4.4 (2016-12-15)
    - Add support for geodata
    - Assure that non-marine channel stay hidden
    - Add RSK2MAT.m for legacy mat file users
    - Update support for coefficients and parameter tables


* Version 1.4.3 (2016-11-03)
    - Events structure does not read in notes
    - Fix dbInfo bug to read last entry
    - Support for RSK v1.13.4


* Version 1.4.2 (2016-10-20)
    - Changed removal of 'datasetID' to be case insensitive
    - Fix upcast/downcast type in RSKplotprofiles
    - Fix RSKreadprofile typo
    - Fix bug opening |rt instruments data


* Version 1.4.1 (2016-05-20)
    - Add RSKreadwavetxt to handle import wave text exports	
    - properly read "realtime" RSK files
    - don't plot hidden channels in profiles
    - Fix bug reading data table for RSK version >= 1.12.2
    - add info from `ranging` table to structure
    - mfile vignette using Matlab markup
  

* Version 1.4 (2015-11-30)
    - add support for profile events and profile plotting
    - supports TEOS-10 for calculation of salinity
    - improved documentation
  

* Version 1.3
    - compatible with RSK generated from an EasyParse (iOs format) logger


* Version 1.2

    - added linux 64 bit mksqlite library


* Version 1.1

    - added burst and event readers

