Metadata Schema

Previous Next

Case Metadata format

The metadata file is a .xml schema that is passed from the server to the client when the dataset is loaded. It allows for generic info tags and a hierarchy to be specified. In the Case file format, it is specified in the ‘SCRIPTS’ section using the section:


SCRIPTS
metadata: filename


User-defined readers can return this information via the optional ‘int USERD_get_metadata(int *nbytes, char *data)’ routine. This function is called right after ‘set_filenames’. It is called two times. The first time, data is NULL, and the reader should put the number of bytes in the XML text (including ‘\0’) in nbytes and return. The second call will have a valid ‘data’ pointer specified (pointing at nbytes of storage space).


The XML metadata syntax looks like this:

  <?xml version="1.0" encoding="UTF-8"?>

  <CEImetadata version="1.0">

    <parts>

      <metatags>

        <tag name="foo1" type="str">defaultvalue</tag>

        <tag name="foo2" type="str">defaultvalue</tag>

      </metatags>

      <partlist>

        <part name="qwe"></part>

        <group name="jkl">

          <part name="uio" foo2="value"></part>

          <group name="fgh" foo1="value" foo2="value">

            <part name="rty" foo1="value"></part>

            <part name="uio"></part>

          </group>

        </group>

      </partlist>

    </parts>

    <vars>

      <metatags>

        <tag name="foo1" type="str">defaultvalue</tag>

        <tag name="foo2" type="str">defaultvalue</tag>

      </metatags>

      <varlist>

        <var name="qwe"></var>

        <var name="uio" foo2="value"></var>

      </varlist>

    </vars>

    <case>

      <metatags>

        <tag name="foo1" type="str">value1</tag>

        <tag name="foo2" type="str">value2</tag>

      </metatags>

    </case>

  </CEImetadata>


Note: the only allowed metatag types are ‘int’ (integer), ‘flt’ (float), ‘str’ (string) and ‘python’ (string) the latter executable form specifies code to be run when the associated part is loaded. Currently, group constructs are not allowed in the vars section.

Internationalization and Metadata XML Files

The example above includes an XML encoding specification (UTF-8), which specifies that all text in the XML are encoded as such. Currently in EnSight, the readers and server do not specify parts and variable names in UTF-8, instead, they use the 8bit native platform encoding (UTF-8 on Linux and OSX but MBCS on Windows).  If no encoding is specified in the metadata XML file (e.g. no encoding="" attribute), EnSight will treat the encoding as 8bit native platform encoding and NOT UTF-8 as is common in many XML parsers.  This is done to make it easier to unify string representations with the reader/server pipeline.  In any case, if the encoding of the metadata XML file is known (e.g. ISO-8859-1 or UTF-8), the developer is encouraged to specify it correctly in the metadata XML file (e.g. '<?xml version="1.0" encoding="ISO-8859-1"?>' or '<?xml version="1.0" encoding="UTF-8"?>') and EnSight will honor it.

How does this work?

The basic idea is that when the case is loaded, the XML file is read. The loading code creates ENS_GROUP objects beneath the ENS_CASE object to match the tree described in the XML. It also creates an ENS_LPART object for each of the parts in the case. It places these ENS_LPART objects into the ENS_GROUP objects as specified by the XML. Any ENS_LPART objects not referenced in the XML file will be created as children of the ENS_CASE object itself. If an application uses ENS_LPART→load() without any parent specified, the default is to use the same parent as the ENS_LPART. As a result, loading all the parts in their default locations in the tree will reproduce the tree outlined in the XML file.

Note: if no XML file is specified or an XML file is passed without a <partlist> section, EnSight will create a single ENS_GROUP object under the ENS_CASE object and will place all of the ENS_LPART objects into that group.

LPART objects are tagged with the metadata from the <partlist> section. Model PART objects will be tagged with the same metadata stored on their LPART counterparts (LPARTPARENT attribute). Other PART object are not tagged. CASE objects are tagged with the metadata found in the <case> section. VAR objects are tagged with metadata from the <varlist> section of the current CASE object.

Metadata "Schema"

Here we introduce the concept of a metadata schema. The basic idea is to define a collection of metadata tags and document their behavior.  In many ways, a metadata schema is a loose collection of rules.  If multiple datasets follow the same rule, then EnSight can use that information in a universal manner.  Today, this is done by defining a EnSight extension object that watches for the presence of a metadata schema and alters the behavior of EnSight when it detects the presence of the schema.

An example is the CFD_VAR schema (covered in more detail below).  The idea here is that datasets use differently named variables for the same entities.  This makes it difficult for EnSight to "guess" that a variable might be pressure or density.  As a result, it is difficult to write GUI utilities that provide domain specific computation with datasets from different formats.  The CFD_VAR schema defines some fundamental variable quantities and tags the variables to let the GUI know that while this variable might be named "HELLO", it should be treated as "CFD_Velocity".  The schema includes a tag 'CFD_VAR' that is specified on the case object itself that reports that the case supports the schema and the version number of the schema employed.

Again, a "schema" is really a concept, not code specifically.  One could define a schema for things like units for instance or colors or materials.  The key is to document and share the schema so others can implement the schema in their readers.

Schema Agents

Defining the XML syntax and rules defines the schema, but in most cases some code is necessary in the client to process the state of the objects and their associated METADATA tags. These pieces of code are called "Agents".  Agents are subclasses of the ensight.core.schema_core.ensschema class.  They can be enabled or disabled and they have a state (active or inactive) based on whether or not a case that advertises the named schema has been loaded in EnSight. In all of the shipping schema, there is an associated tool_extension class that provides (1) a GUI for the current schema state and (2) a command language hook for recording otherwise unscripted operations.

 The Schema Engine

All schema Agents are registered with the Schema Engine which manages a list of the schema and manages their update status.  The engine watches for cases opening that advertise support for schema. It informs the schema of the existence of such cases and controls their enabled and activated status.  The engine singleton object can be accessed using: ensight.core.schema_engine.  For example, to check to see if the "ENS_UNITS_LABEL" schema is active, use code like this:

 

if (ensight.core.schema_engine.schema("ENS_UNITS_LABEL")._active):

    print("Schema is active")

 

Individual schema are expected to provide methods to manipulate METADATA tags on objects for the caller.

Currently defined schema:

Example dataset

An example dataset is available for download here as an attachment. It loads the guardrail dataset with a simple hierarchy included as an XML file as well as ENS_UNITS_LABEL, ENS_UNITS_DIMS and ENS_OBJATTR tags.