Text

The Text block can generate a file based on a template using values of variables received to input ports, and extract values from an input file in order to send them to output ports. Its configuration is based on a template file — usually a sample of some program’s input or output.

Introduction

The Text block is a custom file processor which can read data from text files and change their contents. It is primarily used to create input and output adapters for integrating third-party applications into pSeven workflows (see the Integration Basics tutorial).

If the integrated application requires an input file with parameters, the Text block uses a template file (a sample of input) to generate input files when running. It reads template contents, replaces specified areas with values received to input ports, and outputs a new file with changed parameters. This file is then sent to the block which launches the application (usually a Program block).

Application output can be parsed with the Text block if the application is able to save its results to a text file. Also it can be used with an application which sends results to the standard output (prints to the command prompt window), because this output is easily redirected to a file. A Text block which is used to get values from a program output receives an output file from the block which launches the application, reads data from specified locations in the file, and sends data values to output ports. In this case, the template file is not required to run, however having a sample of output is convenient when configuring the block.

General logic of the Text block is always the same:

  • Get values of input variables (received to ports) and the input file. The input file may be the same file which you used as the template, or a file received from another block.
  • Copy the input file to memory and perform operations over this copy (write input values, get values of output variables).
  • Send values of output variables and the file (changed copy) to output ports.

Two typical cases of using the Text block are outlined above. However, these are not some presets — rather they are two commonly used combinations of settings. Sections Generate Program Input and Parse Program Output explain these two frequently used configurations in more detail. Other configurations are also possible — for example, the block can read and write to the same file at once, if needed.

Text blocks can be used in an optimization workflow which runs an external solver for function evaluations. In such a workflow, one Text block receives values of variables from Optimizer and creates an input file for the solver; the other receives solver’s output, reads result values and sends them to Optimizer (see Integrated Component Optimization).

With the Text block, you can also generate complex text reports, create custom configuration files for your workflows, and perform other text-related tasks. It also supports Python scripting and allows to combine general Python code with its built-in functions. Note though, that it is not intended to read simple tabular files like the CSV format. In most cases, such files are easier to read and write using the CSVParser and CSVGenerator blocks.

Configuration Dialog

Usually a Text block is configured using a template file where you select values in the text and specify which variables to read or write.

../_images/page_blocks_Text_configure.png

The main pane 1 shows the template file contents. You can reload the template or open it in your default text editor using the toolbar buttons 2. If the input is an existing file on disk, this file is automatically shown as the template, and browsing for a template file is disabled. Loading a separate template 3 is needed, for example, when the input file is received to a port (the block is used to parse program output).

Input and output files are configured on the panes 4 and 5. The b_browse buttons on these panes open the common Configure file dialog — for its detailed description, see the File block page.

The Operations pane 6 shows the sequence of operations that the block will perform when running, such as reading or writing values in the file. Here you can edit the sequence and test it before running the workflow, using the commands available on the pane’s toolbar and in its b_blconf_context menu (see Testing).

The Variables pane 7 shows block variables, their names, types and test values. This pane allows editing variables that were added from the template, as well as adding variables manually. Test values of variables shown here are used when you run operation tests. The b_locate button on the pane’s toolbar works much like the find function for test results: it locates values of variables which were read or changed by the tested operations. Use it after testing to check that test values of variables are in line with the template values.

Generate Program Input

When the Text block generates an input file for some program, it needs a sample of such a file. The output of the block is a file which contains parameters received from other blocks in the workflow, from workflow configuration in Run, or other sources.

../_images/page_blocks_Text_configure_input.png
  • Click b_browse in the Input file pane to open the Configure file dialog.
  • In the dialog, set file origin to project and browse for a file. Click OK in the dialog to return to block configuration.
  • The generated file is sent to the port named output by default. When you use Text to write parameters to a file, there is no need to change any settings on the Output file pane.
  • The file you selected as input is automatically used as the template 1. Note that the block assumes the UTF-8 file encoding by default. If your file uses another encoding, select it using the Text encoding option.
  • In the template, select the values you want to replace 2.
  • When you release the mouse button, a pop-up appears 3 which lets you create a new input variable or select an existing one.
  • Input a name or select a variable, then click the write button b_blconf_write in the pop-up.
  • Required operations 4 are added automatically. If you have input a new variable name, the block also creates this variable 5 and sets its properties.
  • The block automatically tests new operations. You can also run these tests manually — see Testing for details.
  • If parameter values are found in different parts of the template, repeat the above steps for other locations.

For more details on how selections work, see Quick Selection. Variables and operations can also be added manually — see sections Variables and Operations.

Parse Program Output

When the Text block parses an output received from some program, its input file comes from the block which launches this program. Since this file appears only during a workflow run, usually a separate template file (a sample of output) is used when configuring the block. The output of the block in this case contains parameter values found in the input file.

../_images/page_blocks_Text_configure_output.png
  • The input file is accepted to the port named input by default. When you use Text to read parameters from a file, there is no need to change any settings on the Input file pane. The output file is not used in this case. By default, it is still sent to the port named output; you can disable this in the Output file pane settings.
  • To load a template file, click b_browse in the Template file pane and navigate to the file. The template should be an example of the input file which the block is going to receive when the workflow runs.
  • The Template file pane shows file contents 1. Note that the block assumes the UTF-8 file encoding by default. If your file uses another encoding, select it using the Text encoding option. Note also that when the block is configured to parse a program’s output, it actually never reads the template file when running — the template is useful only when configuring the block, since it simplifies adding variables and operations.
  • In the template, select the values to read from file 2.
  • When you release the mouse button, a pop-up appears 3 which lets you create a new input variable or select an existing one.
  • Input a name or select a variable, then click the read button b_blconf_read in the pop-up.
  • Required operations 4 are added automatically. If you have input a new variable name, the block also creates this variable 5 and sets its properties.
  • The block automatically tests new operations. You can also run these tests manually — see Testing for details.
  • If parameter values are found in different parts of the template, repeat the above steps for other locations.

For more details on how selections work, see Quick Selection. Variables and operations can also be added manually — see sections Variables and Operations.

Quick Selection

Quick selection is intended to simplify Text block configuration. It is not as flexible as adding and editing operations manually, and cannot cover all use cases. Quick selection when parameter values are located in a column, row, or other rectangular area in the template, and this table-like area is formatted properly. The block automatically resolves your selections and adds operations that relocate the working frame and read or write data.

Note that a selection should include only the values to be replaced, not entire lines in the template — see the examples in Generate Program Input and Parse Program Output.

Typical examples of using quick selection:

  • A single value or word in the template is resolved to a scalar variable — for example, RealScalar or StringScalar.
  • A row or column of values is resolved to a vector variable by default. Note that if there are multiple columns and you want to select just one of them, this works only if the columns do not overlap — that is, there are no ambiguous value placements. Such selections can also use List variables.
  • A table-like area with multiple rows and columns is resolved to a matrix variable. This works only if the “table” is rectangular (all rows and columns have the same number of values).

A selection may also include numeric values with column or row names (text labels). Such selections use Dict variables — associative arrays of (key, value) pairs, where keys have the same names as columns (rows).

Dict variables are useful if you have a big set of named values and want to avoid creating a specific variable for each value. Also, a Dict variable does not rely on the order of components, as vector or List variables do. The value under a key is usually a vector which corresponds to a row or column in the template. Scalars or single-element vectors can also be used to replace or read scalar values in the template.

For example:

../_images/page_blocks_Text_dict_selection1.png

This selection can be replaced with a Dict {"x1": 1.1, "x2": -0.9} (contains scalars) or {"x1": (1.1), "x2": (-0.9)} (contains single-element vectors).

Another example:

../_images/page_blocks_Text_dict_selection2.png

This selection can be replaced with a Dict {"x1": (1.1, 2.1), "x2": (1.2, 2.2), "x3": (1.3, 2.3)}.

Note

Dictionary replacements also work with named rows and columns of different lengths, but in such cases the block may be unable to resolve the selection automatically, so you will have to add operations manually.

Testing

You can test the Text block before running the workflow, verifying that operations are performed correctly. When you use quick selections, the block automatically tests new operations and shows results. You can also run tests manually — for example, to test the entire sequence of operations after making some quick selections.

Testing Operations

To test operations, use the buttons on the Operations pane toolbar:

  • b_blconf_test tests all operations in the list.
  • b_blconf_test_next tests the next untested operation only.
  • b_common_sweep clears test results: removes test values from the template and reverts all operations to untested state.

Note that before testing the Write value… and Insert value… operations, you should set test values for input variables. To add a test value, double-click the “Test value” field for a variable, or select Edit variable… from the Variables pane’s b_blconf_context menu.

../_images/page_blocks_Text_test_passed.png

When you run tests, the test values 1 of variables are shown highlighted 2 in the template. These changes are not saved to the template file. Tooltips 3 on the Template file pane provide a few more details on test results.

The Write value… operation shows test values as if they are written into the template. The Read value… operation gets values of variables from the template and shows them in the “Test value” column on the Variables pane. Note that although this operation sets new test values, you should also specify initial test values before running the test. The block needs these initial test values to determine the shape of a variable — for example, the number of components in a vector or rows in a matrix. Without this information, it cannot check that a value is read correctly and that it fills all components of a variable.

../_images/page_blocks_Text_test_failed.png

If a test fails, the unsuccessful operation is marked in the list 1 and in the template 2, and error details 3 are shown on the Template file pane.

Locating Variables

After testing operations, you can quickly check the results of your test — the values of variables read from the template and a preview of changes applied by the block to the template. To scan changes in the template, select a variable 1 in the Variables pane and click the b_locate button 2 on the pane’s toolbar. The block finds the first operation which uses the selected variable and highlights 3 the template lines which are in scope of this operation.

../_images/page_blocks_Text_locvar.png

If the variable is used by multiple operations, clicking b_locate again jumps to the next operation and highlights related lines in the template. In the above example, the block writes two components of the variable named “S3” using two different operations. The result of the first operation is located on the line 342 which is highlighted. Clicking b_locate again would locate the result of the second operation on the line 344 and highlight that line.

Note that locating variables is possible only if they are used by operations which are already tested. An attempt to locate an “untested” variable shows an error in the Template file pane.

Advanced

This section provides more details on properties of variables, operations settings, scripting, and file configuration.

Variables

The Text block allows to declare variables manually and to edit properties of variables added by quick selections.

To add a variable, click b_blconf_add on the Variables pane. This button opens the Add variables dialog.

../_images/page_blocks_Text_addvar.png
  • Name: specifies the name of the variable. Names are case-sensitive. They should begin with a letter and contain only letters, numbers, and underscores. Multiple variables can be added at once using a comma-separated list of names. When you add multiple variables, all of them get the same properties. These properties can be edited afterwards.
  • Ports: selects which ports are created for the variable: input, output, or an input-output port pair. Port names are the same as the name of variable.
  • Type: selects the variable’s data type.
  • Test value: specifies the value to use when you test operations on the Operations pane. This setting is important both for input and output variables (see Testing Operations).

When you click Add in this dialog, the variable appears on the Variables pane and corresponding ports are added to the block. After you add a variable, you can edit its properties either on the pane (hover a property and click the edit icon) or using the Edit variable… command from the pane’s b_blconf_context menu.

Operations

Operations define how the block searches for data in the input file, reads and writes values. When you use quick selections, the block automatically configures the required sequence of operations and shows them on the Operations pane. You can edit the automatically added operations, add operations manually, and change their order.

  • To edit an operation, double-click it or select Edit operation… from the pane’s b_blconf_context menu.
  • To add operations manually, use the Add operation sub-menu in the pane’s b_blconf_context menu.
    • To insert an operation somewhere in the list, select an existing operation before adding a new one. The new operation will be added preceding the selected one.
    • To add an operation to the end of the list, deselect all operations first by clicking an empty area on the Operations pane.
  • To reorder operations, simply drag them in the list.

Reading and writing values can be understood as a two-step process. The block first sets a working frame inside the file using the Set frame start… and Set frame end… operations which search for specific text strings. After the frame is set, line indexing begins from the frame start. Indexing is zero-based: the line where the frame start is placed has index 0. The Write value…, Read value…, and Insert value… operations then use this line indexing to specify value locations. This method allows to work with values which can be found in different locations in the file, because it searches for a surrounding text first.

Initially the working frame start and end are placed on the first and the last line of the file. In the case when a value in the file is always on the same line, you can skip operations that set the working frame and simply specify this line’s index when configuring other operations. Note that indexing is also zero-based in this case: the first line of file is actually the working frame start and has index 0.

If you change the working frame location more than once, note that Set frame start… always searches from the current frame start position, going downwards, and Set frame end… searches from the current frame end going upwards. In most cases you should use the Reset frame operation before each relocation of the working frame.

Set frame start…

Searches down from the current frame start position. Finds a line that matches the specified pattern and sets the working frame start to a new location.

../_images/page_blocks_Text_set_start.png
  • The search begins from the current working frame start, which is not always the first line of file.
  • The search goes down.
  • If you want to search from the beginning, use Reset frame first.

The pattern can be a text string (default) or a regular expression.

The search skips matched lines until the number of matches reaches the value specified by the “Stop at N match” setting. By default, stops at the first occurrence.

After the search stops, the location can be additionally adjusted by moving a few lines up or down from the finally matched line.

Set frame end…

Searches up from the current frame end position. Finds a line that matches the specified pattern and sets the working frame end to a new location.

../_images/page_blocks_Text_set_end.png
  • The search begins from the current working frame end, which is not always the last line of file.
  • The search goes up from the current frame end.
  • If you want to search from the end of file (up from the last line), use Reset frame first.

The pattern can be a text string (default) or a regular expression.

The search skips matched lines until the number of matches reaches the value specified by the “Stop at N match” setting. By default, stops at the first occurrence.

After the search stops, the location can be additionally adjusted by moving a few lines up or down from the finally matched line.

Reset frame

Reset working frame start and end positions to default (the first line of file and the end of file, respectively). This operation has no additional settings.

Write value…

Writes the current value of a variable to the specified location within the working frame. Note that this operation is intended to replace existing values and cannot insert new lines — see Insert value… for this case.

../_images/page_blocks_Text_write_value.png
  • Variable: selects the variable to write. Alternatively, you can input a new name here to add the variable along with the operation.
  • Elements: intended for vector and matrix variables, allows selecting specific components to write. For a matrix variable, components are rows. Note that component indexing starts from 0.
    • All: write all components.
    • Index: write one component — a single element from a vector, or a single row from a matrix.
    • Slice: write a subset of variable’s data. This option uses the Python slice syntax (start:stop:step).
  • Lines: specifies lines to write within the working frame. Lines are indexed from the current frame start, and indexing starts from 0. Multiple lines can be specified as a list of numbers and ranges (2,5,7-11) or using the Python slice syntax (start:stop:step).
  • Delimiters: specifies strings interpreted as field separators in each line. Default delimiter is one or more whitespace or tab characters. Other delimiters can be specified using the regular expression syntax.
    • Regex: delimiter character, string, or regular expression. Allows specifying multiple delimiters — for example, >|< can be useful when the file contains XML tags (| means “or” in regular expressions). Note that there are more characters that have special meaning in regular expressions: . \ + * ? ^ $ [ ] { } ( ) | /. To be interpreted literally, these characters have to be escaped with a backslash, for example: \+.
  • Fields: specifies the fields to write. Fields are parts of the line separated by the delimiter. Similarly to lines, multiple fields can be specified as a list or a slice. To write all fields in a line, input :.
  • Format style: specifies the number format to use when writing values.
    • No format: default, writes values using the default Python formatting.
    • C: use C format specifiers, such as %.5f for a floating point value with a precision of 5.
    • Fortran: use Fortran format specifiers, such as F10.3 to write a floating point value with a precision of 3 aligned to a 10-character wide field.
  • Decimal separator: intended for numerical values with a floating point. Selects a specific decimal separator — point (default) or comma. By default, uses the character specified by the Decimal separator option.

Note that this operation writes the value which a block variable has at the moment when the operation is executed. Usually this value is received to the corresponding input port, however you can also set it by other means. For example, you can use the Read value… operation to set a variable and then write this variable to another location, or use the Python code… operation to assign a value manually.

Read value…

Reads data from the specified location within the working frame and assigns this value to a variable.

../_images/page_blocks_Text_read_value.png
  • Variable: selects the variable to store the data. Alternatively, you can input a new name here to add the variable along with the operation.
  • Elements: intended for vector and matrix variables, allows setting their specific components. For a matrix variable, components are rows. Note that component indexing starts from 0.
    • All: the data fills all components of a variable.
    • Index: fill one component — set a single element of a vector, or a single row of a matrix.
    • Slice: select multiple components to fill. This option uses the Python slice syntax (start:stop:step).
  • Lines: specifies lines within the working frame to read from. Lines are indexed from the current frame start, and indexing starts from 0. Multiple lines can be specified as a list of numbers and ranges (2,5,7-11) or using the Python slice syntax (start:stop:step).
  • Delimiters: specifies strings interpreted as field separators in each line. Default delimiter is one or more whitespace or tab characters. Other delimiters can be specified using the regular expression syntax.
    • Regex: delimiter character, string, or regular expression. Allows specifying multiple delimiters — for example, >|< can be useful when the file contains XML tags (| means “or” in regular expressions). Note that there are more characters that have special meaning in regular expressions: . \ + * ? ^ $ [ ] { } ( ) | /. To be interpreted literally, these characters have to be escaped with a backslash, for example: \+.
  • Fields: specifies the fields to read from. Fields are parts of the line separated by the delimiter. Similarly to lines, multiple fields can be specified as a list or a slice. To read all fields from a line, input :.
  • Convert to: selects the data type of the variable. This option should be used when you input a new name in the dialog (create a new variable with the operation). If you have selected an existing variable, the correct data type is selected automatically.

Note that this operation assigns a value to a block variable but does not immediately set the output port value. The value of variable is output only when the block finishes all operations. That is, reading data and storing it in a variable does not make this variable protected from further modifications. It is possible to change the value before output, collect data to a single variable using multiple reads (for example, to read different rows of a matrix variable), or use the stored value in the Write value… or Insert value… operations.

Insert value…

This operation can be understood as a special version of the Write value… operation. It can replace the entire working frame with data stored in a variable (removing all frame contents), or insert data above or below the working frame (adding new lines).

../_images/page_blocks_Text_insert_value.png
  • Placement: selects where to write the variable data. Writing above or below the working frame adds new lines as needed. Replacing the working frame means that all its contents are removed and the variable data is be added instead.
  • Transpose vector and matrix values: transposes vectors and matrices before writing. When disabled: vector variable becomes a single line; matrix rows are lines. When enabled: vector variable becomes a column on multiple lines; matrix columns are lines.
  • Separate with: selects the field delimiter. You can select one of the default delimiters or specify your own.
  • Decimal separator: intended for numerical values with a floating point. Selects a specific decimal separator — a point (default) or a comma. By default, uses the character specified by the Decimal separator option.

Other settings are the same as for the Write value… operation.

Python code…

Allows to add Python code snippets to the sequence of operations. Selecting this operation from the menu opens the code editor.

../_images/page_blocks_Text_pycode.png

The snippets contain general Python code. You can import modules, define functions and classes, and so on (see Scripting for more details). Note that all snippets work in the same scope shared with other operations — in particular, block variables from the Variables pane are visible as global variables in the code.

Scripting

All operations in the Text block are in fact function calls in the block’s script. This script can also be edited directly, allowing to combine general Python code with block operations.

Selecting Edit script… from the Operations pane’s b_blconf_context menu opens a window where you can view the script and make simple edits.

../_images/page_blocks_Text_edit_script.png

In the script, you can define functions and classes, import modules (see Built-in Modules), and so on. For long scripts it is better to use an external editor, then copy your code to the Edit script window.

Operations are called from the script using the methods of the template object which is a Template class instance. These methods provide replacements for a few most essential Python’s built-in methods of file objects, since you have no direct access to the template file from the script.

Names of input and output block variables are added to the script namespace as global variables. Your script can use other globals too, meaning that you are not required to declare every global as a block variable.

When the block starts, input variables in the script are automatically assigned values from corresponding input ports. For example, if you have an input port my_invar, then print my_invar outputs the received value to the run log when the block starts. If you assign a value to an output variable, this value is sent to a corresponding output port when the block finishes.

Note that when port values are assigned to or read from script variables, they are converted between pSeven and Python data types. For example, a RealMatrix input variable becomes a 2D numpy.ndarray of floats in the script (see Typesystem and Conversion Rules for details).

Scripting in the Text block does not require you to install Python because the block uses the pSeven’s in-built Python interpreter.

Template Class

class Template

Represents the template file. A Template object, named template, is initialized in the script by the block. You should use methods of this existing object.

insert(value, place='Above', delimiter=' ', transpose=False, format_style='No format', format_string='', format_decimal_separator='.')

Insert data values into the file.

Parameters:
  • value (float, int, str, bool, list, tuple, dict, numpy.ndarray) – the data to write
  • place (str) – insert placement
  • delimiter (str) – field delimiter (a whitespace by default)
  • transpose (bool) – whether to transpose vectors and matrices before writing
  • format_style (str) – number format
  • format_string (str) – number format string
  • format_decimal_separator (str) – decimal separator character

The value can be a block variable (a value received to an input port), a general Python variable (assigned in the script), or a value literal.

The insert placement specified by place can be:

  • 'Above': add new lines above the working frame.
  • 'Below': add new lines below the working frame.
  • 'Instead': replace the working frame.

The delimiter is the string to use as a field separator, empty string means no separators. Default delimiter is a single whitespace.

Numeric values in the text, which you insert to the template, can be formatted with format_style and format_string. The style selected by format_style can be one of the following:

  • 'No format': default Python formatting (as with %s). For this style, format_string is ignored.
  • 'C': C-style formatting.
  • 'Fortran': Fortran-style formatting.

If you select the C or Fortran style, in format_string you can use standard format specifiers of the selected language.

# replace the working frame with the contents of my_matrix,
# writing it transposed,
# adding semicolon delimiters between numbers in each line,
# and formatting numbers as floating point values with 5 decimals
template.insert(my_matrix, place='Instead', delimiter=';', format_style='C', format_string='%.5f', transpose=True)

See the Insert value… operation description for more details.

read(lines, fields, delimiter='', convert='RealScalar')

Read data from the file.

Parameters:
  • lines (str, int) – lines of the working frame to read from
  • fields (str, int) – fields to read
  • delimiter (str) – field delimiter
  • convert (str) – data type of the variable
Returns:

data

Return type:

float, int, str, bool, list, tuple, dict, numpy.ndarray

The lines and fields arguments can specify a comma-separated list of numbers and ranges ('1, 3-5, 8') or a range as a Python slice ('2:9:2', '-3:') — note that both forms are str. Single line or field number may be int.

The delimiter string is a regular expression. If the delimiter is an empty string, any number of whitespace characters is interpreted as a field separator.

Return type depends on the type of the variable set by convert (see Python to pSeven Types Conversion), which should be a string containing a pSeven typename — for example, 'IntScalar' or 'RealMatrix'.

# fill a vector variable (assume its length is 6) using two read operations

# read the first three fields from the third line of the working frame (indexed 2)
# and store these values to the first 3 vector components
my_vector[:3] = template.read(2, '1-3', delimiter=',|;|\/\/', convert='RealVector')

# read other three fields (8-10) from the third line of the working frame (indexed 2)
# and store these values to the next 3 vector components
my_vector[3:] = template.read(2, '8-10', delimiter=',|;|\/\/', convert='RealVector')

# the above operations recognize commas, semicolons, and double slashes as field delimiters
# note that slashes must be backslash-escaped

See the Read value… operation description for more details.

reset_frame()

Reset working frame start and end positions to default — the first line of file and the end of file, respectively.

# reset the working frame to cover the entire file
template.reset_frame()
set_frame_end(search, times=1, as_regex=False, shift=0)

Set location of the working frame end.

Parameters:
  • search (str) – search string
  • times (int) – how many times to repeat the search
  • as_regex (bool) – parse search as a regular expression
  • shift (int) – move shift lines down (up, if negative) after finally matching search

Search for a line that matches search, going up from the current frame end location, skipping matched lines until times matches are made, and finally applying shift.

# starting from the current frame end location, search upwards
# for lines that match the regular expression "^=+endsub"
# (lines starting with one or more = characters after which comes the word "endsub"),
# skip the first such line, stop on the second,
# and after stopping the search, move 2 more lines up
template.set_frame_end('=+endsub', times=2, as_regex=True, shift=-2)

See the Set frame end… operation description for more details.

set_frame_start(search, times=1, as_regex=False, shift=0)

Set location of the working frame start.

Parameters:
  • search (str) – search string
  • times (int) – how many times to repeat the search
  • as_regex (bool) – parse search as a regular expression
  • shift (int) – move shift lines down (up, if negative) after finally matching search

Search for a line that matches search, going down from the current frame start location, skipping matched lines until times matches are made, and finally applying shift.

# from the current frame start location, search downwards
# for lines that match the regular expression "^=+sub"
# (lines starting with one or more = characters after which comes the word "sub"),
# skip the first two such lines, stop on the third,
# and after stopping the search, move to the next line down
template.set_frame_start('^=+sub', times=3, as_regex=True, shift=1)

See the Set frame start… operation description for more details.

write(value, lines, fields, delimiter='', format_style='No format', format_string='')

Rewrite some data in the file.

Parameters:
  • value (float, int, str, bool, list, tuple, dict, numpy.ndarray) – the data to write
  • lines (str, int) – lines of the working frame where to write
  • fields (str, int) – fields to write
  • delimiter (str) – field delimiter
  • format_style (str) – number format
  • format_string (str) – number format string
  • format_decimal_separator (str) – decimal separator character

The value can be a block variable (a value received to an input port), a general Python variable (assigned in the script), or a value literal.

The lines and fields arguments can specify a comma-separated list of numbers and ranges ('1, 3-5, 8') or a range as a Python slice ('2:9:2', '-3:') — note that both forms are str. Single line or field number may be int.

The delimiter is the string to use as a field separator. Empty string means no separators.

Numeric values in the text you write to the template can be formatted with format_style and format_string. The style selected by format_style can be one of the following:

  • 'No format': default Python formatting (as with %s). For this style, format_string is ignored.
  • 'C': C-style formatting.
  • 'Fortran': Fortran-style formatting.

If you select the C or Fortran style, in format_string you can use standard format specifiers of the selected language.

# write 3 values from the my_params vector
# to the first (indexed 0) line of the working frame,
# rewriting fields 7 to 9 in this line,
# recognizing semicolons as field separators,
# and formatting numbers as floating point values with 5 decimals
template.write(my_params[3:6], 0, '7:10', delimiter=';', format_style='C', format_string='%.5f')
Template.write() dictionary example (see this example in section Quick Selection)
# a dictionary can be written to a table-like area in the template
# if its keys are the same as the names of the table's columns
my_table = {"x1": (1.1, 2.1), "x2": (1.2, 2.2), "x3": (1.3, 2.3)}

# each dictionary key corresponds to one column
# write all columns from the my_table dictionary to the three selected lines
# of the working frame (the first line must contain column headers)
template.write(my_table, '2-5', ':')

See the Write value… operation description for more details.

Built-in Modules

pSeven’s Python distribution includes a number of useful modules, which you can import in your scripts:

  • Scientific computing: numpy, pandas, scipy, sympy, scikit-learn, and networkx.
  • Plotting: bokeh and matplotlib with cycler.
  • PyWin32 modules — see PyWin32 Documentation.
  • Excel support: openpyxl, xlrd and xlwt. Note that pSeven also provides the Excel integration block.
  • Open Database Connectivity (ODBC) support: pyodbc. Note that using this module requires a working ODBC driver and related libraries installed in the system which runs pSeven.
  • Markup and parsing: et_xmlfile, fortranformat, markupsafe, pyparsing, whoosh, and yaml.
  • Networking: paramiko, requests, and tornado with tornado_json.
  • Cryptography: Crypto (PyCrypto) and ecdsa.
  • Various utilities: astor, decorator, and six; psutil and lockfile; dateutil, jdcal, and pytz.

Input and Output Files

The input and output files in Text can be configured in various ways using the common Configure file dialog (detailed on the File block page). This section notes some useful configurations, in addition to the most common ones described in sections Generate Program Input and Parse Program Output.

Get an input file from disk

When Text is used to parse a file, this file is usually received to the input port (has port origin). However, you can also set up file exchange on disk: set input file origin to sandbox and configure the Text block sandbox so it points to this file’s directory. This configuration may be useful if the files to parse are created by an external process, or their source is a block which saves files to disk instead of sending them to ports. In the latter case, you can set both the source block’s sandbox and the Text block sandbox to the same directory, designating it as a file exchange location — see section Sandbox for details.

Save the output file

Default output configuration creates a new file of temporary origin and sends it to the output port. Temporary files are not saved to disk when the workflow runs, but you can reconfigure the output to keep generated files.

If the block generates only one output file during each workflow run, you can simply change output file origin to project and specify its path relative to the project directory. If the file with this name does not exist, it will be created by the block. Note however that if it does exist, the block will overwrite its contents entirely. Also, if the path includes a subdirectory, this subdirectory must exist when the workflow starts: the block does not create directories automatically. You can create a new project subdirectory in Workspace using the Project pane.

If you change the file origin and leave the box in the Output port pane checked, the block will both output the generated file to port and write it to disk. This is a clear solution if you save only one file, but it does not work if the Text block runs inside a cycle, since it will write to the same file on each iteration and replace the previous results.

Save output files in a cycle

If the Text block runs in a cycle and saves generated files to disk, every file should have a unique name so they do not overwrite each other. Possible solution is to leave output file settings default and send the generated file to a Program block — the same which launches an external program, or an additional one which is used only to save the file. The Program block can create a copy of the incoming file, giving it a name with a timestamp.

For example, if Program accepts the generated temporary file to the my_infile input port, add a script line like following:

  • In Windows: copy @{my_infile} X:\\destination\\path\\filename_@{timestamp}.txt
  • In Linux: cp @{my_infile} ~/destination/path/filename_@{timestamp}.txt

This saved copy of the file is not removed when pSeven deletes the original (temporary) file. Here, @{timestamp} is a date and time substitution available in the Program block by default.

This solution can be combined with the Program sandbox setting to avoid using absolute destination paths. Use a relative sandbox path to place the sandbox directory inside your project (see section Sandbox for details). In the Program block’s script, remove destination path from the copy command, keeping the filename only. Thus file copies will be created in the sandbox directory you have configured, because it is the working directory for the block. For example, copy @{my_infile} filename_@{timestamp}.txt under Windows copies the received temporary file to YourProjectDirectory\SandboxDirectory\filename_timestamp.txt.

Note

The block which creates and controls a cycle (your cycle driver) may have an utility port, which outputs the index of current cycle iteration. For example, the Design space exploration block provides a set of blackbox index ports (see Blackbox Ports in Design space exploration for details). In such cases you can add a new substitution to the Program block — for example, named iteration. It will create an input port, also named iteration, on the Program block. Connect the driver’s index port to this substitution port, and use the @{iteration} substitution in the script in the same way as described above for the @{timestamp} substitution.

You can even avoid using an additional Program block, if you are fine with naming the files by index only:

  • Set a persistent sandbox for the Text block: specify the sandbox directory and disable its automatic cleanup (see Sandbox).
  • Set the Text block’s output file origin to sandbox and enable the “path from port” setting. Note that there is generally no need to disable the output port for this file.
  • Connect the driver’s index port to the output_path port which now appears among the Text block inputs.

With this configuration, the Text block will both output the file to the output port and save the file to its sandbox under the name received to the output_path port. This name is the iteration index received from the cycle driver block. Note that you will have to clear the sandbox manually between workflow runs to avoid confusion, because all files are saved to the same location.

Options

  • Common options
  • Basic options
    • Decimal separator — the character used as the decimal separator (added in 6.12).
    • Line endings — line endings to use in output files (added in 6.14).
    • Text encoding — text encoding for the template, input and output files (added in 6.10).
Decimal separator

The character used as the decimal separator.

Value:Point, Comma
Default:Point

New in version 6.12.

This option sets the character which is used as the decimal separator when writing values to a file, and is also recognized as the decimal separator when reading values or using quick selection. If your template file uses commas as decimal separators, change this option to Comma before configuring the block since it affects recognition of numeric values and fields in a line. For example, by default a comma may be interpreted as a field separator — as a result, a line with multiple numbers separated by whitespaces, like 1,001 2,201 3,311, may be recognized incorrectly.

Error handling behavior

The action to perform if the block encounters an error.

Value:stop workflow, output defaults and signal, output signal only
Default:stop workflow

Errors in the Text block can occur when it is unable to generate or parse a file. Often a file parse error in Text indicates that there was an error in the block that sent the file to Text — usually in this case the received file is empty, so the block cannot get any values for its variables.

When this option is set to stop workflow, the block simply reports an error and the workflow interrupts.

If set to output defaults and signal, the block suppresses the error. Output ports in this case send values assigned to them (the defaults), and the done port outputs a False value (the signal). Note that port values are not the same as the test values of variables: port values are set on the Ports tab in the block configuration dialog.

The block automatically assigns values to output ports depending on their type (the type of a corresponding variable). Default output port values are:

  • NaN for RealScalar ports,
  • -1 for IntScalar ports,
  • an empty string "" for StringScalar ports,
  • False for BoolScalar ports,
  • zero-size vectors and matrices for vector and matrix ports,
  • an empty list [] for List ports, and
  • an empty dict {} for Dict ports.

The output signal only behavior means to output only the False value to done; nothing is output to other ports.

Line endings

The line endings to use in output files.

Value:Auto, Windows, Linux
Default:Auto

New in version 6.14.

Specifies which line endings to use in files output by the block: Windows style (CR/LF) or Linux style (LF). Auto (default) selects line endings automatically depending on the OS where the workflow runs.

Text encoding

The encoding for the template, input and output files.

Value:name of the encoding
Default:UTF-8

New in version 6.10.

By default, the block reads template and input files as UTF-8 and encodes output in UTF-8, too. If your files use another encoding, you will have to specify it with this option in order to parse and generate files correctly. Selected encoding always applies to all files processed by the block.