FFREAD is a set of FORTRAN-77 subroutines that allow input of variables to a program in a format-free way, much like the NAMELIST statement of old. Unlike the latter, it is portable across a range of computers and has some additional features, like the capability of reading input from files and, on demand, call- ing a user action routine.
To use FFREAD, the user first identifies a variable or array he wishes to set up by a key. These variables and arrays should be in COMMON; the use of local variables can lead to problems with optimizing compilers. After calling an initialization subroutine, he then defines each key he wants to use to the system, giving its location, type (real, integer, or logical), and length (for arrays). When he has defined all keys, he can at any time during his program call the main subroutine of FFREAD, which will read in the data cards and modify the variables in memory accordingly.
Data cards are one of four types:
An item of information consists of three parts, two of which are optional, and it must be wholly contained on one card:
If more than one part is present, they must be in the above order and adjacent, i.e. with no blanks between them.
The value is then stored, starting at the indicated position in the array and for the indicated number of times given by the repeat count.
If anything on a data card doesn't fit the above description, it is considered to be an in-line comment and is skipped.
For all numerical values, the space used per value is one FORTRAN word. For a hollerith value, the space consumed depends on the number of characters in the string and the number of characters which can be stored in one word on the particular computer. However, one word is the minimum and any remaining space in the last (or only) word is blank-filled. As the space required by hollerith values cannot be predicted before the end of the string is reached (which might be on a continuation card), a repeat count is not allowed for such values.
The value actually stored depends on the data type for the key given by the user when he defined it:
If any error occurs during scanning of an item, no action is performed for this card (even if correct items were found before) and the scan is terminated. Continuation cards are however interpreted for this key; the current position may not be what the user expected.
The following are valid items; their interpretation is given in parantheses.
1 (store one copy of an integer or floating value '1' at the next location) 1*1 (equivalent to the above) 1=1*1 (equivalent to the above except force storage at first element of array) 'abcd' (store the hollerith string 'abcd') 1.2 (1.2) -.1 (-0.1) 1E0 1e0 (1.) 13e-4 (1.3E-5) -1.05E-7 (-1.05E-7)
The following are all strange, but valid representations of the number 0:
- . e E -. .e .E -e -E e- E- -.e -.E .e- .E- -.e- -.E- .E3 -.E-10
The following are not valid; the reason is given in parantheses.
-1*1 (repeat count not positive) -17=5 (location indicator not positive) 3*'abcd' (repeat count not allowed on hollerith item)
Note: If you write '- 1.3 E -3', you won't get the number -1.3E3, but the four numbers 0., 1.3, 0., and -3.
By default, keys have a significant length of four characters. This can be changed (see the description of FFSET below) at initialization. If the first non-blank text on a data card compares sucessfully to a user or system key when truncated to the significant length, the key is recognized and the rest of the text is considered to be comment.
Apart from the single letter 'C' which marks a comment card and could be considered to be a system key, there are eight system keys. They are listed below with their arguments (if any) and their actions.
User keys are truncated to the number of significant characters; abbreviations are not allowed. Before comparison with the list of defined keys, a potential key is converted to uppercase. If it is recognized, it is printed on the lis- ting in upper case.
Note: Although you can define a key to be the same as a system key, this key will not be recognized, as the list of system keys is checked first.
If a valid key (user or system) is preceded with the character '*', this indicates the user wants an action routine to be called for this key. This is done after all values for this key (including those on any continuation cards) have been stored and it is supplied (as a hollerith value) the key which triggered the call. The action routine has the name FFUSER; a dummy routine is supplied with the library.
This subroutine initializes the FFREAD package.
If any keys had been previously specified, they are erased with all associated information. The values for the input and output logical units are reset to their default values, which direct them to the terminal or command file/batch log. The significant key size is reset to its default value of 4.
The integer argument NW specifies the number of words the user has allocated to the COMMON /CFREAD/, in which FFREAD keeps all its information. If NW = 0, the default size is large enough to hold 50 keys of the default length (on all machines). If a larger number of keys is required, the user must do the following:
COMMON /CFREAD/ SPACE(1000)
in his programme.
CALL FFINIT (1000)
The calculation of the required size for a given number of keys is as follows:
This will set some optional values which are identified by the character argu- ment CHOPT to the integer value given by IVALUE, if that is valid. Options are:
CALL FFKEY (KEY, ADRESS, LENGTH, CHTYPE)
This subroutine actually defines a key to FFREAD. Its arguments have the following meaning:
If one of the following conditions is met,the key is not defined and an error message is issued:
This subroutine actually reads in the data cards and modifies the memory locations associated with the keys given.
This routine is called whenever a key on input is preceded by '*', after all memory locations set up by the associated data card(s) have been written.
Its integer argument KEY is dimensioned to as many words as necessary to hold the key which caused the call to be stored in hollerith format to its significant length (blank padded, if necessary).
This subroutine returns some internal parameters of FFREAD as selected by the character variable CHOPT. Valid values and their meaning are:
The requested parameter is retuned in the integer variable IVALUE.
Here is an example of the use of FFREAD in the real world. First, a slightly reduced version of the GEANT routine GFFGO, which sets up the standard GEANT keys and then reads in the data cards. Note the usage of key types and array lengths and, as a convention, the use of the keyword 'MIXED'.
Example of using FFREAD
SUBROUTINE GFFGO C COMMON/GCCUTS/CUTGAM,CUTELE,CUTNEU,CUTHAD,CUTMUO,BCUTE,BCUTM + ,DCUTE ,DCUTM ,PPCUTM,TOFMAX,GCUTS(5) C COMMON/GCFLAG/IDEBUG,IDEMIN,IDEMAX,ITEST,IDRUN,IDEVT,IEORUN + ,IEOTRI,IEVENT,ISWIT(10),IFINIT(20),NEVENT,NRNDM(2) C COMMON/GCKINE/IKINE,PKINE(10),ITRA,ISTAK,IVERT,IPART,ITRTYP + ,NAPART(5),AMASS,CHARGE,TLIFE,VERT(3),PVERT(4),IPAOLD C COMMON/GCLIST/NHSTA,NGET ,NSAVE,NSETS,NPRIN,NGEOM,NVIEW,NPLOT + ,NSTAT,LHSTA(20),LGET (20),LSAVE(20),LSETS(20),LPRIN(20) C C Define standard keys C CALL FFKEY ('CUTS',CUTGAM,16,'REAL') CALL FFKEY ('DEBU',IDEMIN, 3,'INTEGER') CALL FFKEY ('GET ',LGET ,20,'MIXED') CALL FFKEY ('HSTA',LHSTA ,20,'MIXED') CALL FFKEY ('KINE',IKINE ,11,'MIXED') CALL FFKEY ('PRIN',LPRIN ,20,'MIXED') CALL FFKEY ('RNDM',NRNDM , 2,'INTEGER') CALL FFKEY ('RUN ',IDRUN , 2,'INTEGER') CALL FFKEY ('RUNG',IDRUN , 2,'INTEGER') CALL FFKEY ('SAVE',LSAVE ,20,'MIXED') CALL FFKEY ('SETS',LSETS ,20,'MIXED') CALL FFKEY ('SWIT',ISWIT ,10,'INTEGER') CALL FFKEY ('TRIG',NEVENT, 1,'INTEGER') C C Now read data cards C CALL FFGO C 999 END
And here is an example input, taken from the GEANT test job GEXAM1:
Input file to previous example
LIST TRIGGERS 10 DEBUG 1 1 1 SWIT 1 CUTS 0.0001 0.001 KINE 2=10. 1. SETS 'CDET' 'HBAR' 'MUEC' PRINT 'MATE' 'VOLU' 'TMED' END
CALL FFREAD (NKEY, KEY, LOCVAR, LENVAR)
This is the old-fashioned form of using FFREAD and is only supplied for backward compatibility.
If NKEY is set to 0, it is used to modify the values for the default input/output LUNs.
If NKEY is negative, it will return them.
If NKEY is positive, it specifies the number of keys in KEY. The keys will be set up (destroying any previously defined keys) and FFGO called to do the work.
The arguments and their meaning:
Internally, FFREAD uses the subroutines FFCARD, FFFIND and FFUPCA.
The following external routines are used by FFREAD. They all come out of the CERN library KERNLIB:
FFREAD contains two patches: FFCDES defines the sequences for COMMON blocks and PARAMETERs, FFREAD contains the actual code. A PATCHY flag is used to define each machine. Currently, the following are available:
Cradle to extract FFREAD code
+USE, FFCDES, FFREAD, <machine flag>, T=EXE. +PAM,T=CARDS. +QUIT.
The PAM also contains a short test program with associated input. This programme and its data are extracted as follows (assuming you have given a file name to stream 23):
Extracting the test program
+ASM, 23. +USE, FFTEST, T=EXE. +PAM,T=CARDS. +QUIT.
After having compiled and linked the programme (it contains a short user action routine), assign the data file produced by the above PATCHY run to a suitable unit number. Then run the program and give the data cards:
Data cards for test program
LIST KEYS READ <logical unit number of data file>
and observe the result. For the IBM and the CDC, example jobs to perform the above are included in the patch TEST, the required version is selected as before.