Package opendap.dap

Class DDS

  • All Implemented Interfaces:
    Serializable, Cloneable, ClientIO
    Direct Known Subclasses:
    DataDDS

    public class DDS
    extends DStructure
    The OPeNDAP Data Descriptor Object (DDS) is a data structure used by the OPeNDAP software to describe datasets and subsets of those datasets. The DDS may be thought of as the declarations for the data structures that will hold data requested by some OPeNDAP client. Part of the job of a OPeNDAP server is to build a suitable DDS for a specific dataset and to send it to the client. Depending on the data access API in use, this may involve reading part of the dataset and inferring the DDS. Other APIs may require the server simply to read some ancillary data file with the DDS in it.

    On the server side, in addition to the data declarations, the DDS holds the clauses of any constraint expression that may have accompanied the data request from the OPeNDAP client. The DDS object includes methods for modifying the DDS according to the given constraint expression. It also has methods for directly modifying a DDS, and for transmitting it from a server to a client.

    For the client, the DDS object includes methods for reading the persistent form of the object sent from a server. This includes parsing the ASCII representation of the object and, possibly, reading data received from a server into a data object.

    Note that the class DDS is used to instantiate both DDS and DataDDS objects. A DDS that is empty (contains no actual data) is used by servers to send structural information to the client. The same DDS can becomes a DataDDS when data values are bound to the variables it defines.

    For a complete description of the DDS layout and protocol, please refer to The OPeNDAP User Guide.

    The DDS has an ASCII representation, which may be transmitted from a OPeNDAP server to a client. Here is the DDS representation of an entire dataset containing a time series of worldwide grids of sea surface temperatures:

      Dataset {
          Float64 lat[lat = 180];
          Float64 lon[lon = 360];
          Float64 time[time = 404];
          Grid {
           ARRAY:
              Int32 sst[time = 404][lat = 180][lon = 360];
           MAPS:
              Float64 time[time = 404];
              Float64 lat[lat = 180];
              Float64 lon[lon = 360];
          } sst;
      } weekly;
     

    If the data request to this dataset includes a constraint expression, the corresponding DDS might be different. For example, if the request was only for northern hemisphere data at a specific time, the above DDS might be modified to appear like this:

      Dataset {
          Grid {
           ARRAY:
              Int32 sst[time = 1][lat = 90][lon = 360];
           MAPS:
              Float64 time[time = 1];
              Float64 lat[lat = 90];
              Float64 lon[lon = 360];
          } sst;
      } weekly;
     

    Since the constraint has narrowed the area of interest, the range of latitude values has been halved, and there is only one time value in the returned array. Note that the simple arrays (lat, lon, and time) described in the dataset are also part of the sst Grid object. They can be requested by themselves or as part of that larger object.

    DDX

    The DDS also has an XML representation. This is known as a DDX. Since BaseType variables now each have their own set of Attributes it has become necessary to have a representation of the DDS that captures these relationships. Consider the previous example. A correctly constructed DAS for that DDS might look like:
     Attributes {
     lat {
     String fullName "latitude";
     String units "degrees North";
     }
     lon {
     String fullName "longitude";
     String units "degrees East";
     }
     time {
     String units "seconds";
     }
     sst {
     String fullName "Sea Surface Temperature";
     String units "degrees centigrade";
     sst {
     Alias fullName .sst.fullName;
     Alias units .sst.units;
     }
     time {
     Alias units .time.units;
     }
     lat {
     Alias fullName .lat.fullName;
     Alias units .lat.units;
     }
     lon {
     Alias fullName .lon.fullName;
     Alias units .lon.units;
     }
     }
     }
     

    Combined with the DDS and expressed as a DDX it would look like:

     

    <?xml version="1.0" encoding="UTF-8"?> <Dataset name="weekly" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xml.opendap.org/ns/DAP2" xsi:schemaLocation="http://xml.opendap.org/ns/DAP2 http://xml.opendap.org/dap/dap2.xsd" >

    <Array name="lat"> <Attribute name="fullName" type="String"> <value>&quot;latitude&quot;</value> </Attribute> <Attribute name="units" type="String"> <value>&quot;degrees North&quot;</value> </Attribute> <Float64/> <dimension name="lat" size="180"/> </Array> <Array name="lon"> <Attribute name="fullName" type="String"> <value>&quot;longitude&quot;</value> </Attribute> <Attribute name="units" type="String"> <value>&quot;degrees East&quot;</value> </Attribute> <Float64/> <dimension name="lon" size="360"/> </Array> <Array name="time"> <Attribute name="units" type="String"> <value>&quot;seconds&quot;</value> </Attribute> <Float64/> <dimension name="time" size="404"/> </Array> <Grid name="sst"> <Attribute name="fullName" type="String"> <value>&quot;Sea Surface Temperature&quot;</value> </Attribute> <Attribute name="units" type="String"> <value>&quot;degrees centigrade&quot;</value> </Attribute> <Array name="sst"> <Alias name="fullName" Attribute=".sst.fullName"/> <Alias name="units" Attribute=".sst.units"/> <Int32/> <dimension name="time" size="404"/> <dimension name="lat" size="180"/> <dimension name="lon" size="360"/> </Array> <Map name="time"> <Alias name="units" Attribute=".time.units"/> <Float64/> <dimension name="time" size="404"/> </Map> <Map name="lat"> <Alias name="fullName" Attribute=".lat.fullName"/> <Alias name="units" Attribute=".lat.units"/> <Float64/> <dimension name="lat" size="180"/> </Map> <Map name="lon"> <Alias name="fullName" Attribute=".lon.fullName"/> <Alias name="units" Attribute=".lon.units"/> <Float64/> <dimension name="lon" size="360"/> </Map> </Grid>

    <dataBLOB href="cid:ContentIdOfTheMIMEAttcahmentContainingTheDataBlob"/> </Dataset>

    The DDX can also be sent from a server to a client.

    Using the DDS's API to construct a DDS

    Many developers choose not to use the DDSParser to build DDS's but to build them using the DDS API. This is typical of devlopers writing servers that work with information rich data formats such as NetCDF or HDF. With the addition of Attributes (and Attribute containers) to all of the datatypes in the DAP it is now possible to construct a DDS that contains all of the source meta-data from the original data source. This is an extremly useful thing. However, when building a DDS using the DDS API be sure to call the functions DDS.checkForAttributeNameConflict() and DDS.resolveAliases()
  • on the new DDS prior to releasing it from the code that builds it. Otherwise the DDS may have functional problems!

    See The OPeNDAP User Guide, or the documentation of the BaseType class for descriptions of the OPeNDAP data types.

See Also:
BaseType, BaseTypeFactory, DAS, DDSXMLParser, checkForAttributeNameConflict(), resolveAliases(), Serialized Form