A Sequencer for starting and stopping runs was implemented in June 2011. Since then development has continued, with more commands being added, and the option of using a Midas Script Language (MSL) for commands, in addition to the XML language.
The sequencer runs inside mhttpd. The first time the button on the Status Page is pressed, the ODB Sequencer Tree is created. If the Sequencer button is not present on the Status Page, it may have been suppressed.
The sequencer runs scripts in XML or MSL (Midas Script Language) format, which reside on the server (where mhttpd is running). The sequencer state is completely stored in the ODB, meaning that even if mhttpd is stopped and restarted, the active sequence operation continues exactly where it has been stopped.
Refer to the /Sequencer ODB tree for more details on its organization.
The following commands are implemented in the MIDAS Sequencer. The left syntax is for the XML file, the right for the MSL (Midas Script Language).
Variable names are indicated in italic, options are enclosed in [brackets].
|XML format||MSL format||Description|
|< !DOCTYPE RunSequence[< !ENTITY name SYSTEM "name.xml" >]> &name;||INCLUDE name||Include another XML file name.xml|
|<Call name="name"> a,b,c...</Call>||CALL name, a, b, c, ...||Call a subroutine. Optional parameters a,b,c... are passed to the subroutine, where they can be referenced via $1, $2, $3, etc. The subroutine can either reside in the current file, or in a library file which is included.|
|<Cat name="name"> a,b,c... </Set>||CAT name, a, b, c, ...||Concatenates the strings a,b,c,... into a single variable name . Can be referenced with $name. If a string must contain a comma, it can be enclosed in quotes such as in CAT title $run, ",", $n events|
|<Comment> comment </Comment>||COMMENT comment||A comment for this XML file, for information only. This comment is shown when one clicks on the XML file in the browser inside the web page and can be used to show some information about an XML file. This can be helpful if one has many XML files and the file name only is not enough to supply enough information.|
|<Goto line="n" / >||GOTO n||Jump to line n in script|
|<If condition="con" >...</if>||IF con ... ENDIF||Statements between <if> and </if> are only executed if condition con is true. The condition can use variables via $name and/or constants together with operators "<", "<=", ">", ">=", "==", "!=", "&" (bitwise AND).|
|<Library name="name" >...</Library>||LIBRARY name||Indicates that the current file is a library (which can be included by other files). A library usually consists of a set of subroutines.|
|<Loop n="n" [var="name"]> ... </Loop>||LOOP [name ,] n ... ENDLOOP||To execute a loop n times. For infinite loops, "infinite" can be specified as n. Optionally, the loop variable running from 1..n can be accessed inside the loop via $name.|
|<Loop var="name" values="a,b,c,..."> ... </Loop>||LOOP name, a, b, c, ... ... ENDLOOP||Loop though a list of values. The loop is executed once for each value, which is stored into the variable name so it can be accessed inside the loop via $name.|
|<Message [wait="1"]> message </Message>||MESSAGE message [,1]||Opens a message box in the browser containing the text message. If wait="1", then the sequencer waits until the box is closed by the user before continuing.|
|<ODBGet path="path" > name </ODBGet>||ODBGET path, name||To get a value from a variable name. The variable can then be referenced with $name.|
|<ODBInc path="path" > delta </ODBInc>||ODBINC path [, delta]||To increment a value in the ODB. delta can be positive or negative. If no "delta" is given, 1 is used.|
|<ODBSet [notify="0|1"] path="path" > value </ODBSet>||ODBSET path, value [, 0|1]||To set a value in the ODB. The notify flag specifies if possible hot-links to this ODB value are notified. This can be useful if a front-end program has many parameters, which must be set for a specific run. The front-end usually has a hot-link to its parameters, so on each modification a callback function in the front-end is called which usually modifies some hardware. If there are many ODBSet statements for all parameters, the callback would be executed on each ODBSet, so the hardware would be reconfigured many times slowing down the startup of a run. In order to prevent this, notify="0" can be specified for all ODBSet statements except the last one which contains notify="1", so the callback function is called only once at the end.|
|<ODBSubdir path="path" >...</ODBSubdir>||ODBSUBDIR path ...ENDODBSUBDIR||If one wants to se several ODB values in the same directory, the ODBSet commands can be rather long if thepath is long. Using this command, the subdir can be specified for all commands between the opening and ending tags. So instead of writing |
|<Param name="name" [comment="comment"][options="a,b,c,..."] [type="bool"] />||PARAM name, comment, [a,b,c | bool]||When starting a script, a start page is shown where one can enter additional parameters for the script. Parameters can be defined either centrally for all scripts in the ODB under /Experiment/Edit on sequence. This subdirectory in the ODB can contain links to ODB values, which are queried at the start page. In addition, each script can define additional parameters appended to this list. They will be stored under /Sequencer/Variables and can be referenced inside the script via $name, where name can be any variable name specified in the parameter statement. The optional "comment" is shown on the start page below the parameter name. If only certain options are possible for the parameter, they can be defined via the options list. The web page will then contain a drop-down list showing the options. In case of type="bool", a checkbox will be shown.|
|<RunDescription> description </RunDescription>||RUNDESCRIPTION description||a run description which is stored under /Experiment/Run Parameters/Run Description .|
|<Script [params="a,b,c,..."]> script </Script>||SCRIPT script [, a, b, c, ...]||To call a script on the server side. Optionally, pass parameters to the script.|
|<Set name="name"> value </Set>||SET name, value||Sets the variable name to "value". The variable can then be referenced with $"name".|
|<Subroutine name="name">...</Subroutine>||SUBROUTINE name ... ENDSUBROUTINE||Declares a subroutine which can be called via CALL.|
|<Transition>Start | Stop</Transition>||TRANSITION start | stop | pause | resume||To start, stop, pause or resume a run|
|<Wait for="events | ODBvalue | seconds" [path="ODB path"] [op=">=/>/<=/</==/!="]> value </Wait>||WAIT events | ODBvalue | seconds, [ODB path], [op], [value]||Wait until a number of events is acquired (testing /Equipment/Trigger/Statistics/Events sent), or until a value in the ODB exceeds value, or wait for value seconds. If the operand op is given, the ODB value is compared with value using this operand. So one could wait until an ODB value is equal to value or becomes smaller than value. Here is an example of such a statement which waits until some high voltage is below 100 V.
WAIT ODBvalue, /Equipment/HV/Variables/Measured, <, 100
The following example is a simple script, which writes a run description to the ODB, asks for a number of runs, then executes the runs, each running for 3000 events.
COMMENT "This is a MSL test file" RUNDESCRIPTION "Test run" PARAM runs LOOP $runs TRANSITION START WAIT events 3000 TRANSITION STOP ENDLOOP
The following XML script does exactly the same.
<?xml version="1.0" encoding="ISO-8859-1"?> <RunSequence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation=""> <Comment>This is a XML test file</Comment> <RunDescription>Test run</RunDescription> <Param name="runs" /> <Loop n="$runs"> <Transition>START</Transition> <Wait for="events">3000</Wait> <Transition>STOP</Transition> </Loop> </RunSequence>