.. _schemaxml:
Defining a calculation scheme in the XML format
=================================================
An XML file that describes a calculation scheme can contain the following information:
- definitions of data types
- definitions of containers
- definitions of elementary calculation nodes
- definitions of composite nodes
- definitions of connections between nodes
- initialisations
These definitions will be presented progressively. We will start with:
- the definition of data types
- the definition of a sub-set of elementary nodes
- the definition of non-datastream connections
- the definition of composite nodes
We will then add complements on:
- the definition of containers
- the definition of node properties
- the definition of datastream connections
- the definition of the remaining elementary nodes.
A calculation scheme is defined using the XML proc tag. The simplest calculation scheme is as follows:
.. code-block:: xml
It contains no definition and it does nothing.
Definition of data types
---------------------------------
It is impossible to define basic types other than existing types. All basic types are predefined by YACS.
However, aliases can be defined. For example, an alias for the double type can be written:
.. code-block:: xml
we can then write mydble instead of double.
Object reference
'''''''''''''''''''''
The simplest way of defining an object reference type is:
.. code-block:: xml
The name attribute of the objref tag gives the name of the new type.
The complete form to define this type would be:
.. code-block:: xml
mesh
If there are several basic types, we will write:
.. code-block:: xml
mesh
unautretype
As for CORBA, we can use namespaces to define types.
For example, if the SALOME mesh type is defined in the myns namespace, we will write:
.. code-block:: xml
Sequence
''''''''''
To define a double sequence, we will write:
.. code-block:: xml
All attributes of the sequence tag are compulsory. The name attribute gives the name of the new type.
The content attribute gives the name of the type of elements in the sequence.
A sequence of sequences can be defined by:
.. code-block:: xml
We can also define a sequence of object references by:
.. code-block:: xml
Structure
'''''''''''''
A structure is defined using a struct tag with member sub-tags for the definition of structure members.
The following is an example definition:
.. code-block:: xml
The member tag has 2 compulsory attributes, firstly name that gives the member name and secondly type that gives its type.
The struct tag has a compulsory "name" attribute that gives the name of the type.
Definition of elementary calculation nodes
-----------------------------------------------
.. _xml_script_node:
Python script node
'''''''''''''''''''''
A Python script inline node is defined using the inline tag with the script sub-tag as in
the following example:
.. code-block:: xml
The name attribute (compulsory) of the inline tag is the node name. The Python script is given using the code sub-tag. As many code
lines as necessary are added. A CDATA section can be used if the script contains unusual characters. This also makes it possible
to assure that only one code tag is used for a complete script.
For example:
.. code-block:: xml
The script calculates the variable p1 that is to be set as a node output variable. The output port “p1” of the node is defined
with the outport sub-tag. This tag has two compulsory attributes: name that gives the port name, and type that gives the supported
data type. This type must already be defined.
To add an input data port, the import tag will be used instead of the output tag.
An example node with input and output ports:
.. code-block:: xml
The node now receives p1 as the input variable, adds 10 to it and exports it as an output variable.
If you want to execute your script node on a remote container, you have to change the tag from **inline** to **remote**
and to add a tag **load** in the definition of the node as in the following example:
.. code-block:: xml
.. _xml_function_node:
Python function node
''''''''''''''''''''''''
A Python function node is defined using the inline tag and the function sub-tag as in the following example:
.. code-block:: xml
def f(p1):
p1=p1+10
return p1
The name attribute (compulsory) of the inline tag is the node name. The only difference from the Python script node is in
the execution part (function tag instead of the script tag). The function tag has a compulsory name attribute that gives
the name of the function to be executed. The body of the function is given with code tags as for the script.
If you want to execute your function node on a remote container, you have to change the tag from **inline** to **remote**
and to add a tag **load** in the definition of the node as in the following example:
.. code-block:: xml
def f(p1):
p1=p1+10
return p1
.. _xml_service_node:
SALOME service node
''''''''''''''''''''''''
As stated in :ref:`principes`, there are two ways of describing a SALOME service node.
The first definition form uses the service tag and the component and method sub-tags as in the following example:
.. code-block:: xml
AddComponent
Add
The compulsory name attribute of the service tag gives the node name. The component tag gives the name of the SALOME
component to be used and method gives the name of the service to be executed. The objective in this case is to execute
the AddComponent (Add component) service that is located in SALOME example components.
The second definition form uses the service tag and the node and method sub-tags as in the following example:
.. code-block:: xml
node4
Setx
The node tag references the previously defined node4 so as to use the same component instance for node4 and node5.
Definition of connections
-----------------------------
We will need to define a source node and/or a target node for all of the following concerning port connections and initialisations.
In all cases, the name that will be used is the relative node name, considering the connection definition context.
Control link
''''''''''''''''''
A control link is defined using the control tag as in the following example:
.. code-block:: xml
node1
node2
The fromnode sub-tag gives the name of the node that will be executed before the node with the name given by the tonode sub-tag.
Dataflow link
''''''''''''''''
A dataflow link is defined using the datalink tag as in the following example:
.. code-block:: xml
node1 p1
node2 p1
The fromnode and fromport sub-tags give the name of the node and the output data port that will be connected to the node
and to the port for which the names are given by the tonode and toport sub-tags. The above link example states that the output
variable p1 of node node1 will be sent to node node2 and used as an input variable p1.
Data link
''''''''''
A data link is defined using the same datalink tag, but adding the control attribute and setting the value equal to false.
Example:
.. code-block:: xml
node1 p1
node2 p1
Therefore the above dataflow link can also be written as follows:
.. code-block:: xml
node1
node2
node1 p1
node2 p1
.. _initialisation:
Initialising an input data port
-----------------------------------------------
An input data port can be initialised with constants by using the parameter tag, and the tonode, toport and value sub-tags.
The toport tag gives the name of the input port of the node with the name tonode to be initialised.
The initialisation constant is given by the value tag.
The constant is encoded using the XML-RPC coding convention (http://www.xmlrpc.com/).
Example initialisation:
.. code-block:: xml
node1 p1
coucou
Port p1 of node node1 is initialised with a character string type constant (“coucou”).
The following gives some examples of XML-RPC coding:
============================ ==============================================
Constant XML-RPC coding
============================ ==============================================
string "coucou" ``coucou``
double 23. ``23``
integer 0 ``0``
boolean true ``1``
file ``/tmp/forma01a.med``
list of integers .. code-block:: xml
1
0
structure (2 members) .. code-block:: xml
s
1
t
1
============================ ==============================================
First example starting from previous elements
------------------------------------------------------
A complete calculation scheme can be defined with definitions of nodes, connections and initialisations.
.. code-block:: xml
ECHO
echoDouble
node1 node2
node1 node4
node1 p1
node2 p1
node1 p1
node4 p1
node1 p1
5
The scheme includes 2 Python nodes (node1, node2) and one SALOME node (node4).
Nodes node2 and node4 can be executed in parallel as can be seen on the following diagram.
.. image:: images/ex1.png
:align: center
Definition of composite nodes
-----------------------------------
The next step is to define composite nodes, either to modularise the scheme (Block) or to introduce control structures (Loop, Switch).
.. _xml_block:
Block
''''''''
All the previous definition elements (except for data types) can be put into a Block node.
A Block can be created simply by using a bloc tag with a compulsory name attribute, the name of which will be the block name.
The next step is to add definitions in this tag to obtain a composite node that is a Block.
The following is an example of a Block that uses part of the above example:
.. code-block:: xml
ECHO
echoDouble
node1 node4
node1 p1
node4 p1
This block can now be connected to other nodes like a simple elementary node.
A few rules have to be respected:
- a control link crossing a block boundary cannot be created
- input and output data links crossing the boundary can be created provided that a context sensitive naming system is used (see :ref:`nommage`)
.. _xml_forloop:
ForLoop
'''''''''''
A Forloop is defined using a forloop tag. This tag has a compulsory name attribute, the name of which is the node name and an
optional nsteps attribute that gives the number of loop iterations to be executed. If this attribute is not specified, the node will
use the value given in its input port named nsteps. The forloop tag must contain the definition of one and only one internal node
that can be an elementary node or a composite node. Forloops can be nested on several levels, for example. If we would like to have
more than one calculation node in the ForLoop, a Block will have to be used as the internal node.
Consider an example:
.. code-block:: xml
This represents a loop that will be executed 5 times on a Python script node.
The rules to be respected to create links are the same as for the blocks. To make iterative calculations, it must be possible
to connect an output port of an internal node with an input port of this internal node. This is done using a data link that is
defined in the context of the Forloop node.
The following example applies to looping on port p1:
.. code-block:: xml
node2 p1
node2 p1
If the number of steps in the loop is calculated, the nsteps input port of the loop will be used as in the following example:
.. code-block:: xml
nnsteps
l1 nsteps
Finally, if the internal node needs to known the current step of the loop it can use the loop output port
named "index".
.. _xml_whileloop:
WhileLoop
''''''''''''
A WhileLoop is defined using the while tag. It has a single compulsory attribute “name”, that carries the node name.
The input port with name “condition” must be connected for the loop to be valid.
The following is an example of a While loop that increments the variable p1 until it exceeds the value 40:
.. code-block:: xml
node2 p1
node2 p1
l1.b.node2 condition
l1 condition
l1.b.node2 p1
23
Obviously, nested while loops can be defined.
.. _xml_foreachloop:
ForEach loop
''''''''''''''''
The ForEach loop is defined using the foreach tag. It has 2 compulsory attributes: name that bears the name of the ForEach
node and type that gives the type of elements in the collection on which the loop will iterate. A third optional attribute
nbranch is used to fix the number of parallel branches that the loop will manage. If this attribute is not supplied, the input
data port of the loop named "nbBranches" must be connected.
The foreach tag must contain the definition of one and only one internal node (elementary or composite).
The following is a minimal example of the ForEach loop:
.. code-block:: xml
def f(p1):
p1= p1+10.
print p1
return p1
node0p1
b1 SmplsCollection
b1evalSamples
b1.node2 p1
b1.node2p1
node1 p1
A first Python script node constructs a list of doubles. This list will be used by the ForEach loop to iterate (connection
to the SmplsCollection input port). The internal node of the loop is a Python function node that adds 10 to the element that it processes.
Finally, the results are collected and received by the Python node node1 in the form of a list of doubles.
.. _xml_switch:
Switch
''''''''''
A Switch node is defined with the switch tag. It has a single compulsory name attribute that carries the name of the node.
Each case is defined with the case sub-tag. The default case is defined with the default sub-tag.
The case tag has a compulsory id attribute that must be an integer. The default tag has no attribute.
A minimal switch example:
.. code-block:: xml
n b1
nselect
b1 select
b1.p3_n2 p1
54
b1.default_n2 p1
54
.. _xml_optimizerloop:
OptimizerLoop
''''''''''''''''
An OptimizerLoop node is defined with the **optimizer** tag. It has a compulsory name attribute that carries the name of the node.
It has two other compulsory attributes (**lib** and **entry**) that define the C++ or Python plugin (parameters with same names).
It can have the attribute **nbranch** or an input port **nbBranches** to define the number of branches of the loop.
The OptimizerLoop ports (**nbBranches**, **algoInit**, **evalSamples**, **evalResults** and **algoResults**) need not be defined as they
are already defined at the creation of the node.
A minimal OptimizerLoop example:
.. code-block:: xml
b1evalSamples
b1.node2 p1
b1.node2p1
b1 evalResults
Definition of containers
--------------------------------
YACS containers must be defined immediately after data types have been defined and before calculation nodes are defined.
A container is defined using the container tag. This tag has a single compulsory attribute that is the container name.
Constraints on placement of the container are specified using properties defined with the property sub-tag.
This tag has two compulsory attributes, the name and the value, that give the name of the constraint and its value in the
form of a character string.
The following is an example of a container defined by the graphic user interface:
.. code-block:: xml
Once containers have been defined, SALOME components can be placed on this container.
This information simply has to be added into the definition of the SALOME service node using the load sub-tag.
This tag has a single compulsory attribute named container that gives the name of the container on which the SALOME component will be located.
If the SALOME service defined above is to be placed on the DefaultContainer container, we will write:
.. code-block:: xml
AddComponent
Add
Node properties
-----------------------------
Properties can be defined for all elementary and composite nodes.
However, they will only really be useful for SALOME service nodes.
A property is defined by adding a property sub-tag in the definition of a node.
The property tag has 2 compulsory attributes, name and value, that carry the name of the property and its value in the form of a character string.
Example with a SALOME service node:
.. code-block:: xml
AddComponent
Add
In the case of a SALOME service node, the property is transmitted to the component and by default is set as an environment variable.
.. _xml_active_study:
Datastream connections
----------------------------
Datastream connections are only possible for SALOME service nodes, as we have seen in :ref:`principes`. Firstly, datastream ports
have to be defined in the service node. An input datastream port is defined with the instream subtag.
This tag has 2 compulsory attributes, firstly name that gives the port name and secondly type that gives the supported data
type (see :ref:`principes` for datastream types).
The outstream tag is used instead of the instream tag to define an output datastream port.
The property sub-tag is used with its two attributes name and value to define a property associated with the port.
See :ref:`calcium` for a list of possible properties.
The following gives an example definition of the SALOME service node with datastream ports. It is the DSCCODC component
that can be found in the DSCCODES module in the EXAMPLES base. Datastream ports are of the integer type with time dependence.
.. code-block:: xml
DSCCODC
prun
The stream tag is used to define datastream links. Fromnode and fromport sub-tags give the name of the node and the output
datastream port that will be connected to the node and to the port, the names of which are given by the tonode and toport sub-tags.
The parameters for a datastream link can be set with properties (see :ref:`calcium`).
A property is defined with the property sub-tag.
The following is a more complete example with parameters set for datastream links. There are two SALOME components with
integer type datastream ports with time dependency (TIME_DEPENDENCY).
The datastream connections use an explicit time scheme (TI_SCHEM).
.. code-block:: xml
DSCCODC
prun
DSCCODD
prun
node2 STP_EN
node1 ETP_EN
node1 STP_EN
node2 ETP_EN
Other elementary nodes
--------------------------------
SalomePython node
'''''''''''''''''''''''
This type of node is defined with the sinline tag. It has a compulsory attribute name that carries the node name.
It is defined using the same sub-tags as for the Python function node: function for the Python code to be executed, inport
and outport to define its input and output data ports.
The placement on a container is defined using the load sub-tag as for the SALOME service node.
The following is an example of a call to the PYHELLO component from a SalomePython node:
.. code-block:: xml
import salome
salome.salome_init()
import PYHELLO_ORB
def f(p1):
print __container__from__YACS__
machine,container=__container__from__YACS__.split('/')
param={}
param['hostname']=machine
param['container_name']=container
compo=salome.lcc.LoadComponent(param, "PYHELLO")
print compo.makeBanner(p1)
print p1
The PYHELLO component will be placed on container A. YACS selects the container. The result of the choice is accessible
in the python __container_from_YACS__ variable and is used by the node to load the component using the SALOME LifeCycle.
.. _xml_datain:
Datain node
''''''''''''''''
This type of node is defined with the datanode tag. It has a compulsory attribute name that carries the node name.
Node data are defined using the parameter sub-tag. This tag has two compulsory attributes, name and type, that give
the data name and its type respectively. The initial value of the data is supplied by the value sub-tag of the parameter tag
using the XML-RPC coding (see :ref:`initialisation`).
The following is an example of a DataIn node that defines two double type data (b and c) and a file type data (f):
.. code-block:: xml
f.data
5.
-1.
.. _xml_dataout:
DataOut node
''''''''''''''''
This type of node is defined with the outnode tag. It has a compulsory attribute, name and an optional attribute, ref.
The name attribute carries the node name. The ref attribute gives the file name in which the values of results will be saved.
The parameter sub-tag is used to define results of the node. This tag has two compulsory attributes, name and type, that
give the result name and its type respectively, and one optional attribute, ref.
The ref attribute is only useful for file results. If it is defined, the result file will be copied into the file with the
name given by the attribute. Otherwise, the file will be a temporary file usually located in the /tmp directory (possibly on a remote machine).
The following is an example of a DataOut node that defines 5 results (a, b, c, d, f) of different types (double, int,
string, doubles vector, file) and writes the corresponding values in the g.data file.
The result file will be copied into the local file myfile:
.. code-block:: xml
.. _xml_studyin:
StudyIn node
'''''''''''''''
This type of node is defined as a DataIn node with the datanode tag. All that is necessary is to add the kind attribute
with the “study” value.
The parameter sub-tag will be used to define the node data. This tag has two compulsory attributes, name and type, that give the
data name and type respectively. The ref attribute gives the input into the study in the form of a SALOME Entry, or a
path in the study tree structure.
The following is an example of a StudyIn node that defines 2 data (b and c) with types GEOM_Object and Boolean. It is assumed
that SALOME has loaded the study into memory. Data b is referenced by a SALOME Entry.
The data c is referenced by a path in the study tree structure.
.. code-block:: xml
.. _xml_studyout:
StudyOut node
''''''''''''''''''
This type of node is defined as a DataOut node with the outnode tag and the name attribute.
All that is necessary is to add the kind attribute with the value “study”.
The optional ref attribute gives the name of the file in which the study will be saved at the end of the calculation.
The parameter sub-tag will be used to define the node results. This tag has two compulsory attributes, name and type, that
give the data name and type respectively. The ref attribute gives the entry into the study in the form of a SALOME Entry, or
a path in the study tree structure.
The following gives an example of the StudyOut node that defines 2 results (a and b) of the GEOM_Object type.
The complete study is saved in the study1.hdf file at the end of the calculation:
.. code-block:: xml