CCP4 web logo CCP4i: Graphical User Interface
Documentation for Programmers
The Command Template File

next button previous button top button

Introduction

Using CreateComScript in a Script File

Introduction to the Template File Format

Parameter Substitution and the Write Flag

Splitting Commands into Components - Continuation Lines
Sub-components and Double-Continuation
The | character - an inline ELSE

Undefined Parameters and Why Split Commands into Components

Control Structures
IF-ELSE-ENDIF
LOOP-ENDLOOP
CASE-CASEMATCH-ENDCASE

LABELLINE - Writing LABIN and LABOUT Commands

Hints for Programmers

Appendix: Some Examples of Write Flags

Introduction

First read the Overview of the files required for a task interface.

It is common in scripts to run CCP4 programs to redirect the command input from the script file using << but in CCP4i the commands are written to a separate file (chiefly to enable VMS support). Command templates are used to generate the command files for CCP4 (or other) programs.

The procedure CreateComScript will substitute parameters into the template to create a command file. There is usually one command template file per program, though if program function is very modular it may be reasonable to have seperate templates for different functions (e.g. see the amore_*.com templates in $CCP4I_top/templates). Note that the templates are all kept in the directory $CCP4I_top/templates. Before writing a new task interface, check here for existing templates for program(s) you may want to use - particularly because the rest of the task interface must use the same parameter names that are used in the template.

Using CreateComScript in a Script File

The CreateComScript procedure is usually called from a run script - a few example lines of a run script might be:

set TITLE "This should be a really good fiddle"
set FACTOR_1 0.1
set FACTOR_2 400
set FACTOR_3 27.1
set EXTRA_FIDDLE 1

CreateComScript $CCP4I_top/templates/fiddleprog.com fp_script

The first argument to CreateComScript is the name of the fiddleprog template file and the second argument returns the name of a temporary file which is created and will contain the command lines:

title 'This should be a really good fiddle'
fiddlefactors 0.1 400 -
27.1

Note that the values of the parameters set in the run file are not passed to the CreateComScript procedure - a bit of Tcl black magic enables it to see the variables at the higher, calling, level in the stack.

Introduction to the Template File Format

The commands for many CCP4 programs are very complex with many optional keywords and subkeywords and variable numbers of parameters. The format of the template file is designed so that only the required keywords, subkeywords and parameters are written to the command file - in most cases nothing will be written so:

  • the program will be able to choose its own defaults
  • if the user chooses to look at the command file it will be as simple as possible
  • In order to implement this, each command line must be broken down into its various components and with the option of an independent decision whether or not to write each component to the command file.

    Parameter Substitution and the Write Flag

    To control whether a command line is written or not, the first parameter on a standard line in the template file is a logical variable. For example to create a command line:

    resolution 10.0 3.0
    

    the line in the template file could be:

    $SET_RESOLUTION_LIMITS resolution $RESOLUTION_MIN $RESOLUTION_MAX
    

    Any word on the template line beginning with $ will be treated as a variable and the value substituted. Thus the line above requires the parameters SET_RESOLUTION_LIMITS, RESOLUTION_MIN and RESOLUTION_MAX to be set. The values of these variables will be substituted into the template line. All other words will be retained as they are.

    The first word in the template line is treated as a write flag. It must be a logical with value 1 (true) or 0 (false). A line will only be written to the command file if the write flag is true. The write flag is not written to the command file.

    If a line should always be written, the write flag can be given a fixed value of 1:

    1 resolution $RESOLUTION_MIN $RESOLUTION_MAX
    

    If the decision whether to write the line is more complex, a more complex function can be used, providing it has a logical (i.e. 0 or 1) result, for example:

    { $SET_RESOLUTION_LIMITS && $RESOLUTION_MAX > 0.0 } resolution $RESOLUTION_MIN $RESOLUTION_MAX
    

    For the command line to be written, $SET_RESOLUTION_LIMITS must be true and $RESOLUTION_MAX must be greater than zero. Note that the write flag function is enclosed in curly braces {} and is in the Tcl language. Examples of some functions which might be useful, are given below.

    Splitting Commands into Components - Continuation Lines

    The definition of one command may be spread over several lines in the template file. Each line of the template file is processed independently so each of the components of the command is treated independently. Thus for an example command line:

    fiddlefactors <factor_1> <factor_2> [ <factor_3> ]
    

    where the third parameter <factor_3> is optional, the template might be:

    1 fiddlefactors $FACTOR_1 $FACTOR_2
    - $EXTRA_FIDDLE $FACTOR_3
    

    The first line will always be written, as it has a write flag of 1.

    The second line encodes a component of the command which will only be written if the parameter $EXTRA_FIDDLE is 1 (true). The - character at the beginning of the second line indicates that it is a continuation of the preceding line. In CCP4 command files the continuation character goes on the end of the preceding line. The reason for the different convention here will become apparent later. Of course, when the template file is processed, the resulting command file has the continuation character at the end of the preceding line.

    An alternative form for the template is:

    $SET_FIDDLEFACTORS fiddlefactors $FACTOR_1 $FACTOR_2
    - $EXTRA_FIDDLE $FACTOR_3
    

    Here writing the first line is dependent on the value of the parameter $SET_FIDDLEFACTORS. If this is 1 (true), the command line is written as above, but if it is 0 (false), nothing is written. The second, continuation, line is NOT written if the preceding line is not written.

    Analysing command lines can result in several components which can be written as continuation lines, e.g. the refi command in the refmac interface:

    1 refi
    - 1 type $REFINE_TYPE
    - $IFRESI resi $RESIDUAL
    - 1 meth $MINIMISATION
    

    Note that if the $IFRESI parameter were 0, the resi keyword would not be written out but the subsequent meth keyword would still be written.

    Sub-components and Double-Continuation

    There are a few complex commands which can be interpreted as having sub-components of the components and these are represented as starting with -- on a line. The line will only be written if the preceding command line and component line are written. For example in the fft template file:

    1 exclude
    - $EXCLUDE_BYSIGMA sig1 $EXCLUDE_BYSIGMA_1
    -- [IfSet $EXCLUDE_BYSIGMA_2] sig2 $EXCLUDE_BYSIGMA_2
    - $EXCLUDE_MINIMUM f1min $EXCLUDE_MINIMUM_1
    -- [IfSet $EXCLUDE_MINIMUM_2] f2min $EXCLUDE_MINIMUM_2
    

    The sub-component keywords sig2 and f2min will only be written out if the preceding components are written and if their own write flag function is true (the IfSet procedure is described more fully in the library of CCP4i commands - essentially it checks that a parameter is not an empty string).

    Where there is a 'double-continuation' in the template file, only a single continuation will be written to the end of the preceding line in the command file.

    The continuation character in the template file is put at the beginning of lines rather than the end so the 'double-continuation character' of sub-components can be used unambiguously.

    The | character - an inline ELSE

    If there is a | character in the template line, the interpretation of the write flag is changed. If the write flag is 1 (true), the words preceding the | character will be written to the command file. If the write flag is 0 (false), the words after the | character will be written to the command file. In this case, there is NO option not to write to the command file.

    An example from the scala template:

    $TAILS_FIX_V FIX V | UNFIX V
    

    Dependent on the value of $TAILS_FIX_V, either "FIX V" or "UNFIX V" will be written to the command file.

    This is equivalent to (see section on IF-ELSE-ENDIF):

    IF $TAILS_FIX_V
     1 FIX V
    ELSE
     1 UNFIX V
    ENDIF
    

    Undefined Parameters and Why Split Commands into Components

    Many template files contain a large number of variables but it is not necessary to set values for all of them in order to use the template file. The template file is processed one line at a time and if ANY parameter in the line is not set, the line will not be written (it will be treated as if the write flag was 0 (false)). A major incentive to split commands into component lines is that if a parameter is not set for one component it will not stop other components being processed and written successfully.

    Note that a parameter can be set to the empty string:

    set RESOLUTION ""
    

    and it will still be considered as defined. This can lead to errors in the command file where parameters are 'missing'. You need to check that parameters are not just an empty string using the IfSet procedure.

    Control Structures

    The command template format supports control structures of the form IF-ELSE-ENDIF, LOOP and CASE. Note that the keywords MUST be uppercase and written on separate lines. It is permissible to nest LOOPs and IFs.

    The control structures can be used within the definitions for a single command or around one or more commands.

    IF-ELSE-ENDIF

    IF-ELSE-ENDIF has the form:

    IF { logical_function }
    ..
    ..
    ELSE
    ..
    ..
    ENDIF
    

    The ELSE component is optional. An example from the refmac template:

    1 refi
     - 1 type $REFINE_TYPE
     - 1 resi $RESIDUAL
     - 1 meth $MINIMISATION
    IF { [StringSame $REFINE_TYPE IDEA RIGID] }
     - $B_REFINEMENT bref over
    ELSE
     - $B_REFINEMENT bref $B_REFINEMENT_MODE
    ENDIF
    

    Here the IF-ELSE-ENDIF is used with the definition of the refi command. The StringSame procedure is being used to test if $REFINE_TYPE is set to IDEA or RIGID and the line written to the command file depends on the result.

    The logical function could be a variable name or any Tcl function.

    LOOP-ENDLOOP

    LOOP-ENDLOOP has the form:

    LOOP loop_variable start_value end_value
    ..
    ..
    ENDLOOP
    

    The loop variable should be a simple name (e.g. "n"); the value of the loop variable can be accessed inside the loop (e.g. as "$n"). The start_value and end_value should be integers, end_value should be greater than start_value. Currently there is no option for increment values other than 1.

    An example from the refmac template to write out scaling factors for a variable number of partials:

    IF { $NPARTIALS > 0 }
    1 scpa
      LOOP N 1 $NPARTIALS
       - 1 $PARTIAL_SCALE($N)
      ENDLOOP
    ENDIF
    

    CASE-CASEMATCH-ENDCASE

    CASE-CASEMATCH-ENDCASE has the form:

    CASE $case_variable
    CASEMATCH value_1
    ..
    CASEMATCH value_2
    ..
    ......
    ..
    CASEMATCH value_n
    ..
    ..
    ENDCASE
    

    The action depends on whether the value of case_variable matches any of the values value_1, value_2, .. value_n.

    An example from the refmac template in generating the weight command. The parameters written to the command file depend on the value of $WEIGHTING_METHOD:

    1 weight
     - { !$EXPERIMENTAL_WEIGHTING } NOEX
    CASE $WEIGHTING_METHOD
    CASEMATCH MATRIX
     - 1 MATRIX $MATRIX_WEIGHT
    CASEMATCH GRADIENT
     - 1 GRADIENT $GRADIENT_WEIGHT
    CASEMATCH SIGMA
     - 1 SIGMA $SIGMA_WEIGHT
    ENDCASE
    

    NOTE that in { !$EXPERIMENTAL_WEIGHTING } the '!' means 'not' and so this statement is true if $EXPERIMENTAL_WEIGHTING is set to zero (i.e. false). See also examples below.

    LABELLINE - Writing LABIN and LABOUT Commands

    The usual form for LABELLINE is:

    LABELLINE label_keyword program_label_list label_index
    

    The label_keyword is usually LABIN, or LABOUT. It could be the continuation character - if it is a continuation from a previous LABELLINE. The program_label_list is a list of program labels. The label_index is optional and, if used, should be a positive integer value.

    For example if the following parameters are set:

    set LABIN "F1 SIGF1 PHI"
    set F1 FP
    set SIGF1 SIGFP
    set PHI PHIC
    

    then the template line:

    LABELLINE labin $LABIN
    

    will result in the command line:

    labin F1 = FP -
    SIGF1 = SIGFP -
    PHI = PHIC
    

    For each of the program labels listed in the variable $LABIN the appropriate assignment has been written to the command file. The program_label_list does not need to be a variable; the line:

    LABELLIST labin "F1 SIGF1 PHI"
    

    with the program labels grouped inside double inverted commas, would also work. Many programs have variable program labels dependent on their mode of use and it is usually advisable to make the program_label_list a variable which is set in the taskname_run procedure.

    Some programs have 'indexed' program labels which usually correspond to derivatives numbered 1 to n. So, for example, for MLPHARE, the usual program labels (with no anomalous data) are: FP SIGFP FPH1 SIGFPH1 .. FPHn SIGFPHn. The template lines for these are:

    LABELLINE labin "FP SIGFP"
    LOOP n 1 $N_DERIVS
     LABELLINE - "FPH SIGFPH" $n
    ENDLOOP
    

    Hints for Programmers

    When writing a task interface, write the command template file first. It will give you a chance to look at the details of the program input.

    Use existing templates wherever possible. Contact the Interface developers if you want to check if a template has been recently created or if you have some argument with an existing template.

    If you are the first person to write a template for a particular program, please do not take short cuts (for example leaving out keywords that you do not want to use or making assumptions of parameters being equivalent where it is not necessarilly so). This just makes for problems in the future.

    Split commands into components.

    If there is an error in the template file, the resultant error messages are not always very helpful so you need to be able to spot erros in the file. Use indentation to make the control structure of the template file more obvious.

    90% of errors in the template file are forgetting to put a write flag in a command line or are typos in variable names.

    It is not necessary that every parameter in the command template maps onto a widget in the task window seen by the user. Some parameters may be irrelevant for a particular task and it is often desirable to present the user with fewer, simplified parameters - these can be expanded to the parameters required by the template file at either of two stages: in the taskname_run procedure or in the task script.

    The easiest way to test a template file is simultaneously with testing the task window. Use the Run&ViewComFile option when running the task so you can see the resultant command file and check it is what you expect for the parameters set in the task window.

    Appendix: Some Examples of Write Flags

    This is intended as a very quick introduction to the snippets of Tcl that you may need to use in defining a write flag. Note that IfSet and StringSame are CCP4i procedures and are documented in the Text Handling Utilities section of the library of CCP4i commands.

    { [IfSet $TITLE] } title $TITLE
    
    write the title command line if the $TITLE string is not empty.
    { [regexp MIN $REFINE_MODE] } ......
    
    write the line if the string in variable $REFINE_MODE includes the string MIN (N.B. it does not have to be an exact match). regexp is a very powerful regular expression procedure, of which the full range of functionality is described very tersely in the Tcl documentation
    {[StringSame $REFINE_MODE MINI MAXI ]} ....
    
    write the line if the string in variable $REFINE_MODE is an exact match to any of the subsequent arguments to the StringSame procedure. Note that the procedure can have two or more arguments.
    {[expr $N - 1] == $HIT_VALUE } ....
    
    the line is written if $N -1 is equal to $HITVALUE. All arithmetic operations in Tcl should be done with the expr procedure (see the Tcl documentation). The Tcl operators such as == are also described in the expr documentation.
    !$FIX unfix
    
    write out "unfix" if NOT $FIX. The exclamation mark is the 'not' operator.
    { $TEST_1 && $TEST_2 } ....
    
    the line is written if both $TEST_1 and $TEST_2 are true
    { $TEST_1 || $TEST_2 } ....
    
    the line is written if $TEST_1 or $TEST_2 is true
    { ($TEST_1 && $TEST_2) || $TEST_3 } ..
    
    the line is written if both $TEST_1 and $TEST_2 are true OR if $TEST_3 is true