Schema

In designing this schema, I have used short, perhaps in cases somewhat cryptic element and attribute names. The reason for doing this is simply to reduce the size of the configuration documents, which may be several megabytes in size. The ultimate reason for the large size of the configuration documents is that each correlator output product (lag spectrum) must be specified in order that the backend correctly assembles the lag frames, and each correlator output product must be assigned to a spectral window.

RELAX NG form
start = config.elt

# backend configuration
#
# Configuration is split into three parts: input configuration,
# specifying the correlator hardware configuration w.r.t. the products
# it produces; output configuration, specifying the subarrays and
# spectral windows in the backend output; and pipeline configuration,
# mapping correlator products to spectral windows and specifying the
# processing pipeline into which the input products go.
#
config.elt = element config {
   # input configuration
   inputConfig.elt,
   # output configuration
   outputConfig.elt,
   # pipeline configuration
   pipelineConfig.elt
}

# backend input configuration
#
# Configuration is split into two parts: the specification of the
# correlator baseline board input streams, and the products produced
# by the baseline boards from their input streams.
#
inputConfig.elt = element inputConfig {
   # streams
   stream.elt*,
   # products
   (product4.elt
    | product7.elt)*
}

stream.elt = element strm {
   # product id
   attribute id { xsd:ID },
   # station id
   attribute stn { xsd:positiveInteger },
   # baseband id
   attribute bb { xsd:nonNegativeInteger },
   # subband id
   attribute sb { xsd:nonNegativeInteger }
}

# 'product4' and 'product7' could be combined with the addition of a
# 'mode' attribute to reflect 4 or 7 bit products, but this produces a
# nondeterministic schema that cannot be accurately translated to
# the W3C XML Schema language
#
# product =
#   element product {
#     attribute id { xsd:ID },
#     attribute lags { xsd:positiveInteger },
#     attribute bins { xsd:positiveInteger },
#     attribute streamA { xsd:IDREF },
#     attribute streamB { xsd:IDREF },
#     ((attribute mode { xsd:integer "4" },
#       corrIntegration, lagChainSegment+)
#       | (attribute mode { xsd:integer "7" },
#          corrIntegration,
#          subProduct00,
#          subProduct01,
#          subProduct10,
#          subProduct11))
#   }

product.common.content =
   attribute id { xsd:ID },
   # number of lags
   attribute nLg { xsd:positiveInteger },
   # number of bins
   attribute nBn { xsd:positiveInteger },
   # stream "A" reference
   attribute strmA { xsd:IDREF },
   # stream "B" reference
   attribute strmB { xsd:IDREF },
   corrIntegration.elt

# four bit correlation product
product4.elt = element prd4 {
   product.common.content,
   lagChainSegment.elt+
}

# seven bit correlation product
product7.elt = element prd7 {
   product.common.content,
   # LSN (least significant nibble) - LSN product
   subProduct00.elt,
   # LSN - MSN (most significant nibble) product
   subProduct01.elt,
   # MSN-LSN product
   subProduct10.elt,
   # MSN-MSN product
   subProduct11.elt
}

subProduct.elements = lagChainSegment.elt+
subProduct00.elt = element sPrd00 {
   subProduct.elements
}
subProduct01.elt = element sPrd01 {
   subProduct.elements
}
subProduct10.elt = element sPrd10 {
   subProduct.elements
}
subProduct11.elt = element sPrd11 {
   subProduct.elements
}

# correlator integration
corrIntegration.elt = element cIntn {
   # minHW integration time (not sure this is needed)
   attribute minHW { xsd:positiveInteger },
   # hardware integration time (TODO: units)
   attribute hw { xsd:positiveInteger },
   # LTA integration time (TODO: units)
   attribute lta { xsd:positiveInteger }
}

# lag chain (spectrum) segment
lagChainSegment.elt = element lcSeg {
   # rack id
   attribute rck { xsd:positiveInteger },
   # crate id
   attribute crt { xsd:nonNegativeInteger },
   # slot id
   attribute slt { xsd:nonNegativeInteger },
   # corr chip x coordinate
   attribute x { xsd:nonNegativeInteger },
   # corr chip y coordinate
   attribute y { xsd:nonNegativeInteger },
   # first CCC
   attribute ccc0 { xsd:nonNegativeInteger },
   # lasg CCC
   attribute cccN { xsd:nonNegativeInteger },
   # recirculation factor
   attribute rec { xsd:positiveInteger },
   # corr chip X input
   xInp.elt,
   # corr chip Y input
   yInp.elt
}

inp.content =
   # stream label
   attribute strm { "A" | "B" },
   # lag block
   attribute inpBlk { xsd:nonNegativeInteger }

xInp.elt = element xInp {
   inp.content
}

yInp.elt = element yInp {
   inp.content
}

# output configuration
#
# Comprises a number of subarray configurations.
#
outputConfig.elt = element outputConfig {
   subarray.elt*
}

# subarray configuration
#
# A subarray consists of a number of stations, and it has an
# unchanging number of APC bins and integration time for all spectral
# windows. Auto- and cross-correlation configurations are given
# separately to account for different allowed values of the number of
# polarization products (this could be simplified were we to ignore
# W3C schema compatibility).
#
subarray.elt = element subarray {
   # subarray id
   attribute id { xsd:ID },
   # station id list
   attribute stns { list { xsd:nonNegativeInteger+ } },
   # num APC bins
   attribute nAPC { xsd:positiveInteger },
   # integration (TODO: units?)
   attribute intn { xsd:positiveInteger },
   # auto-correlation products
   autoCorrelations.elt?,
   # cross-correlation products
   crossCorrelations.elt?
}

# autocorrelations configuration
#
# Comprises a list of I/Fs and the spectral windows in each I/F.
#
autoCorrelations.elt = element aCorr {
   element if {
      # I/F id
      attribute val { xsd:nonNegativeInteger },
      # spectral window
      element sw {
         # spectral window id
         attribute id { xsd:ID },
         # number of (phase) bins
         attribute nBn { xsd:positiveInteger },
         # number of spectral channels
         attribute nCh { xsd:positiveInteger },
         # number of polarization
         attribute nPn { xsd:integer "1" | xsd:integer "2" }
      }+
   }+
}

# cross-correlations configuration
#
# Comprises a list of I/Fs and the spectral windows in each I/F.
#
crossCorrelations.elt = element xCorr {
   element if {
      # I/F id
      attribute val { xsd:nonNegativeInteger },
      element sw {
         # spectral window id
         attribute id { xsd:ID },
         # number of (phase) bins
         attribute nBn { xsd:positiveInteger },
         # number of spectral channels
         attribute nCh { xsd:positiveInteger },
         # number of polarization products
         attribute nPn { xsd:integer "1" | xsd:integer "2"
                       | xsd:integer "4" }
      }+
   }+
}

# pipeline configuration
#
# Pipeline configuration has two functions: assigning input products
# to spectral windows, and describing the pipeline used to move and
# convert the input products to the spectral windows. The assignment
# of input products to a baseline and polarization product in a
# spectral window may make this element very large. Perhaps we could
# create rules to describe the assignments in order to reduce the size
# of this element.
#
pipelineConfig.elt = element pipelineConfig {
   pipeline.elt*
}

inputProduct.elt = element prd {
   attribute bbA { xsd:nonNegativeInteger },
   attribute bbB { xsd:nonNegativeInteger }
}

pipeline.elt = element pln {
   # pipeline id
   attribute id { xsd:ID },
   # (output) spectral window ref
   attribute sw { xsd:IDREF },
   # pipeline description
   attribute desc { text },
   # (baseband, subband)->(pol'n product, sw offset) mapping
   element map {
      # subband id
      attribute sb { xsd:nonNegativeInteger },
      # offset of (subband) product in spectral window
      attribute off { xsd:nonNegativeInteger },
      # LL polarization product
      element pLL {
         inputProduct.elt
      }?,
      # LR polarization product
      element pLR {
         inputProduct.elt
      }?,
      # RL polarization product
      element pRL {
         inputProduct.elt
      }?,
      # RR polarization product
      element pRR {
         inputProduct.elt
      }?
   }+
}
W3C XML form
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
  <!--
    backend configuration
    
    Configuration is split into three parts: input configuration,
    specifying the correlator hardware configuration w.r.t. the products
    it produces; output configuration, specifying the subarrays and
    spectral windows in the backend output; and pipeline configuration,
    mapping correlator products to spectral windows and specifying the
    processing pipeline into which the input products go.
    
  -->
  <xs:element name="config">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="inputConfig"/>
        <xs:element ref="outputConfig"/>
        <xs:element ref="pipelineConfig"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <!--
    backend input configuration
    
    Configuration is split into two parts: the specification of the
    correlator baseline board input streams, and the products produced
    by the baseline boards from their input streams.
    
  -->
  <xs:element name="inputConfig">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="strm"/>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element ref="prd4"/>
          <xs:element ref="prd7"/>
        </xs:choice>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="strm">
    <xs:complexType>
      <xs:attribute name="id" use="required" type="xs:ID"/>
      <xs:attribute name="stn" use="required" type="xs:positiveInteger"/>
      <xs:attribute name="bb" use="required" type="xs:nonNegativeInteger"/>
      <xs:attribute name="sb" use="required" type="xs:nonNegativeInteger"/>
    </xs:complexType>
  </xs:element>
  <!--
    'product4' and 'product7' could be combined with the addition of a
    'mode' attribute to reflect 4 or 7 bit products, but this produces a
    nondeterministic schema that cannot be accurately translated to
    the W3C XML Schema language
    
    product =
      element product {
        attribute id { xsd:ID },
        attribute lags { xsd:positiveInteger },
        attribute bins { xsd:positiveInteger },
        attribute streamA { xsd:IDREF },
        attribute streamB { xsd:IDREF },
        ((attribute mode { xsd:integer "4" },
          corrIntegration, lagChainSegment+)
          | (attribute mode { xsd:integer "7" },
             corrIntegration,
             subProduct00,
             subProduct01,
             subProduct10,
             subProduct11))
      }
  -->
  <xs:element name="product.common.content" abstract="true">
    <xs:complexType>
      <xs:attribute name="minHW" use="required" type="xs:positiveInteger"/>
      <xs:attribute name="hw" use="required" type="xs:positiveInteger"/>
      <xs:attribute name="lta" use="required" type="xs:positiveInteger"/>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="product.common.content">
    <xs:sequence>
      <xs:element ref="product.common.content"/>
    </xs:sequence>
    <xs:attribute name="id" use="required" type="xs:ID"/>
    <xs:attribute name="nLg" use="required" type="xs:positiveInteger"/>
    <xs:attribute name="nBn" use="required" type="xs:positiveInteger"/>
    <xs:attribute name="strmA" use="required" type="xs:IDREF"/>
    <xs:attribute name="strmB" use="required" type="xs:IDREF"/>
  </xs:complexType>
  <!-- four bit correlation product -->
  <xs:element name="prd4">
    <xs:complexType>
      <xs:complexContent>
        <xs:extension base="product.common.content">
          <xs:sequence>
            <xs:element maxOccurs="unbounded" ref="lcSeg"/>
          </xs:sequence>
        </xs:extension>
      </xs:complexContent>
    </xs:complexType>
  </xs:element>
  <!-- seven bit correlation product -->
  <xs:element name="prd7">
    <xs:complexType>
      <xs:complexContent>
        <xs:extension base="product.common.content">
          <xs:sequence>
            <xs:element ref="sPrd00"/>
            <xs:element ref="sPrd01"/>
            <xs:element ref="sPrd10"/>
            <xs:element ref="sPrd11"/>
          </xs:sequence>
        </xs:extension>
      </xs:complexContent>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="subProduct.elements">
    <xs:sequence>
      <xs:element maxOccurs="unbounded" ref="lcSeg"/>
    </xs:sequence>
  </xs:complexType>
  <xs:element name="sPrd00" type="subProduct.elements"/>
  <xs:element name="sPrd01" type="subProduct.elements"/>
  <xs:element name="sPrd10" type="subProduct.elements"/>
  <xs:element name="sPrd11" type="subProduct.elements"/>
  <!-- correlator integration -->
  <xs:complexType name="corrIntegration.elt">
    <xs:sequence>
      <xs:element ref="cIntn"/>
    </xs:sequence>
  </xs:complexType>
  <xs:element name="cIntn" substitutionGroup="product.common.content"/>
  <!-- lag chain (spectrum) segment -->
  <xs:element name="lcSeg">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="xInp"/>
        <xs:element ref="yInp"/>
      </xs:sequence>
      <xs:attribute name="rck" use="required" type="xs:positiveInteger"/>
      <xs:attribute name="crt" use="required" type="xs:nonNegativeInteger"/>
      <xs:attribute name="slt" use="required" type="xs:nonNegativeInteger"/>
      <xs:attribute name="x" use="required" type="xs:nonNegativeInteger"/>
      <xs:attribute name="y" use="required" type="xs:nonNegativeInteger"/>
      <xs:attribute name="ccc0" use="required" type="xs:nonNegativeInteger"/>
      <xs:attribute name="cccN" use="required" type="xs:nonNegativeInteger"/>
      <xs:attribute name="rec" use="required" type="xs:positiveInteger"/>
    </xs:complexType>
  </xs:element>
  <xs:attributeGroup name="inp.content">
    <xs:attribute name="strm" use="required">
      <xs:simpleType>
        <xs:restriction base="xs:token">
          <xs:enumeration value="A"/>
          <xs:enumeration value="B"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
    <xs:attribute name="inpBlk" use="required" type="xs:nonNegativeInteger"/>
  </xs:attributeGroup>
  <xs:element name="xInp">
    <xs:complexType>
      <xs:attributeGroup ref="inp.content"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="yInp">
    <xs:complexType>
      <xs:attributeGroup ref="inp.content"/>
    </xs:complexType>
  </xs:element>
  <!--
    output configuration
    
    Comprises a number of subarray configurations.
    
  -->
  <xs:element name="outputConfig">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="subarray"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <!--
    subarray configuration
    
    A subarray consists of a number of stations, and it has an
    unchanging number of APC bins and integration time for all spectral
    windows. Auto- and cross-correlation configurations are given
    separately to account for different allowed values of the number of
    polarization products (this could be simplified were we to ignore
    W3C schema compatibility).
    
  -->
  <xs:element name="subarray">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="0" ref="aCorr"/>
        <xs:element minOccurs="0" ref="xCorr"/>
      </xs:sequence>
      <xs:attribute name="id" use="required" type="xs:ID"/>
      <xs:attribute name="stns" use="required">
        <xs:simpleType>
          <xs:restriction>
            <xs:simpleType>
              <xs:list itemType="xs:nonNegativeInteger"/>
            </xs:simpleType>
            <xs:minLength value="1"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="nAPC" use="required" type="xs:positiveInteger"/>
      <xs:attribute name="intn" use="required" type="xs:positiveInteger"/>
    </xs:complexType>
  </xs:element>
  <!--
    autocorrelations configuration
    
    Comprises a list of I/Fs and the spectral windows in each I/F.
    
  -->
  <xs:element name="aCorr">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" name="if">
          <xs:complexType>
            <xs:sequence>
              <xs:element maxOccurs="unbounded" name="sw">
                <xs:complexType>
                  <xs:attribute name="id" use="required" type="xs:ID"/>
                  <xs:attribute name="nBn" use="required" type="xs:positiveInteger"/>
                  <xs:attribute name="nCh" use="required" type="xs:positiveInteger"/>
                  <xs:attribute name="nPn" use="required">
                    <xs:simpleType>
                      <xs:restriction base="xs:integer">
                        <xs:enumeration value="1"/>
                        <xs:enumeration value="2"/>
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:attribute>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
            <xs:attribute name="val" use="required" type="xs:nonNegativeInteger"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <!--
    cross-correlations configuration
    
    Comprises a list of I/Fs and the spectral windows in each I/F.
    
  -->
  <xs:element name="xCorr">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" name="if">
          <xs:complexType>
            <xs:sequence>
              <xs:element maxOccurs="unbounded" name="sw">
                <xs:complexType>
                  <xs:attribute name="id" use="required" type="xs:ID"/>
                  <xs:attribute name="nBn" use="required" type="xs:positiveInteger"/>
                  <xs:attribute name="nCh" use="required" type="xs:positiveInteger"/>
                  <xs:attribute name="nPn" use="required">
                    <xs:simpleType>
                      <xs:restriction base="xs:integer">
                        <xs:enumeration value="1"/>
                        <xs:enumeration value="2"/>
                        <xs:enumeration value="4"/>
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:attribute>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
            <xs:attribute name="val" use="required" type="xs:nonNegativeInteger"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <!--
    pipeline configuration
    
    Pipeline configuration has two functions: assigning input products
    to spectral windows, and describing the pipeline used to move and
    convert the input products to the spectral windows. The assignment
    of input products to a baseline and polarization product in a
    spectral window may make this element very large. Perhaps we could
    create rules to describe the assignments in order to reduce the size
    of this element.
    
  -->
  <xs:element name="pipelineConfig">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="pln"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="inputProduct.elt">
    <xs:sequence>
      <xs:element ref="prd"/>
    </xs:sequence>
  </xs:complexType>
  <xs:element name="prd">
    <xs:complexType>
      <xs:attribute name="bbA" use="required" type="xs:nonNegativeInteger"/>
      <xs:attribute name="bbB" use="required" type="xs:nonNegativeInteger"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="pln">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" ref="map"/>
      </xs:sequence>
      <xs:attribute name="id" use="required" type="xs:ID"/>
      <xs:attribute name="sw" use="required" type="xs:IDREF"/>
      <xs:attribute name="desc" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="map">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="0" ref="pLL"/>
        <xs:element minOccurs="0" ref="pLR"/>
        <xs:element minOccurs="0" ref="pRL"/>
        <xs:element minOccurs="0" ref="pRR"/>
      </xs:sequence>
      <xs:attribute name="sb" use="required" type="xs:nonNegativeInteger"/>
      <xs:attribute name="off" use="required" type="xs:nonNegativeInteger"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="pLL" type="inputProduct.elt"/>
  <xs:element name="pLR" type="inputProduct.elt"/>
  <xs:element name="pRL" type="inputProduct.elt"/>
  <xs:element name="pRR" type="inputProduct.elt"/>
</xs:schema>