| 37 | If the conduit entrance and exit have the same name, the second argument of {{{tie}}} is optional. |
| 38 | |
| 39 | === Filters === |
| 40 | |
| 41 | If a conduit filter should be applied to a conduit, these can be added as a list as the last argument of {{{tie()}}}: |
| 42 | {{{ |
| 43 | cs.attach('w' => 'r') { |
| 44 | tie('dataOut', 'dataIn',['muscle.core.conduit.filter.MultiplyDoubleFilter_0.5']) |
| 45 | } |
| 46 | }}} |
| 47 | In the example, the MUSCLE filter {{{MultiplyDoubleFilter}}} is applied, which multiplies each double with a value, in this case 0.5. For user defined filters, one double argument may be given, separated from the class name by an underscore. MUSCLE already supplies some custom filters, the filter package is {{{muscle.core.conduit.filter}}}: |
| 48 | ||= Filter =||= Class =||= Arguments =||= Message datatype =||= Behavior =|| |
| 49 | ||{{{null}}} ||{{{NullFilter}}} ||none ||any ||Removes all incoming messages|| |
| 50 | ||{{{pipe}}} ||{{{PipeFilter}}} ||none ||any ||Forwards all incoming messages unchanged|| |
| 51 | ||{{{console}}} ||{{{ConsoleWriterFilter}}} ||none ||any ||Prints all messages to console and forwards them|| |
| 52 | ||{{{linearinterpolation}}} ||{{{LinearInterpolationFilterDouble}}} ||none ||{{{double[]}}} ||Creates a {{{double[]}}} of length-1 of the original, and linearly interpolates between the original values: {{{k'_i <- (k_i+k_{i+1})/2}}}|| |
| 53 | ||{{{multiply}}} ||{{{MultiplyFilterDouble}}} ||{{{double factor}}} ||{{{double[]}}} ||Multiplies each value of the incoming message by {{{factor}}}|| |
| 54 | ||{{{drop}}} ||{{{DropFilter}}} ||{{{int step}}} ||any ||Drops messages that are not a multiple of {{{step}}}|| |
| 55 | ||{{{timeoffset}}} ||{{{TimeOffsetFilter}}} ||{{{double time}}} ||any ||Adds an offset {{{time}}} to the timestamps of messages|| |
| 56 | ||{{{timefactor}}} ||{{{TimeFactorFilter}}} ||{{{double factor}}} ||any ||Multiplies the sent timestamp of messages|| |
| 57 | ||{{{blockafter}}} ||{{{BlockAfterTimeFilter}}} ||{{{double time}}} ||any ||Drops messages with a timestamp greater than {{{time}}}|| |
| 58 | ||{{{lineartimeinterpolation}}}||{{{LinearTimeInterpolationFilterDouble}}}||{{{int step}}}||{{{double[]}}} ||For {{{step==2}}}, forwards the first message and then sends two messages for every message received, interpolating between one message and the next.|| |
| 59 | |
| 60 | For convenience, the MUSCLE filters may be referred to by their name instead of their class: |
| 61 | {{{ |
| 62 | cs.attach('w' => 'r') { |
| 63 | tie('dataOut', 'dataIn',['multiply_0.5','console']) |
| 64 | } |
| 65 | }}} |
| 66 | |
| 67 | === Terminals === |
| 68 | |
| 69 | It may be convenient to couple a submodel to dummy terminals, to evaluate its individual behavior, or to read a message from file instead of receiving it from another submodel. A terminal is initialized by calling |
| 70 | |
| 71 | {{{ |
| 72 | cxa.add_terminal('readA', 'muscle.core.conduit.terminal.DoubleFileSource') |
| 73 | cxa['readA:filename'] = "/path/to/some.file.dat" |
| 74 | cxa['readA:relative'] = false |
| 75 | cxa['readA:delimiter'] = ',' |
| 76 | |
| 77 | cs.attach('readA' => 'r') { |
| 78 | tie('dataIn') |
| 79 | } |
| 80 | }}} |
| 81 | Here, we're reading the file {{{/path/to/some.file.dat}}}, and the path is not relative to the runtime path of MUSCLE. The doubles in that file are delimited by commas. Finally, a terminal port takes any name of the receiving or sending end, so only one value is given to tie. For the moment, it is not possible to apply filters to terminals. |