-
Notifications
You must be signed in to change notification settings - Fork 10
Exploring and Visualizing Slocum Glider Data: Dbd Class
Wiki ▸ Cookbook ▸ Exploring 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:
- What sensors are contained in the file?
- How do timestamp and depth sensor selection affect data set integrity?
- 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).
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:
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.
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:
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();
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:
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:
These images provide a clear illustration of the significance of timestamp and depth sensor selection on the resulting data set.
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:
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: