Skip to content

Exploring and Visualizing Slocum Glider Data: Dbd Class

John Kerfoot edited this page Aug 28, 2019 · 7 revisions

WikiCookbookExploring and Visualizing Slocum Glider Data: Dbd Class

So you've got a native Slocum glider data file and you'd like to start exploring the contents. Some of the questions you may ask:

  1. What sensors are contained in the file?
  2. How do timestamp and depth sensor selection affect data set integrity?
  3. Does the file contain profiles and, if they do, how can I see them?

All of these questions (and many more) are easily answered using the Dbd class. Let's start answering the questions one by one. First we need to load our data file and create an instance of the Dbd class. Let's get the list of files we want to explore:

>> pwd

ans =

/home/kerfoot/sandbox/glider/deployments-test/2013/ru22-397/ascii/sbd

>> dbds = listDbds('ext', 'dat')

dbds = 

    '/home/kerfoot/sandbox/glider/deployments-test/2013/ru22-397/ascii/sbd/ru22_2013_271_0_0_sbd.dat'
    '/home/kerfoot/sandbox/glider/deployments-test/2013/ru22-397/ascii/sbd/ru22_2013_271_0_3_sbd.dat'
    '/home/kerfoot/sandbox/glider/deployments-test/2013/ru22-397/ascii/sbd/ru22_2013_271_0_4_sbd.dat'
    '/home/kerfoot/sandbox/glider/deployments-test/2013/ru22-397/ascii/sbd/ru22_2013_271_0_5_sbd.dat'
    '/home/kerfoot/sandbox/glider/deployments-test/2013/ru22-397/ascii/sbd/ru22_2013_271_0_6_sbd.dat'
    '/home/kerfoot/sandbox/glider/deployments-test/2013/ru22-397/ascii/sbd/ru22_2013_271_0_7_sbd.dat'
    '/home/kerfoot/sandbox/glider/deployments-test/2013/ru22-397/ascii/sbd/ru22_2013_271_0_8_sbd.dat'
    '/home/kerfoot/sandbox/glider/deployments-test/2013/ru22-397/ascii/sbd/ru22_2013_271_0_9_sbd.dat'
    '/home/kerfoot/sandbox/glider/deployments-test/2013/ru22-397/ascii/sbd/ru22_2013_271_0_10_sbd.dat'
    '/home/kerfoot/sandbox/glider/deployments-test/2013/ru22-397/ascii/sbd/ru22_2013_271_0_11_sbd.dat'
    '/home/kerfoot/sandbox/glider/deployments-test/2013/ru22-397/ascii/sbd/ru22_2013_271_0_12_sbd.dat'

Next, load a single file and create an instance of the Dbd class:

>> dbd = Dbd(dbds{1})

dbd = 

  Dbd with properties:

                 glider: 'ru22'
                segment: 'ru22_2013_271_0_0'
             sourceFile: '/home/kerfoot/sandbox/glider/deployments-test/2013/ru22-397/ascii/sbd/ru22_2013_271_0_0_sbd.dat'
         the8x3filename: '01270000'
               filetype: 'sbd'
                  bytes: 545577
                   rows: 1785
                sensors: {73x1 cell}
            sensorUnits: [1x1 struct]
           startDatenum: 735506.75751717
             endDatenum: 735506.889813181
              startTime: '2013-09-29 18:10:49'
                endTime: '2013-09-29 21:21:19'
        timestampSensor: 'drv_m_present_time_datenum'
            depthSensor: 'drv_m_pressure'
    dbdTimestampSensors: {6x1 cell}
        dbdDepthSensors: {4x1 cell}
            profileInds: [30x2 double]
            numProfiles: 30
              fillTimes: 'none'
         proMinTimeSpan: 8
        proMinNumPoints: 2
             fillDepths: 'none'
            proMinDepth: 1
        proMinDepthSpan: 2
                fillGps: 'none'
         hasBoundingGps: 1
                scratch: []

We see that this is segment ru22_2013_271_0_0 , which is an sbd file from a deployment of glider ru22. The file contains 1,785 rows. drv_m_present_time_datenum and drv_m_pressure were chosen as the default timestamp and depth/pressure sensors, repsectively and indexing of the depth time-series resulted in 30 profiles (numProfiles).

Glider File Sensors

The instance contains 73 sensors, most of which were included in the data file with a few derived (sensor names prefixed with drv) sensors created during instantiation. Let's take a look at the sensor frequency using the Dbd.plotSensorMap method of the instance:

>> dbd.plotSensorMap();

Here's what the sensor map looks like: ru22-2013-271-0-0-sbd_sensorMap

This plot provides a quick view of the content of each sensor data array, independent of the chosen timestamp. Colored points denote non-NaN values. You can see that the majority of the sensor data arrays were not logged continuously over the file time frame and that many of the sci sensor values are pretty consistently reported.

Timestamp and Depth Sensor Selection

Now that have a rough idea of what the data set looks like, let's create a similiar plot. This time, however, we'll plot the available sensor data with respect to the chosen timestamp which, in this case is drv_m_present_time_datenum:

ru22-2013-271-0-0-sbd_sampleMap-m_present_time

Now, let's change the Dbd.timestampSensor and the re-plot the sample map using the new timestamp:

>> dbd.timestampSensor = 'drv_sci_m_present_time_datenum'

dbd = 

  Dbd with properties:

                 glider: 'ru22'
                segment: 'ru22_2013_271_0_0'
             sourceFile: '/home/kerfoot/sandbox/glider/deployments-test/2013/ru22-397/ascii/sbd/ru22_2013_271_0_0_sbd.dat'
         the8x3filename: '01270000'
               filetype: 'sbd'
                  bytes: 545577
                   rows: 1785
                sensors: {73x1 cell}
            sensorUnits: [1x1 struct]
           startDatenum: 735506.75751717
             endDatenum: 735506.889813181
              startTime: '2013-09-29 18:10:49'
                endTime: '2013-09-29 21:21:19'
        timestampSensor: 'drv_sci_m_present_time_datenum'
            depthSensor: 'drv_m_pressure'
    dbdTimestampSensors: {6x1 cell}
        dbdDepthSensors: {4x1 cell}
            profileInds: []
            numProfiles: 0
              fillTimes: 'none'
         proMinTimeSpan: 8
        proMinNumPoints: 2
             fillDepths: 'none'
            proMinDepth: 1
        proMinDepthSpan: 2
                fillGps: 'none'
         hasBoundingGps: 1
                scratch: []

Notice that number of indexed profiles has changed from 30 to 0. Why? Since the select timestamp sensor is measured on the glider's science controller and the selected pressure sensor is recorded by the glider's flight controller, as is often the case, the 2 sensor data arrays contain at least on NaN value. The resulting depth-time series is incomplete and results in no indexed profiles. Now let's look at the sensor map with respect to the newly selected timestamp:

>> dbd.plotSampleMap();

ru22-2013-271-0-0-sbd_sampleMap-sci_m_present_time

What happened? All we did was change the Dbd.timestampSensor property. This is a striking example of how selection of the Dbd instance timestamp and depth sensor affects data set integrity. In the first example, we're using drv_m_present_time_datenum and using drv_sci_m_present_time_datenum in the second. Here's the explanation: m_present_time is measured on the flight controller, which writes sbd files, and sci_m_present_time is measured on the science controller, which writes tbd files. These 2 files are then transferred to shore and manually merged. All sci sensors are also measured on the science controller while the rest of the sensors are measured on the flight controller. Differences in sampling strategy employed by the glider operator as well as the glider's timestamping result in significantly different results.

Let's take a look at how this affects the depth time-series profile indexing. First, we'll use a timestamp and depth sensor from the flight controller and plot the depth time-series:

>> dbd.timestampSensor = 'drv_m_present_time_datenum'
>> dbd.depthSensor = 'drv_m_pressure'

dbd = 

  Dbd with properties:

                 glider: 'ru22'
                segment: 'ru22_2013_271_0_0'
             sourceFile: '/home/kerfoot/sandbox/glider/deployments-test/2013/ru22-397/ascii/sbd/ru22_2013_271_0_0_sbd.dat'
         the8x3filename: '01270000'
               filetype: 'sbd'
                  bytes: 545577
                   rows: 1785
                sensors: {73x1 cell}
            sensorUnits: [1x1 struct]
           startDatenum: 735506.75751717
             endDatenum: 735506.889813181
              startTime: '2013-09-29 18:10:49'
                endTime: '2013-09-29 21:21:19'
        timestampSensor: 'drv_sci_m_present_time_datenum'
            depthSensor: 'drv_m_pressure'
    dbdTimestampSensors: {6x1 cell}
        dbdDepthSensors: {4x1 cell}
            profileInds: []
            numProfiles: 0
              fillTimes: 'none'
         proMinTimeSpan: 8
        proMinNumPoints: 2
             fillDepths: 'none'
            proMinDepth: 1
        proMinDepthSpan: 2
                fillGps: 'none'
         hasBoundingGps: 1
                scratch: []

>> dbd.plotYo();

Here's the plot: ru22-2013-271-0-0-sbd_yoProfile-flight

Now, let's use science controller timestamp and depth sensors:

>> dbd.timestampSensor = 'drv_sci_m_present_time_datenum';
>> dbd.depthSensor = 'drv_sci_water_pressure'

dbd = 

  Dbd with properties:

                 glider: 'ru22'
                segment: 'ru22_2013_271_0_0'
             sourceFile: '/home/kerfoot/sandbox/glider/deployments-test/2013/ru22-397/ascii/sbd/ru22_2013_271_0_0_sbd.dat'
         the8x3filename: '01270000'
               filetype: 'sbd'
                  bytes: 545577
                   rows: 1785
                sensors: {73x1 cell}
            sensorUnits: [1x1 struct]
           startDatenum: 735506.75751717
             endDatenum: 735506.889813181
              startTime: '2013-09-29 18:10:49'
                endTime: '2013-09-29 21:21:19'
        timestampSensor: 'drv_sci_m_present_time_datenum'
            depthSensor: 'drv_sci_water_pressure'
    dbdTimestampSensors: {6x1 cell}
        dbdDepthSensors: {4x1 cell}
            profileInds: [14x2 double]
            numProfiles: 14
              fillTimes: 'none'
         proMinTimeSpan: 8
        proMinNumPoints: 2
             fillDepths: 'none'
            proMinDepth: 1
        proMinDepthSpan: 2
                fillGps: 'none'
         hasBoundingGps: 1
                scratch: []

>> dbd.plotYo();

Here's the plot: ru22-2013-271-0-0-sbd_yoProfile-science

These images provide a clear illustration of the significance of timestamp and depth sensor selection on the resulting data set.

File Metadata: Profiles

Since we ultimately want to look at water column properties, let's stick with our choices of drv_sci_m_present_time and drv_sci_water_pressure for Dbd.timestampSensor and Dbd.depthSensor, respectively and start looking at profile data:

>> dbd

dbd = 

  Dbd with properties:

                 glider: 'ru22'
                segment: 'ru22_2013_271_0_0'
             sourceFile: '/home/kerfoot/sandbox/glider/deployments-test/2013/ru22-397/ascii/sbd/ru22_2013_271_0_0_sbd.dat'
         the8x3filename: '01270000'
               filetype: 'sbd'
                  bytes: 545577
                   rows: 1785
                sensors: {73x1 cell}
            sensorUnits: [1x1 struct]
           startDatenum: 735506.75751717
             endDatenum: 735506.889813181
              startTime: '2013-09-29 18:10:49'
                endTime: '2013-09-29 21:21:19'
        timestampSensor: 'drv_sci_m_present_time_datenum'
            depthSensor: 'drv_sci_water_pressure'
    dbdTimestampSensors: {6x1 cell}
        dbdDepthSensors: {4x1 cell}
            profileInds: [14x2 double]
            numProfiles: 14
              fillTimes: 'none'
         proMinTimeSpan: 8
        proMinNumPoints: 2
             fillDepths: 'none'
            proMinDepth: 1
        proMinDepthSpan: 2
                fillGps: 'none'
         hasBoundingGps: 1
                scratch: []

The data file contains 14 profiles, with the row indices for the stop and start positions of these profiles are accessible via the Dbd.profileInds property:

>> dbd.profileInds

ans =

          65         182
         182         276
         334         453
         453         554
         585         708
         708         798
         830         957
         957        1037
        1066        1188
        1188        1271
        1299        1406
        1406        1487
        1517        1631
        1631        1717

Using the Dbd.plotProfiles method, we can quickly create a plot of the temperature profiles:

>> dbd.plotProfiles('sci_water_temp');

>> get(gcf, 'Tag')

ans =

ru22_2013_271_0_0_sci-water-temp_profiles

>> print(gcf, '-dpng', '-r300', fullfile('/www/home/kerfoot/public_html/pub/git-images/Dbd', [get(gcf, 'Tag') '.png']))

Here's the image that's created:

ru22_2013_271_0_0_sci-water-temp_profiles.png

The profiles are color coded using the jet colormap according to chronological order (blue -> green -> yellow -> orange -> red). Clicking on a profile will highlight it and display basic profile metadata:

ru22_2013_271_0_0_sci-water-temp_profiles-metadata.png