<?xml version="1.0"?>
  <!--  This example's derived from a dictionary for the CASTEP 
        code; you can find it at http://www.castep.org/ --> 
<dictionary
  namespace="http://www.materialsgrid.org/castep/dictionary"
  dictionaryPrefix="castep" 
  title="CASTEP Dictionary"
  xmlns="http://www.xml-cml.org/schema"
  xmlns:h="http://www.w3.org/1999/xhtml/"
  xmlns:cml="http://www.xml-cml.org/schema"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:golem="http://www.lexical.org.uk/golem"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!--  You specify the three attributes above here - a URL for the dictionary
  (which you can think of as a machine-readable name; pick something 
  unique at a domain you control), the dictionaryPrefix (short name for
  the dictionary), and the dictionary title (which is the title
  people using the dictionary'll see.) 
  
  The dictionary generator will add the namespaces for you, but if you're
  writing your own dictionary for whatever reason, just copy them across
  as they are here.-->
  
  <!--  Here's a typical Golem dictionary entry for a concept which
  is represented as a string which can take one of a few, enumerated, values. -->
  <entry id="xcFunctional" term="Exchange-Correlation Functional">
  <!-- The id must be unique within the dictionary. The term is
  designed for documentation, so should be as pithy as you can make
  it... -->
    <definition> <!-- Ideally, a one-sentence description of the concept. -->
      The exchange-correlation functional used.
    </definition>
    <description> 
    <!--  A longer description - think documentation. Typically,
    this'll be XHTML - if you look above, we've declared the "h:"
    namespace as mapping to that, so... -->
    <h:div class="dictDescription">
      The exchange-correlation functional used in a given simulation.
      Available values for this are:
      <h:ul>
        <h:li>
          <h:strong>LDA</h:strong>, the Local Density Approximation
        </h:li>
        <h:li>
          <h:strong>PW91</h:strong>, Perdew and Wang's 1991 formulation
        </h:li>
        <h:li>
          <h:strong>PBE</h:strong>,
          Perdew, Burke and Enzerhof's original GGA functional
        </h:li>
        <h:li>
          <h:strong>RPBE</h:strong>, Hammer et al's revised PBE functional
        </h:li>
      </h:ul>
    </h:div>
    </description>
    
    <metadataList> <!--  Optional. If you want to document provenance -
                    like who wrote an entry - this is where to do it. -->
      <metadata name="dc:contributor" content="golem-kiln" />
    </metadataList>
    <!-- Where this concept can be found in CML documents which 
    use this dialect - usually inferred by the dictionary builder  -->
    <golem:xpath>/cml:cml/cml:parameterList[@dictRef="input"]/cml:parameter[@dictRef="castep:xcFunctional"]</golem:xpath>

    <!--  Now, how to read the data once you've found it.
    
    Here, the value of @call will, typically, correspond to the name of
    the tag which has the actual data in:
    
    <parameter dictRef="castep:xcFunctional" name="Exchange-Correlation Functional">
      <scalar dataType="xsd:string">PBE</scalar>
    </parameter>
    
    so here it's "scalar".
    
    The golem dictionary generation tools "know about" - i.e., have templates
    for:
    
    - <scalar>
    - <array>
    - <matrix>
    - <cellParameter>
    - <metadata>
    - <lattice>
    - <atomArray>
    
    so if your data is in one of these, then this template will be
    automatically added. If you've got something else, then you need to: 
    
    - write a dictionary entry with the tagname as the id
      (i.e. <entry id="newEntry" ...>)
    - write an XSLT stylesheet which produces a JSON doc 
      of the form [ newEntry_value, "units:newEntry_units" ]
      when run over the data
    - put this in your dictionary entry as:
      <golem:template role="getvalue" binding="pygolem_serialization">
        <xsl:stylesheet />
      </golem:template>
    - add <golem:template call="newEntry" role="getvalue" 
                          binding="pygolem_serialization" /> 
      to the dictionary entries which'll use this new template to read
      their data.
    -->
    <golem:template call="scalar" role="getvalue" binding="pygolem_serialization" />
    <!--  You can add other templates with different roles, too. These
    get mapped onto functions if you're using pyGolem: if you've got
    a dictionary "d" with namespace "n", then...
    
    xcFunctional_entry = d["{%s}xcFunctional" % n]
    print str(xcFunctional_entry.arb_to_input("RPBE"))
    
    will print out the value of this template when passed "RPBE" as
    an argument.
    
    Arguments are labelled p1, p2... pn in the template; if you're writing
    a template to which you're going to pass arguments, you need to set
    the @binding attribute to "input", as here, and @input to "external"
    (meaning it takes externally-provided arguments, not XML).
    -->
    
    <golem:template role="arb_to_input" binding="input" input="external">
      <xsl:stylesheet version='1.0' 
                      xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
                      xmlns:cml='http://www.xml-cml.org/schema'>
        <xsl:strip-space elements="*" />
        <xsl:output method="text" />
        <xsl:param name="p1" />
        <xsl:template match="/">
          <xsl:text>XC_FUNCTIONAL </xsl:text><xsl:value-of select="$p1" />        
        </xsl:template>
      </xsl:stylesheet>
    </golem:template>
    <!--  golem:implements entries say that this concept is 
    an "implementation" - subclass, more or less - of another concept
    in the dictionary. Here, xcFunctional is convertible to input,
    has a value, and is absolutely-positioned (always found, if it's
    present, in exactly the same place in all documents in this dialect).
    You can add these by hand, but mostly they're added automatically
    by the dictionary generator. -->
    <golem:implements>convertibleToInput</golem:implements>
    <golem:implements>value</golem:implements>
    <golem:implements>absolute</golem:implements>
    <!-- This is also added automatically.
    
    A concept, in Golem, maps onto a set of nodes in the XML DOM according
    to the <golem:xpath> expression above. An entry is a <golem:childOf> of
    another if it can, possibly, be found in the child nodes of the nodes
    to which the parent concept maps. --> 
    <golem:childOf>input</golem:childOf>

    <!--  Type and bounds checking. Here we've got a string; we could
    also have an int, float or matrix, but we'll come back to those
    later. -->
    <golem:possibleValues type="string">
      <golem:enumeration> <!--  contains the possible values for this concept -->
        <golem:value>LDA</golem:value> <!--  and one of these for each value -->
        <golem:value>PW91</golem:value>
        <golem:value>PBE</golem:value>
        <golem:value>RPBE</golem:value>
      </golem:enumeration>
    </golem:possibleValues>
   </entry>
   
   <!-- Now for an entry with integer data. -->
  <entry id="mg_numberOfSimulations" term="Number of simulations to run in this workflow">
    <annotation />
    <definition></definition>
    <description/>    
    <metadataList>
      <metadata name="dc:creator" content="golem-kiln" />
    </metadataList>
    <!--  This is the different bit. <golem:range> here is optional;
    if you don't specify it, this can be any integer at all.
    
    <golem:maximum> - if you specify it - works just the same as
    <golem:minimum> here. 
    
    Likewise, type="float" is pretty much identical, except for the 
    obvious! -->
    <golem:possibleValues type="int">
      <golem:range>
        <golem:minimum>2</golem:minimum>
      </golem:range>
    </golem:possibleValues>
    <golem:implements>parameterInInput</golem:implements>
  </entry>
  
  <!--  And here's an example of both a matrix, and of one of the
  dictionary entries which implements the reading of a particular
  datatype - in this case, the lattice. -->
  <entry id="lattice" term="Set of lattice vectors - generic read">
    <annotation />
    <definition />
    <description />
    <!--  
    When you're writing a template which is going to be called, 
    give it the same role and binding as you're going to put on the 
    calling entries:
    
    ie, you'd call this by:
    <golem:template call="lattice" role="getvalue" 
                    binding="pygolem_serialization" />
    -->
    <golem:template role="getvalue" binding="pygolem_serialization">
      <xsl:stylesheet version='1.0' 
        xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
        xmlns:cml='http://www.xml-cml.org/schema'
        xmlns:str="http://exslt.org/strings"
        extension-element-prefixes="str">
      <xsl:output method="text" />
      <xsl:template match="/">
        <xsl:apply-templates />
      </xsl:template>  
      <xsl:template match="cml:lattice">
        <xsl:text>[</xsl:text>
          <xsl:for-each select="cml:latticeVector">
            <xsl:text>[</xsl:text> 
            <xsl:for-each select="str:tokenize(string(.), ' ')" >
              <xsl:choose>
                <xsl:when test="position() != last()">
                  <xsl:value-of select="." /><xsl:text>,</xsl:text>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="." />
                </xsl:otherwise>
              </xsl:choose>
            </xsl:for-each>
            <xsl:choose>
              <xsl:when test="position() != last()">
                <xsl:text>],</xsl:text>
              </xsl:when>
              <xsl:otherwise>
                <xsl:text>]</xsl:text>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:for-each>
          <xsl:text>]</xsl:text>
        </xsl:template>
      </xsl:stylesheet>
    </golem:template>
    <!--  A relatively-positioned concept: this can occur in multiple
    different places throughout the document. That means you need to have
    cut down the bit of the document you're searching - by searching for
    a parent entry - before you look for these, or you can
    easily wind up matching multiple entries at once... -->
    <golem:xpath>.//cml:lattice</golem:xpath>
    <!--  Here's how you specify the type, and size, of a matrix. -->
    <golem:possibleValues type="matrix">
        <!--  The data type of the matrix *elements* goes in here - 
        so this is a matrix of floats... -->
      <golem:matrix dimensionx="3" dimensiony="3" type="float" symmetric="false"/>
      <!--  The @symmetric element on golem:matrix specifies whether the
      matrix is symmetric. If it is, only the upper diagonal elements
      should be given; if not, the full matrix is expected. -->
      
      <!-- If you give a <golem:range> here, it applies to all the elements
      in the matrix: so, sa,
       <golem:range>
         <golem:minimum>0</golem:minimum>
         <golem:maximum>10</golem:maximum>
       </golem:range>
       
       would constrain the matrix elements to lie in the range
       0 <= elementhi dan <= 10. -->
    </golem:possibleValues>
  </entry>
</dictionary>