Monitoring and the SamplingPoint object - Part 4

Abstract

After Monitoring and the SamplingPoint object - Part 3 we had reviewed various methods of encoding blocks of tabular data in XML and identified a number of previous implementations of this construct (WITSML, SensorML).

This article details how DIGGSML builds on the implementations in WITSML and SensorML and implements a generic Table structure for storing lots of repeating Monitoring data.

Previous implementations

SensorML

The implementation of SensorML's swe:DataArray is very comprehensive, including both ASCII and Binary data encoding. This was a problem for DIGGSML since the aim has been to reduce the transfer of Binary data, importing the swe:DataArray element verbatim from SensorML would not allow DIGGSML to restrict its contents to ASCII data and therefore was not suitable. SensorML however did have a very well defined dictionary of terms, it was decided that since these terms already existed defining what was meant by a Sensor, Detector or Measurement that DIGGSML would use the same terminology so that there was no need to learn two different sets of terms if you already knew SensorML. This would also aid in keeping DIGGSML compatible with SensorML and aid the transformation between the two with XSLT stylesheets.

SensorML also had the drawback that reporting measurements with respect to a coordinate reference system or an axis was complicated and lengthy, DIGGSML tries to reduce the complexity of reporting these results by allowing Detectors to include a CRS indicating their axis and sign convention.

WITSML

Monitoring and the SamplingPoint object - Part 3 showed us how John Bobbitt of WITSML had written a paper on transfering tabular data in XML, after emailing John he sent me an example of how this was implemented in WITSML with the WellLog object.

Example 1 - WITSML WellLog (from John Bobbitt of Energistics)

<wellLog uidWell="" uidWellbore="1" uid="1">
  <nameWell>NPR-3 25-1-X-14</nameWell>
  <nameWellbore>NPR-3 25-1-X-14</nameWellbore>
  <name>NPR-3 25-1-X-14</name>
  <serviceCompany>Schlumberger</serviceCompany>
  <creationDate>2002-04-05T12:00:00.000</creationDate>
  <indexType>measured depth</indexType>
  <minIndex>722.0</minIndex>
  <maxIndex>5952.0</maxIndex>
  <logParam index="1" description="RUN NUMBER" name="RUN" uom="N/A">1</logParam>
  <logParam index="2" description="Permanent Datum" name="PDAT" uom="N/A">GROUND LEVEL</logParam>
  <logParam index="3" description="Elevation of Permanent Datum above Mean Sea Level" name="EPD" uom="ft">5214.799805</logParam>
  <logParam index="4" description="Logging Measured From (Name of Logging Elevation Reference)" name="LMF" uom="N/A">KELLY BUSHING</logParam>
  <logParam index="5" description="Elevation of Depth Reference (LMF) above Permanent Datum" name="APD" uom="ft">10.000000</logParam>
  <logCurveInfo uid="0">
    <mnemonic>DEPT</mnemonic>
    <classWitsml>dept</classWitsml>
    <unit>ft</unit>
    <nullValue>-999.25</nullValue>
    <curveDescription>DEPTH (BOREHOLE)</curveDescription>
    <typeLogData>double</typeLogData>
  </logCurveInfo>
  <logCurveInfo uid="1">
    <mnemonic>HAZI</mnemonic>
    <classWitsml>hazi</classWitsml>
    <unit>dega</unit>
    <nullValue>-999.25</nullValue>
    <curveDescription>Hole Azimuth</curveDescription>
    <typeLogData>double</typeLogData>
  </logCurveInfo>
  <logCurveInfo uid="2">
    <mnemonic>SDEV</mnemonic>
    <classWitsml>sdev</classWitsml>
    <unit>dega</unit>
    <nullValue>-999.25</nullValue>
    <curveDescription>Sonde Deviation</curveDescription>
    <typeLogData>double</typeLogData>
  </logCurveInfo>
  <logCurveInfo uid="3">
    <mnemonic>ED</mnemonic>
    <classWitsml>ed</classWitsml>
    <unit>ft</unit>
    <nullValue>-999.25</nullValue>
    <curveDescription>East Departure</curveDescription>
    <typeLogData>double</typeLogData>
  </logCurveInfo>
  <logCurveInfo uid="4">
    <mnemonic>ND</mnemonic>
    <classWitsml>nd</classWitsml>
    <unit>ft</unit>
    <nullValue>-999.25</nullValue>
    <curveDescription>North Departure</curveDescription>
    <typeLogData>double</typeLogData>
  </logCurveInfo>
  <logCurveInfo uid="5">
    <mnemonic>TVDE</mnemonic>
    <classWitsml>tvde</classWitsml>
    <unit>ft</unit>
    <nullValue>-999.25</nullValue>
    <curveDescription>True Vertical Depth</curveDescription>
    <typeLogData>double</typeLogData>
  </logCurveInfo>
  <logCurveInfo uid="6">
    <mnemonic>VSEC</mnemonic>
    <classWitsml>vsec</classWitsml>
    <unit>ft</unit>
    <nullValue>-999.25</nullValue>
    <curveDescription>Vertical Section</curveDescription>
    <typeLogData>double</typeLogData>
  </logCurveInfo>
  <logCurveInfo uid="7">
    <mnemonic>GR</mnemonic>
    <classWitsml>gr</classWitsml>
    <unit>gAPI</unit>
    <nullValue>-999.25</nullValue>
    <curveDescription>Gamma Ray</curveDescription>
    <typeLogData>double</typeLogData>
  </logCurveInfo>
  <blockInfo blockId="0">
    <pass>1</pass>
    <description>main log section</description>
    <indexType>measured depth</indexType>
    <startIndex>722.0</startIndex>
    <endIndex>5952.0</endIndex>
    <stepIncrement uom="F">0.5</stepIncrement>
    <direction>increasing</direction>
    <nullValue>-999.25</nullValue>
    <blockCurveInfo>
      <curveId>0</curveId>
      <columnIndex>1</columnIndex>
      <minIndex>722.0</minIndex>
      <maxIndex>5952.0</maxIndex>
    </blockCurveInfo>
    <blockCurveInfo>
      <curveId>1</curveId>
      <columnIndex>2</columnIndex>
      <minIndex>722.0</minIndex>
      <maxIndex>5952.0</maxIndex>
    </blockCurveInfo>
    <blockCurveInfo>
      <curveId>2</curveId>
      <columnIndex>3</columnIndex>
      <minIndex>722.0</minIndex>
      <maxIndex>5952.0</maxIndex>
    </blockCurveInfo>
    <blockCurveInfo>
      <curveId>3</curveId>
      <columnIndex>4</columnIndex>
      <minIndex>722.0</minIndex>
      <maxIndex>5952.0</maxIndex>
    </blockCurveInfo>
    <blockCurveInfo>
      <curveId>4</curveId>
      <columnIndex>5</columnIndex>
      <minIndex>722.0</minIndex>
      <maxIndex>5952.0</maxIndex>
    </blockCurveInfo>
    <blockCurveInfo>
      <curveId>5</curveId>
      <columnIndex>6</columnIndex>
      <minIndex>722.0</minIndex>
      <maxIndex>5952.0</maxIndex>
    </blockCurveInfo>
    <blockCurveInfo>
      <curveId>6</curveId>
      <columnIndex>7</columnIndex>
      <minIndex>722.0</minIndex>
      <maxIndex>5952.0</maxIndex>
    </blockCurveInfo>
    <blockCurveInfo>
      <curveId>7</curveId>
      <columnIndex>8</columnIndex>
      <minIndex>722.0</minIndex>
      <maxIndex>5952.0</maxIndex>
    </blockCurveInfo>
  </blockInfo>
  <logData>
    <data id="0">722.0,266.0261,4.2191,0.0552,-0.0641,725.4987,-0.0641,52.1323</data>
    <data id="0">722.5,266.0261,4.2191,0.0552,-0.0641,725.4987,-0.0641,51.5528</data>
      <!-- ... truncated values  ... -->
    <data id="0">5951.5,317.3154,4.3422,156.5043,322.5522,5934.8213,322.5522,34.2945</data>
    <data id="0">5952.0,317.3249,4.3418,156.5300,322.5800,5935.3198,322.5800,34.2945</data>
  </logData>
  <commonData>
    <sourceName>--</sourceName>
    <dTimCreation>2006-11-08T10:09:30.030</dTimCreation>
  </commonData>
  <customData/>
</wellLog>

Whilst this is a very good method of encoding Well Log data in XML the terminology used doesn't really reflect the generic construct required for DIGGSML, many of the elements have very specific names. Hence the DIGGSML's tabular data implementation is not just an inclusion of WITSMLs implementation, as would have been ideal. DIGGSML takes many of the objects and properties in the WITSML implementation and renames them with more generic names (from SensorML) and also adds one or two more properties to enable DIGGSML to be more compatible with SensorML.

Implementation

It was decided that DIGGSMLs implementation should follow the WITSML implementation as much as possible, but it should also be compatible with SensorML, so a number of objects were renamed to coincide with SensorML, with a view to only having to learn one lexicon when representing monitoring data in XML, some properties were also added to ease this compatibility.

Example

Example 2 - DIGGSML Table showing a three detector Strain Rosette

<sensors>
  <Sensor>
    <gml:name>Strain Rosette</gml:name>
    <crs><!-- omitted for brevity --></crs>
    <detectors>
      <Detector>
        <id>DMDC-DETECTOR1</id>
        <position><gml:pos>0</gml:pos></position>
        <crs><!-- omitted for brevity --></crs>
        <measurand codeSpace="DIGGS_Measurands">Strain</measurand>
      </Detector>
 
      <Detector>
        <id>DMDC-DETECTOR2</id>
        <position><gml:pos>0</gml:pos></position>
        <crs><!-- omitted for brevity --></crs>
        <measurand codeSpace="DIGGS_Measurands">Strain</measurand>
      </Detector>
 
      <Detector>
        <id>DMDC-DETECTOR3</id>
        <position><gml:pos>0</gml:pos></position>
        <crs><!-- omitted for brevity --></crs>
        <measurand codeSpace="DIGGS_Measurands">Strain</measurand>
      </Detector>
    </detectors>
 
    <tables>
      <table>
        <columns>
          <column index="1">
            <type>DateTime</type>
            <meaning codeSpace="DIGGS_MonitorColumnMeaning">INDEX</meaning>
          </column>
          <column index="2">
            <type>double</type>
            <meaning codeSpace="DIGGS_MonitorColumnMeaning">MEASURE</meaning>
            <source>
              <Ref path="//*[diggs:id='DMDC-DETECTOR1']" />
            </source>
            <uom>%</uom>
            <noDataValue>-999</noDataValue>
            <nullValue>-1000</nullValue>
          </column>
          <column index="3">
            <type>double</type>
            <meaning codeSpace="DIGGS_MonitorColumnMeaning">MEASURE</meaning>
            <source>
              <Ref path="//*[diggs:id='DMDC-DETECTOR2']" />
            </source>
            <uom>%</uom>
            <noDataValue>-999</noDataValue>
            <nullValue>-1000</nullValue>
          </column>
          <column index="4">
            <type>double</type>
            <meaning codeSpace="DIGGS_MonitorColumnMeaning">MEASURE</meaning>
            <source>
              <Ref path="//*[diggs:id='DMDC-DETECTOR3']" />
            </source>
            <uom>%</uom>
            <noDataValue>-999</noDataValue>
            <nullValue>-1000</nullValue>
          </column>
        </columns>
        <tokenSeparator>&#x20;</tokenSeparator>
        <blockSeparator>,</blockSeparator>
        <decimalSeparator>.</decimalSeparator>
        <data>
          2007-09-07T12:00:00 0.005 0.006 0.007,
          2007-09-07T12:01:00 0.0051 0.0059 0.0074,
          2007-09-07T12:02:00 0.005 0.006 0.0068
        </data>
      </Table>
    </tables>
  </Sensor>
</sensors>

As you can see DIGGSML adds two properties to SensorML's implementation, nullValue indicates that no data is availiable for this measurement and noDataValue indicates that although a measurement was attempted no data was availiable, either due to a fault during measurement or an out of range error.

Rules and Definitions

There are five important things to remember about monitoring in DIGGSML.

  1. A Sensor is a point in 3D space either down a borehole (i.e. a peizometer), or at a sampling point on, above or below ground.
  2. Each sensor can report more than one type of measure using a number of detectors (Spade cell measure horizontal pressure and porewater pressure using two Detectors)
  3. Each measure may be omnidirectional (i.e. temperature) or unidirectional (i.e. strain) this direction is a property of the Detector, not the Sensor.
  4. Each measurement will have a single measure and a date time the sole exception being position measurements which will be reported with a gml:pos.
  5. A group of Detectors is grouped into a single Sensor when their results are only of meaning when used together e.g. A Strain Rosette is a single Sensor with three Detectors. When the Detectors results are of meaning independently they may optionally be grouped into a Sensor, or represented as separate Sensors e.g. A weather station recording temperature and pressure as one Sensor and rainfall as a separate Sensor.


Conclusion

It has already been said that DIGGSMLs verbose XML format would not be suitable for large ammounts of monitoring data, causing prohibitively large files and slow data transmission. Including this ability to represent ASCII data in a tabular format allows DIGGSML users to insert large blocks of data without having to include the XML markup associated with this file size increase.

By keeping the terminology common with SensorML the DIGGSML format is easily interoperable with the ISO standard for transferring this type of data without including it verbatim and allowing for more complicated constructs than DIGGSML was designed to hold.

Much of the structure of the tabular format is common with WITSML, a standard DIGGSML has already borrowed heavily from with many of the measurement types, and therefore much of the work done developing WITSML can be seen in the DIGGSML implementation. This should mean that the DIGGSML implementation is more mature than it would have been had it been developed from scratch, hopefully this complicated and advanced construct will be shown to be an effective way of reducing the size of monitoring data, and other blocks of large repeating data, in the DIGGSML format.