Prev Up Next Index
Go backward to 6.4.1 Dataset Descriptor Structure
Go up to 6.4 Ancillary data
Go forward to E Appendices

6.4.2 Dataset Attribute Structure

The Dataset Attribute Structure (DAS) is used to store attributes for variables in the dataset. An attribute is any piece of information about a variable that the creator wants to bind with that variable excluding the type and shape, which are part of the DDS. Attributes can be as simple as error measurements or as elaborate as text describing how the data was collected or processed21. In principle, attributes are not processed by software, other than to be displayed. However, many systems rely on attributes to store extra information that is necessary to perform certain manipulations of data. In effect, attributes are used to store information that is used `by convention' rather than `by design'. OPeNDAP can effectively support these conventions by passing the attributes from data set to user program via the DAS. Of course, OPeNDAP cannot enforce conventions in datasets where they were not followed in the first place.

Similarly to the DDS, the actual location of the DAS storage will vary from one API to another. Data files created with some APIs will contain within themselves attribute information that can be contained in the DAS. For these APIs, the DAS will be constructed dynamically by the OPeNDAP server from data within the files.

Other data access APIs must have attribute information specified in an ancillary data file. APIs that contain attribute information can have that information enriched by the addition of these ancillary attribute files. These files are typically stored in the same directory as the data files, and given the same name as the data files, appended with .das.

The syntax for attributes in a DAS is given in table 6.4.2. Every attribute of a variable is a triple: attribute name, type and value. Note that the attributes specified using the DAS are different from the information contained in the DDS. Each attribute is completely distinct from the name, type, and value of its associated variable. The name of an attribute is an identifier, following the normal rules for an identifier in a programming language with the addition that the `/' character may be used. The type of an attribute may be one of: Byte, Int32, UInt32, Float64, String or Url. An attribute may be scalar or vector. In the latter case the values of the vector are separated by commas (,) in the textual representation of the DAS.

Dataset Attribute Structure Syntax
 

DAS

Attributes { var-attr-list }

var-attr-list

var-attr
var-attr-list var-attr
(empty list)

var-attr

variable { attr-list }
container { var-attr-list }
global-attr
alias

global-attr

Global variable { attr-list }

attr-list

attr-triple ;
attr-list attr-triple
(empty list)

attr-triple

attr-type attribute attr-val-vec ;

attr-val-vec

attr-val
attr-val-vec , attr-val

attr-val

numeric value
variable
"string"

attr-type

Byte
Int32
UInt32
Float64
String
Url

alias

Alias alias-name variable ;

variable

user-chosen variable name

attribute

user-chosen attribute name

container

user-chosen container name

alias-name

user-chosen alias name

When creating a DAS to be kept in an ancillary file, you can use the # character as a comment indicator. All characters after the # on a line are ignored. 

Containers

An attribute can contain another attribute, or set of attributes. This is roughly comparable to the way compound variables can contain other variables in the DDS. The container defines a new lexical scope for the attributes it contains22.

Consider the following example:

Attributes {
   Bill {
      String LastName "Evans";
      Byte Age 53;
      String DaughterName "Matilda";
      Matilda {
         String LastName "Fink";
         Byte Age 26;
      }
   }
}
An Example of Attribute Containers
 

Here, the attribute Bill.LastName would be associated with the string "Evans", and Bill.Age with the number 53. However, the attribute Bill.Matilda.LastName would be associated with the string "Fink" and Bill.Matilda.Age with the number 26.

Using container attributes as above, you can construct a DAS that exactly mirrors the construction of a DDS that uses compound data types, like Structure and Sequence. Note that though the Bill attribute is a container, it has attributes of its own, as well. This exactly corresponds to the situation where, for example, a Sequence would have attributes belonging to it, as well as attributes for each of its member variables. Suppose the sequence represented a single time series of measurements, where several different data types are measured at each time. The sequence attributes might be the time and location of the measurements, and the individual variables might have attributes describing the method or accuracy of that measurement.

Aliases

Building on the previous example, it might be true that it would be convenient to refer to Matilda without prefixing every reference with Bill. In this case, we can define an alias attribute as follows:

Attributes {
   Bill {
      String LastName "Evans";
      Byte Age 53;
      String DaughterName "Matilda";
      Matilda {
         String LastName "Fink";
         Byte Age 26;
      }
   }
   Alias Matilda Bill.Matilda;
}
An Example of Attribute Alias
 

By defining an equivalence between the alias Matilda and the original attribute Bill.Matilda, the string Matilda.Age can be used with or without the prefix Bill. In either case, the attribute value will be 26.

Global Attributes

A global attribute is not bound to a particular identifier in a dataset; these attributes are stored in one or more containers with the name Global or ending with _Global. Global attributes are used to describe attributes of an entire dataset. For example, a global attribute might contain the name of the satellite or ship from which the data was collected. Here's an example:

Attributes {
   Bill {
      String LastName "Evans";
      Byte Age 53;
      String DaughterName "Matilda";
      Matilda {
         String LastName "Fink";
         Byte Age 26;
      }
   }
   Alias Matilda Bill.Matilda;
   Global {
      String Name "FamilyData";
      String DateCompiled "11/17/98";
   }
}
An Example of Global Attributes
 

Global attributes can be used to define a certain view of a dataset. For example, consider the following DAS:

Attributes {
   CTD {
      String Ship "Oceanus";
      Temp {
         String Name "Temperature";
      }
      Salt {
         String Name "Salinity";
      }
   }
   Global {
      String Names "OPeNDAP";
   }
   FNO_Global {
      String Names "FNO";
      CTD {
         Temp {
            String FNOName "TEMPERATURE";
         }
         Salinity {
            String FNOName "SALINITY";
         }
      }
      Alias T CTD.Temp;
      Alias S CTD.Salt;
   }
}
An Example of Global Attributes In Use
 

Here, a dataset contains temperature and salinity measurements. To aid processing of this dataset by some OPeNDAP client, long names are supplied for the Temp and Salt variables. However, a different client (FNO) spells variable names differently. Since it is seldom practical to come up with general-purpose translation tables23, the dataset administrator has chosen to include these synonyms under the FNO_Global attributes, as a convenience to those users.

Similar conveniences can be provided using the Alias feature. In the example in figure 6.4.2, the temperature variable can be referred to as FNO_Global.T if desired. That is, a global alias can provide a client with a known attribute name to query for some property, even if that attribute name is not an integral part of the dataset.

Using global attributes, a dataset or catalog administrator can create a layer of aliases and attributes to make OPeNDAP datasets conform to several different dataset naming standards. This becomes significant when trying to compile an OPeNDAP dataset database.


Tom Sgouros, August 25, 2004

Prev Up Next