All the routines contained in this library are written in ANSI standard FORTRAN 77.
The development of the MTZ files and associated software mark 1 is part of the masterplan of the ESF/EACBM Working Group 2.1 for better Protein Crystallographic software for Europe.
The first argument to all the subroutine calls in MTZLIB is MINDX. This mechanism allows more than one pair of MTZ files to be open for read and write at the same time, without the need for separate subroutines. At present a maximum of 8 files can be opened simultaneously (4 for read and 4 for write), but this could be increased easily.
The subroutines of a set share an area of storage for the header data (e.g. for the cell parameters, label and title information) so that when an input file has been opened the header information is available for writing to an output file, without being explicitly copied by the calling program. This information may be replaced or new information may be added depending on the requirements of the output file or it may be created if no input file was read.
The MTZ reflection file format uses fixed length logical 'records' written in a byte stream with, in general, four bytes for each data item (REAL*4), with a minimum of 3 columns and currently a maximum of 200 columns of data per record, although these limits could easily be increased. Additional information (title, cell dimensions, column labels, symmetry information, resolution range, history information and, if necessary, batch titles and orientation data) is contained in labelled header records. The columns of the reflection data records are identified by alphanumeric labels held as part of the file header information. The user relates the item names used by the program to the required data items, as identified by the labels, by means of assignment statements in the program control data.
Record Formats
The file contains basically two classes of records - header records and reflection data records. A standard reflection data file contains the following items, in the order given, not necessarily all items have to be present:
- VERS
- Version stamp (Character*10, currently MTZ:V1.1)
- TITLE
- File Title - short identification of file (Character*70)
- NCOL
- number of columns, number of reflections in file, number of batches (Integer) if number of batches > 0 this indicates multi-record file
- CELL
- Cell Parameters (Real(6))
- SORT
- Sort order of 1st 5 columns in file (Integer(5))
- SYMINF
- Number of Symmetry operations (Integer)
Number of Primitive operations (Integer)
Lattice Type (Character*1)
Space Group Number (Integer)
Space Group Name (Character*10)
Point Group Name (Character*6)- SYMM
- Symmetry operations in international tables style
- RESO
- Minimum (smallest number) and Max (largest number) resolution stored as 1/d-squared (Real(2))
- VALM
- Value with which Missing Number Flag is represented.
- COL
- Column Label (Character*30)
Column Type (Character*1) for each column
Minimum and Maximum value in each column (Real)
ID of corresponding dataset (Integer)- NDIF
- Number of datasets represented in the file.
- PROJECT
- ID of dataset (Integer)
Project Name (Character*64). Normally one for each structure determination.- DATASET
- ID of dataset (Integer)
Dataset Name (Character*64). May be several for each structure determination, e.g. for different crystals or derivatives.- DCELL
- ID of dataset (Integer)
Cell dimensions (Real) for dataset.- DWAVEL
- ID of dataset (Integer)
Wavelength (Real) for dataset.- BATCH
- Batch Serial Number for each batch present (Integer). This line is only present in `multi-record' files.
NB: Column Types are an extra check that the user input assignment for a requested program label is of the correct type. For a list of all column types see section COLUMN TYPES.
Normally the Miller indices will be held in the first three columns though, within the definition of the format, there is no restriction on the use of the columns of the reflection data records. However, the subroutines which output the MTZ header information in a formatted way (e.g. Subroutine LHPRT) presume that the first 3 columns of a standard MTZ file are the Miller Indices, and the first 5 columns of a multi-record MTZ file are H,K,L,M/ISYM and Batch number.
A dataset is identified by a "project name", which specifies a particular structure determination (and is equivalent to the mmCIF data item _entry.id), and a "dataset name", which specifies the particular crystal or derivative (and is equivalent to the mmCIF data item _diffrn.id). Normally, there will be several datasets with the same "project name" and different "dataset names".
The total number of datasets represented in a file is given by the keyword NDIF in the main file header (see above), and a list of the project and dataset names associated with each dataset is given by the PROJECT and DATASET keywords also in the main file header. Each dataset is identified internally by an integer "dataset ID". For a merged single-record-per-reflection MTZ file, each column has as one of its attributes (included in the COL keyword) a "dataset ID", which acts as a pointer to the main list of datasets. For unmerged multi-record MTZ files, a column may be associated with several datasets (corresponding to different batches) and the "dataset ID" is not used. Instead, each batch header contains a "dataset ID", which points to the dataset associated with that batch.
The main file header also contains properties of each dataset. Each dataset can have its own cell dimensions identified by the keyword DCELL, e.g. native and derivative crystals may well have significantly different cells. The information held in DCELL records is distinct from the general cell held in the CELL record, and programs may make use of either. A wavelength can also be attributed to each dataset via the keyword DWAVEL. Other dataset information may be added in the future. The records DCELL and DWAVEL are optional; the header reading routines assume that if they are present, then they will occur immediately after the relevant PROJECT and DATASET keywords.
In mtzlib, the COMMON blocks /HARINT/, /HARREA/ and /HARCHA/ include 8 variables or arrays for each file or file pair opened. NSETW is the number of datasets, read from the file header keyword NDIF. ENTRY_ID, DIFFRN_ID and SET_ID are the "project name", "dataset name" and "dataset ID" for each dataset, read from the PROJECT and DATASET file keywords. CSET_ID is the dataset pointer for each column read from the COLU file keyword. (The corresponding dataset pointer for batches is held as the variable LBSETID in the COMMON block for that batch.) DCELL and DWAVEL hold the dataset cell and wavelength information. Finally, IDEFSET is a default dataset ID for each file, which is used for associating a dataset with a new column when there is no other information available.
This subroutine must be called before any other mtzlib subroutine. Failure to do so may result in unpredictable behaviour.
Arguments:
- =0
- No MTZ info printed at all
- =1
- Brief header info printed (default)
- =2
- as above plus history info
- =3
- Full header dump; symmetry
- any other value; nothing happens
- =0
- OK
- =-1
- no such file
- all other errors cause stop
External Functions: INTEGER LENSTR
External Subroutines: BLANK,GTPINT,GTPREA,LERROR,PARSER,PUTLIN,QOPEN,
QSEEK,QMODE,QREAD,SYMFR3
Function:
Subroutine LROPEN checks that nothing is already open for required index
If it is continue, but print warning
If already open for read, then probably forgot to call LRCLOS from a previous
file
If already open for write, then programmer hasn't read manual - ie has called
LWOPEN on this index before LROPEN
If already open for read and write then the program stops
Then opens the file and record the stream
CALL QOPEN(IUNIN,FILNAM,'READONLY')
CALL QMODE(IUNIN,2,NITEM)
Then Zero the header arrays etc.
Read the 1st record of the file, check it's an MTZ file, and go to the start
of the header records - first record of file contains the offset in the file
of the start of the header records. Put this offset into a call to QSEEK
( CALL QSEEK(RLUN(INDEX),1,HDRST(INDEX),1)) to position file at start of
headers.
Then reads and parses the header, and load COMMON blocks
Passing header line to MRC parser:
CALL PARSER(KEY,LINE,IBEG,IEND,ITYP,FVALUE,CVALUE,
+ IDEC,NTOK,LEND,.FALSE.)
and loops over possible keywords
VERS - version of routines which wrote the file
could test versions here in the future
TITL - read file title
NCOL - no. of cols and refls in file and batches in file
if no. of batches=0 then this is a standard file
CELL - read in the Cell parameters
SORT - read in sort order
SYMI - various symmetry stuff
SYMM - read in the symmetry cards and convert to matrices
If present then calls SYMFR3
RESO - resolution limits for the file (1/d-squared)
COLU - column labels, types and ranges
BATC - batch serial numbers - hopefully only if nbatch >0
END of header card
If the program is going to allow user input column assignments, then you MUST call subroutine LKYIN to parse these input label assignments, before LRASSN is called, as LKYIN sets up arrays which are then used by LRASSN.
Note that user input labels and file labels are case sensitive - the input label must match the file label exactly.
Also note that having an unassigned program label is a fatal error, but this subroutine uses LERROR to report this as a warning, so that all the program label assignments can be checked before stopping.
Arguments:
External Functions: INTEGER LENSTR
External Subroutines: BLANK,LERROR,PUTLIN
Function:
This subroutine references the internal COMMON Blocks /MTZLBC/
and /MTZLAB/ which are set up by LKYIN.
Rpoint is the same as lookup, but held in the MTZWRK COMMON work with this
and copy to LOOKUP at the end, so set to 0.
Also store the number of program labels in MTZWRK, and the program labels
in MTZWRC
First loop over user input labels (if any) and assign them to file labels.
Now loop over program labels for those not yet assigned
Copy RPOINT to LOOKUP
If we had some errors then return or stop now
Print out program labels, column labels and lookup
Check the column types if any given
Arguments:
External Subroutines: LERROR
Arguments:
External Subroutines: LERROR
Arguments:
Arguments:
External Functions : INTEGER LENSTR
External Subroutines: LERROR
Arguments:
External Functions: INTEGER LENSTR
External Subroutines: LERROR
Arguments:
Arguments:
Arguments:
NB: Since the calculation for the resolution is set up when the file is opened (LROPEN) any changes to the unit cell should be made (with LWCELL, where the setup is re-done) BEFORE reflections are read if it is wished that the new cell is used in the resolution calculation.
There is a kluge to handle the absence flags defined by the Groningen BIOMOL system: If the MINDX is larger then 1000, then it is assumed that the subroutine is called by a BIOMOL program or another program that is able to interpret the BIOMOL absence flags (e.g. a value of -1.0E+10 indicates absent data). If MINDX is in the normal range of 1 to 3, then the subroutine will convert values of -1.0E+10 to zero to allow normal processing by the CCP4 programs.
Arguments:
MINDX (I) INTEGER indicates which MTZ file - one index points to both input and output files
External Subroutines: LERROR,QREAD
Function:
Check that there is a file open
Everything OK, update the number of records read
If not end of file read a record with
CALL QREAD(RLUN(INDEX),BDATA,NCOLS(INDEX),IERR)
and rearrange it
Check first 3 columns are of type H and if so calculate the resolution.
Transfer data to ADATA in LOOKUP order, if LOOKUP(?) is 0 then presume it was
an optional column and set ADATA(?) to 0.0
LRREFL calls the following which are external to MTZLIB:
External Subroutines: LERROR,QREAD
Function:
Check that there is a file open
Everything OK, update the number of records read
Check first 3 columns are of type H and if so calculate the resolution
If not end of file read a record with
CALL QREAD(RLUN(INDEX),ADATA,NCOLS(INDEX),IERR)
NB: End of file is no. of refs read > total no.of refs (from header)
Arguments:
External Subroutines: LERROR
Arguments:
External Subroutines: LERROR
Arguments:
External Subroutines: LERROR
Arguments:
External Subroutines : LERROR
Arguments:
External Subroutines: LERROR
External Functions : INTEGER LENSTR
Arguments:
External Subroutines: LERROR, QSEEK
Arguments:
External Subroutines: LERROR, QSEEK
Arguments:
External Subroutines: LERROR,QCLOSE
Function:
Close the file with CALL QCLOSE(RLUN(INDEX))
Mark this index as unoccupied for read
NB: Every time LROPEN is called it zeros all the header info for that MINDX, and then loads up the header storage with data from the file. Therefore if LWOPEN is called first, and if (e.g.) a title of a history line is added with LWTITL or LWHIST, this info will be lost if it is followed by a call to LROPEN (on the same MINDX). While this is unlikely to occur in most programs, care should be taken with programs which open a large number of input files in sequence and write one output file (and therefore have a sequence of calls like - LROPEN, LWOPEN, LRREFL, LWREFL, LRCLOS, LROPEN, LRREFL, LWREFL, LRCLOS ... LWCLOS) not to update items in the header until the last input file has been opened. Alternatively, if you want to retain the data from the first input header in the output header, you should open the first input file on index 1, and the output file on 1 also, and all subsequent input files on index 2.
Arguments:
External Subroutines: LERROR,QOPEN,QMODE,QWRITE
Function:
Explicitly pull in the initialise block data here (EXTERNAL MTZINI)
Check for other open files on this index - first read files
If no read file open, then LROPEN has not been called -
initialise all the MTZ header common blocks here - some of these not necc.
if no read file, but do it for consistency
Then the write files - pretty seious if already open, so stop.
Everything OK, open the file and zero a few variables
CALL QOPEN(IUNIN,FILNAM,'NEW')
CALL QMODE(IUNIN,2,NITEM)
Write a dummy first record to the file (the one which will contain
the header offset and the machine stamp and mtz stamp)
Note that this subroutine changes the values in the header common block, so all information about the input file's labels and types should already have been extracted.
If the program is going to allow user output labels, then the subroutine LKYOUT *MUST* be called to parse the output label assignments from the input control data, before LWASSN is called.
Also note that the case of the user and/or program output labels is preserved.
Arguments:
- =0
- replace all existing labels and types
- =1
- append to the existing labels and types
LWASSN calls the following which are external to MTZLIB:
External Functions : INTEGER LENSTR
External Subroutines: BLANK,LABPRT,LERROR,PUTLIN
Function:
Work out starting column
Work out total number of columns to be written to output file. Loop over the
new labels, and check the user assignments - if an output program label is the
same as an input one, and there is no user output assignment then check the
input assignments and keep the original user label for that column.
Print out the output program labels and output column label, and an output
lookup. Then check the column types are valid.
Arguments:
LWCELL calls the following which are external to MTZLIB:
External Subroutines: LERROR
Arguments:
- =0
- replace all existing labels and types
- =1
- append to the existing labels and types
Arguments:
From FREERFLAG, 21/ 6/94 18:38:48 with fraction 0.050
^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
CCPVRS arg EXTRA
This is just a simplified interface to LWHIST. The history line will
be truncated to 80 characters.
Arguments:
Function:
Check not too many lines input - if so take first NHISTL lines
Copy existing history lines to scratch array
Copy input lines to the history array in the header common blocks
Fill up any space left with lines already in history header
Arguments:
External Subroutines: LERROR
Arguments:
External Subroutines: LERROR,PUTLIN
Function:
First deal with symmetry operations - if NSYMX .gt. 0 ie there is already
symmetry info there, print warning with
CALL SYMTR3(NSYM(INDEX),RSYM(1,1,1,INDEX),SYMCHS,IPRINT) and
CALL SYMTR3(NSYMX,RSYMX(1,1,1),SYMCHS,IPRINT)
but copy the new ones into the header blocks anyway. Then deal with the other
arguments.
Arguments:
- =0
- replace old title with new one
- =1
- append new one to old, with one space
LWTITL calls the following which are external to MTZLIB:
External Functions : INTEGER LENSTR
External Subroutines: LERROR
Arguments:
External Subroutines: LERROR,QWRITE
External Functions : REAL LSTLSQ
Function:
Check that there is a file open. If everything OK, increment no. of reflection
records written.
Update the column ranges
Update the resolution limits
Write the reflection record to file with
CALL QWRITE(WLUN(INDEX),ADATA,NCOLW(INDEX))
This is one of the most important subroutines in the library. If you do not call this subroutine your output file will be corrupted; it will have no header information and the file will be unreadable.
Arguments:
- =0
- No MTZ info printed at all
- =1
- Brief header info printed (normal)
- =2
- Brief header plus history
- =3
- Full header dump
LWCLOS calls the following which are external to MTZLIB:
External Functions : INTEGER LENSTR
External Subroutines: BLANK,LERROR,PUTLIN,QCLOSE,QSEEK,QWRITE,QMODE,QTYPE
Function:
Calculate position of start of header records, and move to it -
=no.refls*no.cols+size of 1st record + 1
Loop over the header lines and write them out (see LROPEN for a list of the
possible header lines) If it is a multi-record file, and if we found that when
we were writing the batches out to the file, the batches were out of order
(ie serial numbers not in ascending order), then do an indexed sort of the
array containing the batch serial numbers, so that they, and the batch
information (title and orientation data), can be output serially. (NB the
batch header info is never read at the same time as the corresponding
reflection records, as it was in the LCF files - all batch headers are read as
soon as the file is opened)
Then write the history lines and then the batch info if a multi-record file.
Write MTZENDOFHEADERS record (which is also end of file).
Go back to the beginning and fill up the first record with an identification
stamp and the offset of the headers. (ie the offset of the headers is the
second long-word in the file)
If IPRINT is gt 0 then call LHPRT to output header information.
Close the file - CALL QCLOSE(WLUN(INDEX)) and mark the index available for
write by setting WLUN(INDEX) to 0.
This will also optionally print out all this information in a pretty format.
Note that the maximum numbers of batches currently allowed is 1000.
Arguments:
- =0
- no print
- =1
- print batch title only
- =2
- print orientation block as well
- >30
- print orientation block as well BUT to IPRINT unit number
LRBAT calls the following which are external to MTZLIB:
External Subroutines: LERROR
If this routine is called at all then it must be called for every batch which is to be output - these batch serial numbers are stored and used in LWCLOS.
If it is called with BATNO = 0 this is a flag to say that the output MTZ file will be a standard file, and not a multi-record one, i.e. no batches. After this call no batch information is available to the calling program, so don't call it too soon !
Note that the maximum numbers of batches currently allowed is 1000.
Arguments:
External Subroutines: LERROR
Function:
This subroutine will check whether the number of the current batch which is being written is (1) already present in the output file (ie LWBAT has already been called with this batch number) and (2) less than the serial number of the last batch written (ie the serial numbers are out of order). If 2 batches are the same the program will stop, and if the serial numbers are out of order a flag is set so that they will be sorted by LWCLOS before being written out to the file.
Arguments:
- =0
- no print
- =1
- print title
- =2
- print title and orientation block
Arguments:
Arguments:
Arguments:
- =0
- no print
- =1
- print batch title only
- =2
- also print orientation block
- >30
- also print orientation block BUT to IPRINT unit number
LBPRT is called by LRBAT, and it calls LBPRTH to do the actual printing.
Arguments :
Arguments :
Arguments :
Arguments :
Arguments :
Arguments :
Arguments :
Arguments :
Arguments :
Arguments :
Arguments :
Arguments :
Arguments :
LKYIN also checks that each assignment set actually contains an input program label on one side of the = sign. This comparison is not case sensitive.
If there is no ambiguity, the order in which program and file labels are given may be swapped.
Arguments:
External Subroutines: CCPUPC, PUTLIN
External Functions : INTEGER LENSTR
This subroutine returns the user input labels to the calling program (LKYIN does not) and the array KPOINT which indicates which of the program labels were assigned user input file labels
Note that although this Subroutine looks similar to LKYIN it cannot be called in its place, it simply adds extra functionality. There is no MINDX argument to this call - it is not tied to any particular file(s) and the header common blocks are not affected by this subroutine.
See the notes above (LKYIN) about the order of the assignment statements.
Arguments:
External Subroutines: CCPUPC, PUTLIN
External Functions : INTEGER LENSTR
LKYOUT also checks that each assignment set actually contains an output program label on one side of the = sign. This comparison is not case sensitive.
If there is no ambiguity, the order in which program and file labels are given may be swapped.
Note that the case of the user output labels is preserved.
Arguments:
External Subroutines: CCPUPC, PUTLIN
External Functions : INTEGER LENSTR
Read column assignments and make them, for input MTZ file open for read on index MINDX
It expects to read from stream 5 a line of the form
LABIN program_label=file_label program_label=file_label . . .
This routine is useful for simple jiffy programs that don't want full
keyworded input
See the LKYIN section above for the notes on case, and order of input assignments.
Arguments:
External Subroutines: PARSER, LERROR
Arguments:
- =1
- Brief header info printed (default)
- =2
- As above plus history info
- =3
- Full header dump, symmetry, alles!
- =4
- As 1 plus full symmetry
- any other value, nothing happens
LHPRT calls the following which are external to MTZLIB:
External Functions : INTEGER LENSTR
External Subroutines: BLANK,LERROR,PUTLIN,SYMTR3
Arguments:
Arguments:
ILUN (I) INTEGER LUN on which the file is open
BATCH (O) INTEGER serial number of this batch
RBATCH (O) REAL(*) array into which integer and real batch
info is decoded by subroutine
this should be equivalenced onto the
appropriate COMMON block in the calling
program. The first item is nwords,ie how
many items in the array, if nword is 0
then only the title is present
CBATCH (O) CHARACTER(*)*1 as RBATCH, but for character items - no
nwords however; title is 1st 70 chars of
CBATCH.
RBATHD is call by LROPEN.
RBATHD calls the following which are external to MTZLIB:
External Subroutines: LERROR,QMODE,QREAD
Arguments:
ILUN (I) INTEGER LUN on which the file is open
BATCH (I) INTEGER serial number of this batch
RBATCH (I) REAL(*) array from which integer and real batch
info is encoded by subroutine
this should be equivalenced onto the
appropriate COMMON block in the calling
program. The first item is nwords,ie how
many items in the array, if nword is 0
then only the title is written
CBATCH (I) CHARACTER(*)*1 as RBATCH, but for character items - no
nwords however; title is 1st 70 chars of
CBATCH.
WBATHD is called by LWCLOS.
WBATHD calls the following which are external to MTZLIB:
External Subroutines: QMODE,QWRITE
Arguments:
ILUN (I) INTEGER LUN on which the file is open,
for each MTZ file open this is stored
in the RLUN array in MTZWRK
LINE (O) CHARACTER*(*) character string containing one header
record from the MTZ file
LRHDRL calls the following which are external to MTZLIB:
External Subroutines: QREAD,LERROR
Arguments:
IBATCH (I) INTEGER batch number
IPRINT (I) INTEGER print indicator: meaning:
=0 no print
=1 print batch title only
=2 also print orientation block
.GT. 30 also print orientation block
TO UNIT NUMBER IPRINT
LBPRTH is called by LBPRT.
LBPRTH calls the following which are external to MTZLIB:
External Subroutines: BLANK,PUTLIN
Arguments:
LABELS (I) CHARACTER*(*) array of dimension (NLABS) containing
the character strings to be output
NLABS (I) INTEGER number of labels to be output
LABPRT calls th following which are external to MTZLIB:
External Functions : INTEGER LENSTR
External Subroutines: PUTLIN
Arguments: N (I) INTEGER dimension of arrays A and IN A (I) INTEGER array to be sorted IN (O) INTEGER index array for A
Arguments: NEWLIN(MAXLIN) (I/O) character array this is cleared on output LINES(MAXLIN) (O) character array
Arguments:
LINES(MAXLIN) (I) character array
NEXTLN (O) INTEGER number of next blank line (= -1 if full)
First calculate the components of input axes in an orthonormal basis, then calculate components of reciprocal axes in same basis
Input angles are in degrees
This is exactly the same as the subroutine SETRSL in SYMLIB, except that it stores its variables in the internal MTZ COMMON blocks, and will work if more than one file is open at once.
MINDX (I) INTEGER indicates which MTZ file - one index
points to both input and output files
A,B,C,ALPHA,BETA,GAMMA
(I) REAL cell parameters
This is exactly the same as the function STHLSQ in SYMLIB, except that it stores it's variables in the internal MTZ COMMON blocks, and will work if more than one file is open at once.
MINDX (I) INTEGER indicates which MTZ file - one index
points to both input and output files
IH,IK,IL (I) INTEGER Miller indices for the reflection
C
C - Parameters, COMMON blocks, and declarations for MTZ subroutines
C
C .. Parameters ..
INTEGER MFILES,MCOLS,MBATCH
PARAMETER (MFILES=4,MCOLS=500,MBATCH=5000)
INTEGER MINCOL
PARAMETER (MINCOL=3)
INTEGER NTYP,LTYP
PARAMETER (NTYP=16,LTYP=9)
INTEGER MBLENG,CBLENG
PARAMETER (MBLENG=185,CBLENG=70+3*8)
INTEGER NHISLM
PARAMETER (NHISLM=30)
C ..
C .. Arrays in Common ..
REAL CELL,CRANGE,SRANGE,RBATR,RBATW,RSYM,WRANGE,WSRNGE
INTEGER BATNUM,HDRST,ISORT,NBATCH,NBATR,NBATW,NCOLS,NCOLW,NHISTL,
+ NPLABS,NREFR,NREFS,NREFW,NSPGRP,NSYM,NSYMP,RLUN,RPOINT,
+ WLUN,WOMBAT,NSETW,SET_ID,CSET_ID,IDEFSET
LOGICAL SORTB
CHARACTER CBATR*1,CBATW*1,CTYPE*1,LTYPE*1,PGNAM*10,SPGNAM*10,
+ CLABEL*30,PLABS*30,TITLE*70,HSCR*80,ENTRY_ID*64,
+ DIFFRN_ID*64
C ..
C .. Local Arrays ..
CHARACTER CTYPES(NTYP)*1,LTYPES(LTYP)*1
C ..
C .. Common blocks ..
COMMON /MTZCHR/TITLE(MFILES),CLABEL(MCOLS,MFILES),
+ CTYPE(MCOLS,MFILES),SPGNAM(MFILES),LTYPE(MFILES),
+ CBATR(CBLENG,MBATCH,MFILES),PGNAM(MFILES)
COMMON /MTZHDR/CELL(6,MFILES),NSYM(MFILES),NSYMP(MFILES),
+ RSYM(4,4,192,MFILES),NCOLS(MFILES),NREFS(MFILES),
+ NBATCH(MFILES),BATNUM(MBATCH,MFILES),ISORT(5,MFILES),
+ CRANGE(2,MCOLS,MFILES),NSPGRP(MFILES),
+ RBATR(MBLENG,MBATCH,MFILES),SRANGE(2,MFILES)
COMMON /MTZWRC/PLABS(MCOLS,MFILES),HSCR(NHISLM,MFILES),
+ CBATW(CBLENG,MBATCH,MFILES)
COMMON /MTZWRK/NCOLW(MFILES),RLUN(MFILES),WLUN(MFILES),
+ RPOINT(MCOLS,MFILES),WRANGE(2,MCOLS,MFILES),NREFW(MFILES),
+ NREFR(MFILES),NPLABS(MFILES),NBATW(MFILES),NBATR(MFILES),
+ WOMBAT(MBATCH,MFILES),HDRST(MFILES),SORTB(MFILES),
+ NHISTL(MFILES),RBATW(MBLENG,MBATCH,MFILES),WSRNGE(2,MFILES)
COMMON /MTZHAR/NSETW(MFILES),SET_ID(MSETS,MFILES),
+ ENTRY_ID(MSETS,MFILES),DIFFRN_ID(MSETS,MFILES),
+ CSET_ID(MCOLS,MFILES),IDEFSET(MFILES)
C ..
C .. Data statements ..
DATA CTYPES/'H','J','F','D','Q','P','W','A','B','Y','I','R',
+ 'G','K','L','M'/
DATA LTYPES/'P','A','B','C','I','F','R','H','?'/
Common blocks used by multi-record MTZ routines:
These subroutines pass the batch header information (title and orientation blocks) as arguments packed into a REAL(185) and a CHARACTER(94) array. In the real array, the first 156 words are REAL numbers and the remaining 29 are INTEGER*4. The subroutine which produces formatted output of the batch headers, LBPRT, decodes these arrays into separate items by copying these arrays into common blocks (one for real and one for characters), and calling a subroutine (LBPRTH) which has these common blocks as
COMMON /MBTHDR/ NWORDS,NINTGR,NREALS,IORTYP,LBCELL(6),MISFLG,
+ JUMPAX,NCRYST,LCRFLG,LDTYPE,JSCAXS,NBSCAL,NGONAX,LBMFLG,
+ NDET,LBSETID,INTPAD(8),
+ CELL(6),UMAT(3,3),PHIXYZ(3,2),CRYDAT(12),DATUM(3),
+ PHISTT,PHIEND,SCANAX(3),TIME1,TIME2,
+ BSCALE,BBFAC,SDBSCL,SDBFAC,PHIRANGE,BATPAD(11),
+ E1(3),E2(3),E3(3),
+ GONPAD(12),SOURCE(3),S0(3),BEMDAT(25),
+ DX1,THETA1,DETLM1(2,2),DX2,THETA2,DETLM2(2,2),DETPAD(33)
INTEGER NWORDS,NINTGR,NREALS,IORTYP,LBCELL,MISFLG,
+ JUMPAX,NCRYST,LCRFLG,LDTYPE,JSCAXS,NBSCAL,NGONAX,LBMFLG,
+ NDET,LBSETID,INTPAD
REAL CELL,UMAT,PHIXYZ,CRYDAT,ETAD,DATUM,
+ PHISTT,PHIEND,PHIRANGE,SCANAX,TIME1,TIME2,
+ BSCALE,BBFAC,SDBSCL,SDBFAC,BATPAD,E1,E2,E3,GONPAD,
+ SOURCE,S0,BEMDAT,ALAMBD,DELAMB,DELCOR,DIVHD,DIVVD,
+ DX1,THETA1,DETLM1,DX2,THETA2,DETLM2,DETPAD,ETADH,ETADV
COMMON /CBTHDR/ BTITLE,GONLAB(3)
CHARACTER BTITLE*70, GONLAB*8
An explanation of the format of the common blocks:
Orientation block data
This contains slots for all information that seems to be essential at present. Each group of parameters is padded at the end for future expansion.
Data in the orientation block are referred to the Cambridge laboratory axis
frame: x along the (idealized) X-ray beam, z along usual rotation axis E1
(omega on 3-axis system). The matrix Q converts a vector in the Madnes frame
to the Cambridge frame. Note that the laboratory frame is essentially defined
by the vectors e1,e2,e3 and source. It doesn't really seem necessary to carry
through a whole lot of crystal and beam tensors, particularly as we have
integrated intensities at this stage, but maybe someone will want to, using
the allocated padding
The general orientation equation is
x = R M U B h
where x position in laboratory frame
R goniostat matrix
M missetting angle matrix (if relevant, see MISFLG)
PhiZ PhiY PhiX (PHIXYZ)
U crystal orientation matrix UMAT
B cell orthogonalization matrix, derived from cell dimensions
h reflection indices
Note that the description below is NOT is the same order as in the
common block, in which all the integers come before all the reals
(flagged as I or R in the description below)
I NWORDS number of words in orientation block
I NINTGR number of integers (first part of block includes
these counts)
I NREALS number of reals
I IORTYP type of orientation block (for possible future
use, now = 0)
I INTPAD(8) padding for future use (integers)
--- Information for this crystal
R CELL(6) cell dimensions (A and degrees)
I LBCELL(6) refinement flags for cell dimensions
R UMAT(3,3) orientation matrix U. If MISFLG .gt. 0, U is the
standard setting when PhiXYZ ==0
I MISFLG status of missetting angles PHIXYZ
= 0 PHIXYZ not used, all orientation in UMAT
= 1 1 set of missetting angles (PHIXYZ(I,1))
= 2 2 sets PHIXYZ(I,J), J=1,2
R PHIXYZ(3,2) missetting angles at beginning and end of rotation
I JUMPAX reciprocal axis closest to principle goniostat axis E1
(only used for printing)
I NCRYST crystal number: a crystal may contain several batches
I LBSETID dataset number (this indexes a list of datasets in the
file header)
I LCRFLG type of crystal mosaicity information
(=0 for isotropic, =1 anisotropic)
*** CRYDAT(12) equivalenced to following ***
R ETAD reflection width (full width) (degrees) (if LCRFLG=0)
or
R ETADH,ETADV horizontal and vertical reflection width (if LCRFLG=1)
R rest of CRYDAT: padding for crystal information
(eg more complicated mosaicity model)
--- Information for this batch
I LDTYPE type of data
= 1 oscillation data (2D spots)
= 2 area detector data (3D spots)
= 3 Laue data
R DATUM(3) datum values of goniostat axes, from which
Phi is measured (degrees)
R PHISTT,PHIEND start and stop values of Phi (degrees)
relative to datum
R PHIRANGE range of Phi values: typically this will be PHIEND-PHISTT,
but storing this explicitly allows a distinction
eg between a rotation of +160 degrees from a rotation
of -200 degrees
I JSCAXS goniostat scan axis number (=1,2,3, or =0
for multiple axis scan
R SCANAX(3) rotation axis in laboratory frame
(not yet implemented: only relevant if JSCAXS=0)
R TIME1, TIME2 start and stop times in minutes
I NBSCAL number of batch scales and Bfactors plus SD's
(4 at present, BSCALE, BBFAC and sd's)
set = 0 if batch scales unset
R BSCALE batch scale
R BBFAC batch temperature factor.
corresponding scale is
exp(-2 B (sin theta/lambda)**2)
R SDBSCL sd (Bscale)
R SDBFAC sd (BBfac)
R BATPAD(11) padding for batch information
--- Crystal goniostat information
I NGONAX number of goniostat axes (normally 1 or 3)
I E1(3),E2(3),E3(3) vectors (in Cambridge laboratory frame,
see below) defining the NGONAX goniostat axes
C GONLAB(3) names of the three goniostat axes
R GONPAD(12) padding for goniostat information
--- Beam information
R SOURCE(3) Idealized (ie excluding tilts) source vector
(antiparallel to beam), in Cambridge
laboratory frame
R S0(3) Source vector (antiparallel ! to beam), in
Cambridge laboratory frame, including tilts
I LBMFLG flag for type of beam information following
= 0 for ALAMBD, DELAMB only (laboratory source)
= 1 ALAMBD,DELAMB,DELCOR,DIVHD,DIVVD
(synchrotron)
(other options could include white beam)
*** BEMDAT(25) equivalenced to following ***
R ALAMBD Wavelength in Angstroms
R DELAMB dispersion Deltalambda / lambda.
R DELCOR Correlated component of wavelength dispersion.
R DIVHD Horizontal beam divergence in degrees.
R DIVVD Vertical beam divergence (may be 0.0 for
isotropic beam divergence.
R rest of BEMDAT: padding for beam information
--- Detector information
I NDET number of detectors (current maximum 2)
-- for each detector
R DXn crystal to detector distance (mm)
R THETAn detector tilt angle (=Madnes:tau2) (degrees)
R DETLMn(2,2) minimum and maximum values of detector
coordinates (pixels)
(i,j): i = 1 minimum, = 2 maximum
j = 1 Ydet, = 2 Zdet
R DETPAD(34) padding for detector information
If you want to see an example of this, look at the subroutines
LBPRT and LBPRTH.
PROGRAM example_MTZ
C ===================
C
C---- An example of a program reading and writing MTZ files.C
C
C .. Parameters ..
INTEGER MCOLS, NPAR, NLOC
PARAMETER (MCOLS=500, NPAR=200, NLOC=50)
C ..
C .. Scalars for Parser ..
INTEGER NTOK
LOGICAL LEND
CHARACTER KEY*4,LINE*400
C ..
C .. Arrays for Parser ..
REAL FVALUE(NPAR)
INTEGER IBEG(NPAR),IDEC(NPAR),IEND(NPAR),ITYP(NPAR)
CHARACTER CVALUE(NPAR)*4
C ..
C .. Local Scalars ..
REAL EPS,F1,F2,FLAGIP,FLAGOP,RSOL
INTEGER ALLSYM,I,IC,ICALL,ICEN,IERR,IFIL,II,ILEN,IPRINT,ISYSAB,
+ JDO10,JDO30,JDO40,JQ,NCEN,NCHK,NCOL,NEPS,NLPRGI,NLPRGO,
+ NREF,NSYM,NSYSAB,NLUSRI,NLURSO
CHARACTER DUMMY*10,TITNEW*70
LOGICAL EOF
C ..
C .. Local Arrays ..
REAL ADATA(MCOLS),DUM(2,MCOLS),RSYM(4,4,192)
INTEGER IH(3),JPOINT(NLOC),LOOKUP(NLOC)
CHARACTER OUTTYP(NLOC)*1,LSPRGI(NLOC)*30,LSPRGO(NLOC)*30,
+ HISNEW(20)*80,CTPRGI(NLOC)*1
C ..
C .. External Subroutines ..
EXTERNAL CCPUPC,CENTR,EPSLON,LRASSN,LRINFO,LROPEN,LRREFF,
+ LRSYMM,LRTITL,LWASSN,LWCLOS,LWHIST,LWOPEN,LWREFL,LWTITL,
+ PARSER,SYMTRN,LKYIN,LKYOUT
C ..
C .. Data statements ..
C---- NLPRGI = number of input labels
DATA NLPRGI,LSPRGI/7,'H','K','L','F1','SIG1','DELF1',
+ 'SIGDELF1',43*' '/
C---- NLPRGO = number of output labels
DATA NLPRGO,LSPRGO/9,'H','K','L','FP','F1','SIG1','SIGFP',
+ 'FN','SIGFN',41*' '/
C---- This code signs which input columns are essential (LOOKUP)
DATA CTPRGI/'H','H','H','F','Q','F','Q',43*' '/
DATA OUTTYP/'H','H','H','F','Q','F','Q','F','Q',41*' '/
DATA LOOKUP/-1,-1,-1,-1,-1,-1,0,43*0/
C---- Clear character arrays TITNEW, HISNEW, JPOINT
DATA HISNEW/20*' '/, JPOINT/50*0/
C ..
CALL CCPFYP
CALL MTZINI
NTOK = NPAR
IFIL = 1
IPRINT = 3
C---- Open input file for Read
CALL LROPEN(IFIL,'HKLIN',IPRINT,IERR)
C---- Open output file
CALL LWOPEN(IFIL,'HKLOUT')
C---- Default is to copy input title to output
C---- Do you want to change title??
TITNEW = 'A test case for reading and writing MTZ files'
CALL LWTITL(IFIL,TITNEW,0)
C---- Some history to append to output file
C Only last 30 lines will be kept
HISNEW(1) = ' Calculating F(+) F(-) - MTZRW_NEW'
HISNEW(2) = ' Some more info...'
CALL LWHIST(IFIL,HISNEW,2)
C---- Find out how many columns and reflections in input file
CALL LRINFO(IFIL,DUMMY,NCOL,NREF,DUM)
C---- We want to set up centric and epsilon tests
ALLSYM = 0
CALL LRSYMM(IFIL,NSYM,RSYM)
CALL SYMTRN(NSYM,RSYM)
CALL CENTRIC(NSYM,ISYM,0)
C---- Read Program labels here if you like or
C use those assigned in data stt above...
C
C Eg as in FFT F1 SIG1 F2 SIG2 PHI ....
C
C LKYIN will read string F1=FNAT89 PHI=Acalc ...
C LRASSN will set LOOKUP(i) (i=1-nlabs) equal
C column number in input file.
C LOOKUP(i)=0 if label not matched...
NLUSRI = 0
NLUSRO = 0
20 CONTINUE
LINE = ' '
KEY = ' '
NTOK = NPAR
CALL PARSER(KEY,LINE,IBEG,IEND,ITYP,FVALUE,CVALUE,IDEC,NTOK,LEND,
+ .FALSE.)
IF (.NOT.LEND) THEN
IF (KEY.EQ.'LABI') THEN
CALL LKYIN (IFIL,LSPRGI,NLPRGI,NTOK,LINE,IBEG,IEND)
CALL LRASSN(IFIL,LSPRGI,NLPRGI,LOOKUP,CTPRGI)
ELSE IF (KEY.EQ.'LABO') THEN
CALL LKYOUT(IFIL,LSPRGO,NLPRGO,NTOK,LINE,IBEG,IEND)
CALL LWASSN(IFIL,LSPRGO,NLPRGO,OUTTYP,0)
END IF
GO TO 20
END IF
C---- Now read data (`lookup' order)
WRITE (6,FMT=*) ' NREF= ',NREF
DO 40 JDO40 = 1,NREF
CALL LRREFF(IFIL,RSOL,ADATA,EOF)
IH(1) = ADATA(1)
IH(2) = ADATA(2)
IH(3) = ADATA(3)
C centricity check
CALL CENTR(IH,ICEN)
IF (ICEN.EQ.1) THEN
NCEN = NCEN + 1
IF (NCEN.LT.21) WRITE (6,FMT='(A,3I4,F8.2)') ' CENTRIC ',IH
END IF
C---- EPS = multiplicity of reflection. ISYSAB = 1 - systematic absence
CALL EPSLON(IH,EPS,ISYSAB)
IF (EPS.GT.1.0) THEN
NEPS = NEPS + 1
WRITE (6,FMT='(/,A,3I4,F8.2)') ' EPS GT 1 ',IH,EPS
IF (ISYSAB.EQ.1) THEN
NSYSAB = NSYSAB + 1
WRITE (6,FMT='(/,A,3I4,F8.2)') ' SYS ABS ',IH
END IF
END IF
NCHK = MOD(JDO40,500)
IF (NCHK.EQ.1) THEN
IH(1) = ADATA(1)
IH(2) = ADATA(2)
IH(3) = ADATA(3)
WRITE (6,FMT=6004) JDO40,IERR,IH, (ADATA(II),II=4,NCOL)
END IF
C---- Do something .....
F1 = (ADATA(4)+ADATA(6))/2
F2 = (ADATA(4)-ADATA(6))/2
ADATA(6) = F1
ADATA(7) = ADATA(5)
ADATA(8) = F2
ADATA(9) = ADATA(5)
C---- New write routine
IF (NCHK.EQ.1) WRITE (6,FMT=6006) JDO40,
+ (ADATA(II),II=1,NLPRGO)
IERR = -1
ICALL = ICALL + 1
CALL LWREFL(IFIL,ADATA)
40 CONTINUE
WRITE (6,FMT=6008) NCEN,NEPS,NSYSAB
C---- Close output file - This call actually writes the header
CALL LWCLOS(IFIL,2)
CALL CCPERR(0, 'Normal termination')
C---- Format statements
6000 FORMAT (' No assignment using default of ',A)
6002 FORMAT (' index for MLABSO = ',I4,' prog lab ',A,' user label ',A)
6004 FORMAT (' NREF IEND - IP DATA ',I8,I3,/1X,3I4,10F8.1,
+ 10 (/13X,10F8.1))
6006 FORMAT (' NREF OP DATA ',I8,/1X,3F6.2,10F8.1,10 (/13X,10F8.1))
6008 FORMAT (' END OF FILE - NUMBER OF CENTRIC REFLNS',I5,/' NUMBER O',
+ 'F EPS GT 1 ',I5,/' NUMBER OF SYS ABS ',I5)
END
Missing Number Flag routines: 1996-ish
Dataset handling: Martyn Winn 1998