C
C CIFtbx README FIRST Information
C -------------------------------
C (Version July 17 1994)
C
C This file contains the complete set of source decks and test data
C needed to implement and test the CIFtbx Tool Box routines.
C
C
C Here is the recommended procedure for implementing and testing CIFtbx.
C
C
C 1. Use your editor to separate the different parts of the file into
C individual files in your workspace. Each part is partitioned by
C a line containing "---cut here---". Use your editor to search for
C these lines. Each part is carefully labelled and indicates the
C recommended filename for the separated file. On some machines
C these filenames may need to be altered to suit the OS or compiler.
C
C The partitions are as follows:
C
C part filename description
C
C 1 ciftbx.f CIFtbx fortran source
C 2 ciftbx.sys CIFtbx common for inclusion into ciftbx.f
C 3 ciftbx.cmn CIFtbx common for inclusion into applications
C 4 tbx_ex.f example application used to test ciftbx.f
C 5 test.cif example CIF used by tbx_ex.f
C 6 test.req example request file used by tbx_ex.f
C 7 test.prt print file output from tbx_ex.f run
C 8 test.out CIF output by the tbx_ex.f run
C
C
C 2. Once you have separated out these files, list 'ciftbx.f' and 'tbx_ex.f'
C in particular (all if possible!) and carefully read the descriptions
C in the front of these files. Remember that 'tbx_ex.f' is only an
C example of a CIF application -- it shows how some basic CIF operations
C can be performed, but it is not necessarily sensible or typical of what
C an actual application would look like!
C
C
C 3. You are now ready to implement the tool box and the test application.
C Here are the recommended steps for a unix system. Vary this according
C to the requirements of your OS and compiler. ***Note*** to execute
C the supplied example application 'tbx_ex.f' identically to the test
C outputs supplied, a copy of the CIF Core Dictionary 'cifdic.c91' must
C be present in your work area. If it is not the tests will proceed with
C a warning message but no validations checks will occur. A copy of the
C dictionary 'cifdic.c91' can be obtained from 'syd@crystal.uwa.edu.au'.
C
C
C (a) compile 'tbx_ex.f' [note that provided the fortran "include"
C function is available to you, the files 'ciftbx.f', 'ciftbx.sys'
C and 'ciftbx.cmn' will be automatically opened and processed by
C this single operation]
C
C (b) link 'tbx_ex.o' as the executable file 'tbx_ex.x'
C
C (c) execute 'tbx_ex.x' so that the input file is 'test.req' connected
C to device 5 (stdin) and the list file 'test.lst' is connected to
C device 6 (stdout). The input CIF 'test.cif' and the output CIF
C 'test.new' will be automatically opened. For a unix OS the command
C will look like this: 'tbx_ex.x < test.req > test.lst'
C
C (d) to check that the test has been successful, compare the files that
C you have generated 'test.lst' with the supplied 'test.prt', and
C 'test.new' with 'test.out'. They should be identical.
C
C (e) if you have any problems with this process please report them to
C Syd Hall [em: syd@crystal.uwa.edu.au fx: 61(9)3801118].
C
C 4. You are now ready to implement CIFtbx for your software applications.
C Note that it more efficient to compile 'ciftbx.f' separately and add
C 'ciftbx.o' at link time. Note that the line "include 'ciftbx.cmn'"
C MUST appear at the start of any routine invoking the CIFtbx commands.
C
C
C-------------------------cut here------------------------------------------
C
C
C \ | / /##| @@@@ @ @@@@@ | |
C \|/ STAR /###| @ @ @ __|__ |
C ----*---- /####| @ @ @@@@ | |___ __ __
C /|\ /#####| @ @ @ | | \ \/
C / | \ |#####| @@@@ @ @ \___/ \___/ __/\__
C |#####|________________________________________________
C ||#####| ___________________ |
C __/|_____||#####|________________|&&&&&&&&&&&&&&&&&&&|| |
C<\\\\\\\\_ |_____________________________|&&&& Jul 17 94 &&&&|| |
C \| ||#####|________________|&&&&&&&&&&&&&&&&&&&||__________|
C |#####|
C |#####|
C |#####|
C /#######\
C |#########|
C ====
C ||
C A tool box of fortran routines for manipulating CIF data.
C ||
C ||
C The latest program source and information is available from:
C ||
C Em: syd@crystal.uwa.edu.au ,-_|\ Sydney R. Hall
C sendcif@crystal.uwa.edu.au / \ Crystallography Centre
C Fx: +61 9 380 1118 || --> *_,-._/ University of Western Australia
C Ph: +61 9 380 2725 || v Nedlands 6009, AUSTRALIA
C ||
C_____________________||_____________________________________________________
C
C
C GENERAL TOOLS
C
C
C init_ Sets the device numbers of files. (optional)
C [logical function always returned .true.]
C
C Set input CIF device (def=1)
C
C Set output CIF device (def=2)
C
C Set direct access formatted
C scratch device number (def=3)
C
C Set error message device (def=6)
C
C
C
C dict_ Requests a CIF dictionary be used for various data checks.
C [logical function returned as .true. is the name dictionary
C was opened; and if the check codes are recognisable.]
C
C A CIF dictionary in DDL format
C
C The codes specifying the types of
C checks to be applied to the CIF.
C
C 'valid' data name validation check.
C 'dtype' data item data type check.
C
C___________________________________________________________________________
C
C
C CIF ACCESS TOOLS ("the get_ing commands")
C
C
C
C open_ Opens the CIF containing the required data.
C [logical function returned .true. if CIF opened]
C
C
C
C
C
C data_ Identifies the data block containing the data to be requested.
C [logical function returned .true. if block found]
C
C A blank name signals that the next
C encountered block is used (the block
C name is stored in the variable bloc_).
C
C
C
C test_ Identify the data attributes of the named data item.
C [logical function returned as .true. if the item is present or
C .false. if it is not. The data attributes are stored in the
C the common variables type_ and list_.
C
C list_ is an integer variable containing the sequential number
C of the loop block in the data block. If the item is not within
C a loop structure this value will be zero.
C
C type_ is a character*4 variable with the possible values:
C 'numb' for number data
C 'char' for character data
C 'text' for text data
C 'null' if data missing or '?']
C
C Name of the data item to be tested.
C
C
C
C name_ Get the next data name in the current data block.
C [logical function returned as .true. if a new data name exists
C in the current data block, and .false. when the end of the data
C block is reached.]
C
C Returned name of next data item in block.
C
C
C
C numb_ Extracts the number and its standard deviation (if appended).
C [logical function returned as .true. if number present. If
C .false. arguments 2 and 3 are unaltered. If the esd is not
C attached to the number argument 3 is unaltered.]
C
C Name of the number sought.
C
C Returned number.
C
C Returned standard deviation.
C
C
C
C char_ Extracts character and text strings.
C [logical function returned as .true. if the string is present.
C Note that if the character string is text this function is
C called repeatedly until the logical variable text_ is .false.]
C
C Name of the string sought.
C
C Returned string is of length long_.
C
C
C____________________________________________________________________________
C
C
C
C CIF CREATION TOOLS ("the put_ing commands")
C
C
C
C pfile_ Create a file with the specified file name.
C [logical function returned as .true. if the file is opened.
C The value will be .false. if the file already exists.]
C
C
C
C
C
C pdata_ Put a data block command into the created CIF.
C [logical function returned as .true. if the block is created.
C The value will be .false. if the block name already exists.]
C
C
C
C
C
C ploop_ Put a loop_ data name into the created CIF.
C [logical function returned as .true. if the invocation
C conforms with the CIF logical structure.]
C
C
C
C
C
C pchar_ Put a character string into the created CIF.
C [logical function returned as .true. if the name is unique,
C AND, if dict_ is invoked, is a name defined in the dictionary,
C AND, if the invocation conforms to the CIF logical structure.]
C
C If the name is blank, do not output name.
C
C A character string of 80 chars or less.
C
C
C
C pnumb_ Put a number and its esd into the created CIF.
C [logical function returned as .true. if the name is unique,
C AND, if dict_ is invoked, is a name defined in the dictionary,
C AND, if the invocation conforms to the CIF logical structure.]
C
C If the name is blank, do not output name.
C
C Number to be inserted.
C
C Esd number to be appended in parentheses.
C
C
C
C ptext_ Put a character string into the created CIF.
C [logical function returned as .true. if the name is unique,
C AND, if dict_ is invoked, is a name defined in the dictionary,
C AND, if the invocation conforms to the CIF logical structure.]
C ptext_ is invoked repeatedly until the text is finished. Only
C the first invocation will insert a data name.
C
C If the name is blank, do not output name.
C
C A character string of 80 chars or less.
C
C
C
C close_ Close the creation CIF. MUST be used if pfile_ is used.
C [subroutine call]
C
C
C____________________________________________________________________________
C
C
C
C....The CIF tool box also provides variables for data access control:
C
C
C text_ Logical variable signals if another text line is present.
C
C loop_ Logical variable signals if another loop packet is present.
C
C bloc_ Character*32 variable: the current block name.
C
C strg_ Character*80 variable: the current data item.
C
C type_ Character*4 variable: the data type code (see test_).
C
C list_ Integer variable: the loop block number (see test_).
C
C long_ Integer variable: the length of the data string in strg_.
C
C file_ Character*80 variable: the filename of the current file.
C
C longf_ Integer variable: the length of the filename in file_.
C
C align_ Logical variable signals alignment of loop_ lists during
C the creation of a CIF. The default is .true.
C
C
C_____________________________________________________________________________
C
C
C >>>>>> Set the device numbers.
C
function init_(devcif,devout,devdir,deverr)
C
include 'ciftbx.sys'
logical init_
integer devcif,devout,devdir,deverr
C
init_=.true.
cifdev=devcif
outdev=devout
dirdev=devdir
errdev=deverr
return
end
C
C
C
C
C
C >>>>>> Read a CIF dictionary and prepare for checks
C
function dict_(fname,checks)
C
include 'ciftbx.sys'
logical dict_,data_,open_,char_
character locase*80
character fname*(*),checks*(*)
character temp*24,codes(4)*5,name*80
integer idict,i,j
data codes /'valid','dtype',' ',' '/
C
C....... Open and store the dictionary
C
if(nname.gt.0) call err(' dict_ must precede open_')
dict_=open_(fname)
if(.not.dict_) goto 500
dictfl='yes'
C
C....... Are the codes OK
C
temp=checks
i=0
120 i=i+1
if(i.ge.24) goto 200
if(temp(i:i).eq.' ') goto 120
do 150 j=1,4
if(temp(i:i+4).eq.codes(j)) goto 170
150 continue
dict_=.false.
goto 500
170 i=i+4
if(j.eq.1) vcheck='yes'
if(j.eq.2) tcheck='yes'
goto 120
C
C....... Loop over data blocks; extract _name's, _type etc.
C
200 if(.not.data_(' ')) goto 400
idict=ndict+1
Cdbg WRITE(6,*) ndict,bloc_
C
250 if(.not.char_('_name',name))goto 200
ndict=ndict+1
if(ndict.gt.1000) call err(' cifdic names > 1000')
dicnam(ndict)=locase(name(1:long_))
if(loop_) goto 250
C
if(tcheck.eq.'no ') goto 200
if(.not.char_('_type',name))call err(' _type line missing')
do 270 i=idict,ndict
270 dictyp(i)=name(1:4)
goto 200
C
400 close(dirdev)
if(tcheck.eq.'yes') vcheck='yes'
dictfl='no '
Cdbg WRITE(6,'(i5,3x,a,2x,a)') (i,dicnam(i),dictyp(i),i=1,ndict)
500 return
end
C
C
C
C
C
C >>>>>> Open a CIF and copy its contents into a direct access file.
C
function open_(fname)
C
include 'ciftbx.sys'
logical open_,test
character fname*(*)
integer case,i
C
jchar=80
nrecd=0
lrecd=0
case=ichar('a')-ichar('A')
tab=char(05)
if(case.lt.0) goto 100
tab=char(09)
C
C....... Make sure the CIF is available to open
C
100 file_=fname
do 120 i=1,80
if(file_(i:i).eq.' ') goto 140
120 continue
140 longf_=i-1
inquire(file=file_(1:longf_),exist=test)
open_=test
if(.not.open_) goto 200
C
C....... Open up the CIF and a direct access formatted file as scratch
C
open(unit=cifdev,file=fname,status='OLD',access='SEQUENTIAL',
* form='FORMATTED')
open(unit=dirdev,status='SCRATCH',access='DIRECT',
* form='FORMATTED',recl=80)
C
C....... Copy the CIF to the direct access file
C
160 read(cifdev,'(a)',end=180) buffer
nrecd=nrecd+1
write(dirdev,'(a)',rec=nrecd) buffer
Cdbg WRITE(6,'(i5,1x,a)') nrecd,buffer(1:70)
goto 160
C
180 lrecd=0
close(cifdev)
200 return
end
C
C
C
C
C
C >>>>>> Store the data names and pointers for the requested data block
C
function data_(name)
C
include 'ciftbx.sys'
logical data_
character name*(*),flag*4,temp*32,ltype*4
character locase*80
integer ndata,idata,nitem,npakt,i,j
C
jchar=80
jrecd=0
nname=0
ndata=0
nitem=0
idata=0
iname=0
loopct=0
loopnl=0
ltype=' '
data_=.false.
loop_=.false.
text_=.false.
irecd=lrecd
lrecd=nrecd
if(name(1:1).ne.' ') irecd=0
C
C....... Find the requested data block in the file
C
100 call getstr
if(type_.eq.'fini') goto 500
if(type_.ne.'text') goto 120
110 call getlin(flag)
if(buffer(1:1).ne.';') goto 110
call getlin(flag)
goto 100
120 if(type_.ne.'data') goto 100
if(name.eq.' ') goto 150
if(strg_(6:long_).ne.name) goto 100
150 data_=.true.
bloc_=strg_(6:long_)
C
C....... Get the next token and identify
C
200 call getstr
Cdbg WRITE(6,*) ltype,type_,loop_,nitem,ndata,idata,irecd,lrecd
C
if(ltype.ne.'name') goto 201
if(type_.eq.'numb') goto 203
if(type_.eq.'char') goto 203
if(type_.eq.'text') goto 203
if(type_.eq.'name'.and.loop_) goto 204
call err(' Illegal tag/value construction')
201 if(ltype.ne.'valu') goto 204
if(type_.eq.'numb') goto 202
if(type_.eq.'char') goto 202
if(type_.eq.'text') goto 202
goto 204
202 if(nitem.gt.0) goto 205
call err(' Illegal tag/value construction')
203 ltype='valu'
goto 205
204 ltype=type_
C
205 if(type_.eq.'name') goto 206
if(type_.eq.'loop') goto 210
if(type_.eq.'data') goto 210
if(type_.ne.'fini') goto 220
206 if(loop_) goto 270
210 if(nitem.eq.0) goto 215
C
C....... End of loop detected; save pointers
C
npakt=idata/nitem
if(npakt*nitem.ne.idata) call err(' Item miscount in loop')
loopni(loopct)=nitem
loopnp(loopct)=npakt
nitem=0
idata=0
215 if(type_.eq.'name') goto 270
if(type_.eq.'data') goto 300
if(type_.eq.'fini') goto 300
C
C....... Loop_ line detected; incr loop block counter
C
loop_=.true.
loopct=loopct+1
if(loopct.gt.50) call err(' Number of loop_s > 50')
goto 200
C
C....... This is the data item; store char position and length
C
220 loop_=.false.
if(nitem.gt.0) idata=idata+1
if(nname.eq.ndata) goto 230
ndata=ndata+1
if(iloop(ndata).gt.1) goto 225
krecd=irecd
kchar=jchar-long_-1
225 dtype(ndata)=type_
drecd(ndata)=krecd
dchar(ndata)=kchar
if(nloop(ndata).gt.0) goto 230
nloop(ndata)=0
iloop(ndata)=long_
C
C....... Skip text lines if present
C
230 if(type_.ne.'text') goto 200
dchar(ndata)=0
if(nloop(ndata).eq.0) iloop(ndata)=80
250 call getlin(flag)
if(buffer(1:1).eq.';') goto 200
if(flag.eq.'fini') call err(' Unexpected end of data')
goto 250
C
C....... This is a data name; store name and loop parameters
C
270 nname=nname+1
if(nname.gt.500) call err(' Number of data names > 500')
dname(nname)=locase(strg_(1:long_))
lloop(nname)=0
nloop(nname)=0
iloop(nname)=0
if(.not.loop_) goto 200
nitem=nitem+1
if(nitem.gt.20) call err(' Items per loop packet > 20')
nloop(nname)=loopct
iloop(nname)=nitem
goto 200
C
C....... Are names checked against dictionary?
C
300 if(dictfl.eq.'yes') goto 500
if(vcheck.eq.'no ') goto 500
C
do 350 i=1,nname
temp=dname(i)
do 330 j=1,ndict
if(temp.ne.dicnam(j)) goto 330
if(tcheck.eq.'no ') goto 350
if(dtype(i).eq.dictyp(j)) goto 350
write(errdev,'(2a,1x,2a)') ' Warning: type ',dtype(i),temp,
* ' different to dictionary!'
goto 350
330 continue
write(errdev,'(3a)') ' Warning: data name ',temp,
* ' not in dictionary!'
350 continue
C
C....... End of data block; tidy up loop storage
C
500 lrecd=irecd-1
loop_=.false.
loopct=0
if(ndata.ne.nname) call err(' Syntax construction error')
C
Cdbg WRITE(6,'(a)')
Cdbg * ' data name type recd char loop leng'
Cdbg WRITE(6,'(a,1x,a,4i5)') (dname(i),dtype(i),drecd(i),dchar(i),
Cdbg * nloop(i),iloop(i),i=1,nname)
Cdbg WRITE(6,'(3i5)') (i,loopni(i),loopnp(i),i=1,loopct)
C
return
end
C
C
C
C
C
C
C >>>>>> Get the attributes of data item associated with data name
C
function test_(temp)
C
include 'ciftbx.sys'
logical test_
character temp*(*),name*32
character locase*80
C
testfl='yes'
name=locase(temp)
test_=.true.
if(testfl.eq.'no ') goto 100
if(name.eq.nametb) goto 200
100 call getitm(name)
200 list_ =loopnl
if(type_.eq.'null') test_=.false.
return
end
C
C
C
C
C
C
C >>>>>> Get the next data name in the data block
C
function name_(temp)
C
include 'ciftbx.sys'
logical name_
character temp*(*)
C
name_=.false.
temp=' '
iname=iname+1
if(iname.gt.nname) goto 100
name_=.true.
temp=dname(iname)
100 return
end
C
C
C
C
C
C
C >>>>>> Extract a number data item and its standard deviation
C
function numb_(temp,numb,sdev)
C
include 'ciftbx.sys'
logical numb_
character temp*(*),name*32
character locase*80
real numb,sdev
C
name=locase(temp)
if(testfl.eq.'no ') goto 100
if(name.eq.nametb) goto 150
C
100 call getitm(name)
C
150 numb_=.false.
if(type_.ne.'numb') goto 200
numb_=.true.
numb =numbtb
if(sdevtb.ge.0.0) sdev=sdevtb
C
200 testfl='no '
return
end
C
C
C
C
C
C
C >>>>>> Extract a character data item.
C
function char_(temp,strg)
C
include 'ciftbx.sys'
logical char_
character temp*(*),name*32
character strg*(*),flag*4
character locase*80
C
name=locase(temp)
if(testfl.eq.'yes') goto 100
if(.not.text_) goto 120
100 if(name.eq.nametb) goto 150
C
120 call getitm(name)
C
150 char_=.true.
text_=.false.
strg=strg_(1:long_)
if(type_.eq.'char') goto 200
char_=.false.
if(type_.ne.'text') goto 200
char_=.true.
call getlin(flag)
if(buffer(1:1).eq.';') goto 200
text_=.true.
strg_=buffer
C
200 testfl='no '
return
end
C
C
C
C
C
C >>>>> Convert name string to lower case
C
function locase(name)
C
include 'ciftbx.sys'
character locase*80
character temp*80,name*(*)
character low*26,cap*26,c*1
data cap /'ABCDEFGHIJKLMNOPQRSTUVWXYZ'/
data low /'abcdefghijklmnopqrstuvwxyz'/
C
temp=name
do 100 i=1,80
c=temp(i:i)
if(c.eq.' ') goto 200
j=index(cap,c)
if(j.ne.0) temp(i:i)=low(j:j)
100 continue
200 locase=temp
return
end
C
C
C
C
C
C >>>>>> Get the data item associated with the tag.
C
subroutine getitm(name)
C
include 'ciftbx.sys'
SAVE
character name*(*),lname(20)*32
character fhash*3,flag*4
integer phash(20),ihash
integer loopch(21),loopln(21),looprd(21)
integer iitem,nitem,npakt
integer kchar,loopi,i
data fhash/'no '/
C
C....... Find requested dataname in hash list
C
nametb=name
if(name(1:1).eq.'_') goto 100
type_='null'
long_=1
goto 1000
100 if(.not.loop_) goto 150
fhash='no '
do 120 ihash=1,nhash
if(lname(ihash).eq.nametb) goto 170
120 continue
if(nhash.eq.20) goto 150
fhash='yes'
C
C....... Else find requested dataname in full list
C
150 do 160 iname=1,nname
if(dname(iname).eq.nametb) goto 180
160 continue
type_='null'
long_=1
goto 1000
C
C....... Update the hash table if need be
C
170 iname=phash(ihash)
180 if(fhash.eq.'no ') goto 190
nhash=nhash+1
phash(nhash)=iname
lname(nhash)=name
190 if(nloop(iname).le.0) goto 500
C
C....... Process loop packet if first item request
C
if(nloop(iname).ne.loopnl) goto 200
if(lloop(iname).lt.loopct) goto 300
if(loop_) goto 230
200 loop_=.true.
nhash=0
loopct=0
loopnl=nloop(iname)
nitem=loopni(loopnl)
npakt=loopnp(loopnl)
irecd=drecd(iname)-1
call getlin(flag)
jchar=max(0,dchar(iname)-1)
C error jchar=dchar(iname)-1
Cdbg if(jchar.lt.0) write(6,'(" dchar ",i5)') jchar
do 220 i=1,nname
220 lloop(i)=0
goto 240
C
C....... Read a packet of loop items
C
230 irecd=looprd(nitem+1)-1
call getlin(flag)
jchar=loopch(nitem+1)
Cdbg if(jchar.lt.0) write(6,'(" loopch",i5)') jchar
240 iitem=0
250 iitem=iitem+1
if(iitem.le.nitem) goto 255
loopch(iitem)=jchar
looprd(iitem)=irecd
goto 270
255 call getstr
loopch(iitem)=jchar-long_
loopln(iitem)=long_
looprd(iitem)=irecd
if(type_.ne.'text') goto 250
260 call getlin(flag)
if(buffer(1:1).ne.';') goto 260
call getlin(flag)
goto 250
270 loopct=loopct+1
if(loopct.lt.npakt) goto 300
loop_=.false.
C
C....... Point to the loop data item
C
300 lloop(iname)=lloop(iname)+1
loopi=iloop(iname)
irecd=looprd(loopi)-1
call getlin(flag)
long_=loopln(loopi)
kchar=loopch(loopi)
goto 550
C
C....... Point to the non-loop data item
C
500 irecd=drecd(iname)-1
call getlin(flag)
kchar=dchar(iname)+1
long_=iloop(iname)
loop_=.false.
loopct=0
loopnl=0
C
C....... Place data item into variable string and make number
C
550 type_=dtype(iname)
strg_(1:long_)=buffer(kchar:kchar+long_-1)
if(type_.eq.'numb') call ctonum
if(type_.eq.'text') strg_(1:1)=' '
if(long_.eq.1.and.strg_(1:1).eq.'?') type_='null'
C
1000 return
end
C
C
C
C
C
C
C
C >>>>>> Read the next string from the file
C
subroutine getstr
C
include 'ciftbx.sys'
integer i
character c*1,num*13,flag*4
data num/'0123456789+-.'/
C
100 jchar=jchar+1
if(jchar.le.80) goto 150
C
C....... Read a new line
C
110 call getlin(flag)
type_='fini'
if(flag.eq.'fini') goto 500
C
C....... Test if the new line is the start of a text sequence
C
if(buffer(1:1).ne.';') goto 150
type_='text'
jchar=81
long_=80
goto 500
C
C....... Process this character in the line
C
150 c=buffer(jchar:jchar)
if(c.eq.' ') goto 100
if(c.eq.tab) goto 100
if(c.eq.'#') goto 110
if(c.eq.'''') goto 300
if(c.eq.'"') goto 300
if(c.ne.'_') goto 200
type_='name'
goto 210
C
C....... Test if the start of a number or a character string
C
200 type_='numb'
if(index(num,c).eq.0) type_='char'
210 do 250 i=jchar,80
if(buffer(i:i).eq.' ') goto 400
if(buffer(i:i).eq.tab) goto 400
250 continue
i=81
goto 400
C
C....... Span quoted character string
C
300 type_='char'
jchar=jchar+1
do 320 i=jchar,80
if(buffer(i:i).eq.c) goto 400
320 continue
call err('Quoted string not closed')
C
C....... Store the string for the getter
C
400 long_=i-jchar
strg_(1:long_)=buffer(jchar:i-1)
jchar=i
Cdbg if(jchar.lt.0) write(6,'(" i ",i5)') jchar
if(type_.ne.'char') goto 500
if(strg_(1:5).eq.'data_') type_='data'
if(strg_(1:5).eq.'loop_') type_='loop'
C
500 return
end
C
C
C
C
C
C
C >>>>>> Convert a character string into a number and its esd
C
C number string -xxxx.xxxx+xxx(x)
C component count CCNT 11111222223333444
C
subroutine ctonum
C
include 'ciftbx.sys'
character test*15,c*1
integer*4 m,nchar
integer*4 ccnt,mant,expn,msin,esin,ndec
real numb,sdev
data test /'0123456789+.-()'/
C
numbtb=0.
sdevtb=-1.
numb=1.
sdev=0.
ccnt=0
mant=0
expn=0.
msin=+1
esin=+1
ndec=0
type_='char'
C
C....... Loop over the string and identify components
C
do 400 nchar=1,long_
C
c=strg_(nchar:nchar)
m=index(test,c)
if(m.eq.0) goto 500
if(m.gt.10) goto 300
C
C....... Process the digits
C
if(ccnt.eq.0) ccnt=1
if(ccnt.eq.2) ndec=ndec+1
if(ccnt.gt.2) goto 220
mant=mant*10+m-1
goto 400
220 if(ccnt.gt.3) goto 240
expn=expn*10+m-1
goto 400
240 sdev=sdev*10.+float(m-1)
sdevtb=1.
goto 400
C
C....... Process the characters . + - ( ) E D
C
300 if(c.ne.'.') goto 320
if(ccnt.gt.1) goto 500
ccnt=2
goto 400
C
320 if(c.ne.'(') goto 340
ccnt=4
goto 400
C
340 if(c.eq.'E') m=10
if(c.eq.'D') m=10
if(ccnt.eq.3) goto 500
if(ccnt.gt.0) goto 360
ccnt=1
msin=12-m
goto 400
360 ccnt=3
esin=12-m
C
400 continue
C
C....... String parsed; construct the numbers
C
expn=expn*esin-ndec
if(abs(expn).gt.21) expn=sign(21,expn)
if(expn.lt.0) numb=1./10.**abs(expn)
if(expn.gt.0) numb=10.**expn
if(sdevtb.gt.0.0) sdevtb=numb*sdev
numbtb=numb*float(mant*msin)
type_='numb'
C
500 return
end
C
C
C
C
C
C
C >>>>>> Read a new line from the direct access file
C
subroutine getlin(flag)
C
include 'ciftbx.sys'
character flag*4
C
irecd=irecd+1
if(irecd.eq.jrecd) goto 200
if(irecd.le.lrecd) goto 100
flag='fini'
goto 200
100 read(dirdev,'(a)',rec=irecd) buffer
jchar=1
jrecd=irecd
flag=' '
200 return
end
C
C
C
C
C
C
C >>>>>> Write error message and exit.
C
subroutine err(mess)
C
include 'ciftbx.sys'
character mess*(*)
C
write(errdev,'(5a,i5)') ' ciftbx error in ',
* file_(1:longf_),' data_',bloc_,' line',irecd
write(errdev,'(1X,a)') mess
stop
end
C
C
C
C
C >>>>>> Create a named file.
C
function pfile_(fname)
C
include 'ciftbx.sys'
logical pfile_,test
integer i
character fname*(*)
C
C....... Test if a file by this name is already open.
C
if(pfilef.eq.'yes') call close_
pfilef='no '
file_=fname
do 120 i=1,80
if(file_(i:i).eq.' ') goto 140
120 continue
140 inquire(file=file_(1:i-1),exist=test)
pfile_=.false.
if(test) goto 200
C
C....... Open up a new CIF
C
open(unit=outdev,file=fname,status='NEW',access='SEQUENTIAL',
* form='FORMATTED')
pfile_=.true.
pfilef='yes'
nbloc=0
200 return
end
C
C
C
C
C
C >>>>>> Store a data block command in the CIF
C
function pdata_(name)
C
include 'ciftbx.sys'
logical pdata_
character name*(*),temp*32
character dbloc(100)*32
integer i
C
if(ploopn.gt.0) call eoloop
if(ptextf.eq.'yes') call eotext
C
C....... Check for duplicate data name
C
temp=name
pdata_=.false.
do 120 i=1,nbloc
if(temp.eq.dbloc(i)) goto 200
120 continue
C
C....... Save block name and put data_ statement
C
nbloc=nbloc+1
if(nbloc.le.100) dbloc(nbloc)=temp
pchar=81
temp='data_'//name
call putstr(temp)
pchar=81
call putstr(' ')
pdata_=.true.
C
200 return
end
C
C
C
C
C
C
C >>>>>> Put a number into the CIF, perhaps with an esd appended
C
function pnumb_(name,numb,sdev)
C
include 'ciftbx.sys'
logical pnumb_,flag
character name*(*),temp*32
real numb,sdev
C
pnumb_=.true.
flag =.true.
temp=name
if(ptextf.eq.'yes') call eotext
C
if(name(1:1).eq.' ') goto 120
if(vcheck.eq.'no ') goto 100
call dcheck(temp,'numb',flag)
pnumb_=flag
100 if(ploopn.gt.0) call eoloop
pchar=81
call putstr(temp)
pchar=35
C
120 ploopf='no '
call putnum(numb,sdev)
if(flag) goto 150
pchar=60
call putstr('#< not in dictionary')
C
150 return
end
C
C
C
C
C
C
C >>>>>> Put a character string into the CIF.
C
function pchar_(name,string)
C
include 'ciftbx.sys'
logical pchar_,flag
character name*(*),temp*32,string*(*)
character line*80,strg*80
integer i,j
C
pchar_=.true.
flag =.true.
temp=name
if(ptextf.eq.'yes') call eotext
C
if(name(1:1).eq.' ') goto 110
if(vcheck.eq.'no ') goto 100
call dcheck(temp,'numb',flag)
pchar_=flag
100 if(ploopn.gt.0) call eoloop
pchar=81
call putstr(temp)
pchar=35
C
110 ploopf='no '
line=string
do 120 i=80,2,-1
if(line(i:i).ne.' ') goto 130
120 continue
130 do 140 j=i,1,-1
if(line(j:j).eq.' ') goto 150
140 continue
strg=line(1:i)
goto 200
150 do 160 j=1,i
if(line(j:j).eq.'''')goto 170
160 continue
strg=''''//line(1:i)//''''
goto 200
170 strg='"'//line(1:i)//'"'
C
200 call putstr(strg)
if(flag) goto 250
pchar=60
call putstr('#< not in dictionary')
250 return
end
C
C
C
C
C
C
C >>>>>> Put a text sequence into the CIF.
C
function ptext_(name,string)
C
include 'ciftbx.sys'
logical ptext_,flag
character name*(*),temp*32,string*(*),store*32
data store/' '/
C
ptext_=.true.
flag =.true.
ploopf='no '
temp=name
if(ptextf.eq.'no ') goto 100
if(temp.eq.store) goto 150
call eotext
C
100 if(name(1:1).ne.' ') goto 110
if(ptextf.eq.'yes') goto 150
goto 130
C
110 if(ploopn.gt.0) call eoloop
if(vcheck.eq.'no ') goto 120
call dcheck(name,'char',flag)
ptext_=flag
120 pchar=81
call putstr(temp)
if(flag) goto 130
pchar=60
call putstr('#< not in dictionary')
130 pchar=81
call putstr(' ')
ptextf='yes'
store=temp
write(outdev,'(a)') ';'
150 write(outdev,'(a)') string
return
end
C
C
C
C
C
C
C >>>>>> Put a loop_ data name into the CIF.
C
function ploop_(name)
C
include 'ciftbx.sys'
logical ploop_,flag
character name*(*),temp*32
C
ploop_=.true.
flag =.true.
if(ptextf.eq.'yes') call eotext
if(name(1:1).eq.' ') goto 150
C
temp=' '//name
if(ploopf.eq.'no ') call eoloop
if(vcheck.eq.'no ') goto 100
call dcheck(name,' ',flag)
ploop_=flag
100 if(ploopn.gt.0) goto 120
ploopf='yes'
pchar=81
call putstr(' ')
pchar=81
call putstr('loop_')
pchar=81
120 call putstr(temp)
if(flag) goto 130
pchar=60
call putstr('#< not in dictionary')
130 pchar=81
ploopn=ploopn+1
C
150 return
end
C
C
C
C
C
C
C >>>>>> Close the CIF
C
subroutine close_
C
include 'ciftbx.sys'
C
if(ptextf.eq.'yes') call eotext
if(ploopn.gt.0) call eoloop
pchar=81
call putstr(' ')
close(outdev)
return
end
C
C
C
C
C
C >>>>>> Put the string into the output CIF buffer
C
subroutine putstr(string)
C
include 'ciftbx.sys'
SAVE
character string*(*),temp*80,obuf*80
integer ichar,i
data ichar /0/
C
temp=string
do 100 i=80,1,-1
if(temp(i:i).ne.' ') goto 110
100 continue
C
C....... Organise the output of loop_ items
C
110 if(i.eq.0) goto 130
if(ploopf.eq.'yes') goto 130
if(ploopn.eq.0) goto 130
ploopc=ploopc+1
if(ploopc.le.ploopn) goto 130
ploopc=1
if(.not.align_) goto 130
pchar=81
C
C....... Is the buffer full and needs flushing?
C
130 if(pchar.lt.ichar) goto 140
if(pchar+i.le.80) goto 150
pchar=1
140 if(ichar.gt.0) write(outdev,'(a)') obuf(1:ichar)
obuf=' '
C
C....... Load the next item into the buffer
C
150 ichar=pchar+i
if(i.eq.0) goto 200
obuf(pchar:ichar)=string(1:i)
pchar=ichar+1
C
200 return
end
C
C
C
C
C
C >>>>>> Convert the number and esd to string nnnn(m)
C
subroutine putnum(numb,sdev)
C
include 'ciftbx.sys'
character string*60,digit*9,temp*20
real numb,sdev
integer i,j
data digit /'123456789'/
C
write(string,'(2f30.10)') numb,sdev
do 120 i=1,30
if(string(i:i).ne.' ') goto 140
120 continue
140 if(sdev.lt.0.0000001) goto 240
C
C....... Numbers with standard deviations
C
do 160 j=31,60
if(index(digit,string(j:j)).gt.0) goto 200
160 continue
200 if(j.lt.50) goto 220
temp=string(i:j-30)//'('//string(j:j)//')'
goto 300
220 temp=string(i:19)//'('//string(j:49)//')'
goto 300
C
C....... Numbers without standard deviations
C
240 do 250 j=21,30
if(string(j:j).ne.'0') goto 260
250 continue
260 if(j.gt.26) goto 280
temp=string(i:26)
goto 300
280 temp=string(i:19)
C
300 call putstr(temp)
return
end
C
C
C
C
C
C >>>>>> Check dictionary for data name validation
C
subroutine dcheck(name,type,flag)
C
include 'ciftbx.sys'
logical flag
character name*(*),temp*32,type*4
integer i
C
flag=.true.
temp=name
do 100 i=1,ndict
if(temp.ne.dicnam(i)) goto 100
if(tcheck.eq.'no ') goto 200
if(type.eq.dictyp(i)) goto 200
goto 150
100 continue
150 flag=.false.
200 continue
return
end
C
C
C
C
C
C >>>>>> End of text string
C
subroutine eotext
C
include 'ciftbx.sys'
C
ptextf='no '
call putstr(';')
pchar=80
return
end
C
C
C
C
C
C >>>>>> End of loop detected; check integrity and tidy up pointers
C
subroutine eoloop
C
include 'ciftbx.sys'
integer i
C
if(ploopn.eq.0) goto 200
if(ploopn.eq.ploopc) goto 200
do 150 i=1,ploopc
150 call putstr('DUMMY')
write(errdev,'(a)')
* ' Missing: missing loop_ items set as DUMMY'
C
200 ploopc=0
ploopn=0
return
end
C
C
C
C
C
C
C >>>>>> Set common default values
C
block data
C
include 'ciftbx.sys'
data cifdev /1/
data outdev /2/
data dirdev /3/
data errdev /6/
data loopct /0/
data nhash /0/
data ndict /0/
data nname /0/
data nbloc /0/
data ploopn /0/
data ploopc /0/
data ploopf /'no '/
data ptextf /'no '/
data pfilef /'no '/
data testfl /'no '/
data vcheck /'no '/
data tcheck /'no '/
data align_ /.true./
data text_ /.false./
data loop_ /.false./
end
C
C
C--------cut here------------------------------------------------------------
C
C
C >>>>>> Common declararations 'ciftbx.sys'
C
C For inclusion in 'ciftbx.f'
C
C
C Flag if test_ last called (yes/no )
character testfl*3
C Name of current data item
character nametb*32
C Tab character for this machine
character tab*1
C Character buffer for reading lines
character buffer*80
C Dictionary validation check
character vcheck*3
C Dictionary data type check
character tcheck*3
C Dictionary being processed flag
character dictfl*3
C Dictionary data names
character dicnam(1000)*32
C Dictionary data types
character dictyp(1000)*4
C Data names in data block
character dname(500)*32
C Data type of data item
character dtype(500)*4
C Flag signalling output CIF open
character pfilef*3
C Flag signalling loop_ being loaded
character ploopf*3
C Flag signalling text being loaded
character ptextf*3
C Record number containing data item
integer drecd(500)
C Character position of item in record
integer dchar(500)
C Loop block number (0 for non-loop)
integer nloop(500)
C Item count in loop packet
integer iloop(500)
C Loop line counter; initially zero
integer lloop(500)
C Number of items per packet in each loop
integer loopni(50)
C Number of packets per loop
integer loopnp(50)
C Number of of items in current loop packet
integer ploopc
C Number of of items in output loop packet
integer ploopn
C Number of current loop block
integer loopnl
C Count of packets in current loop
integer loopct
C Number of data names in hash table
integer nhash
C Number of data names in data block
integer nname
C Current number of data name in block
integer iname
C Number of dictionary names
integer ndict
C Number of records in CIF
integer nrecd
C Record number of requested line
integer irecd
C Record number of current line
integer jrecd
C Last record number of current block
integer lrecd
C Character pointer of current input line
integer jchar
C Character pointer of output CIF line
integer pchar
C Number of data block names stored
integer nbloc
C Device number of input CIF
integer cifdev
C Device number of direct access file
integer dirdev
C Device number of error message file
integer errdev
C Device number of output CIF
integer outdev
C Returned number
real numbtb
C Returned standard deviation
real sdevtb
C
common/tbxc/ buffer,dname,dtype,tab,dicnam,dictyp,dictfl,
* nametb,testfl,vcheck,tcheck,
* pfilef,ploopf,ptextf
C
common/tbxi/ nrecd,drecd,irecd,lrecd,dchar,ndict,outdev,
* nloop,iloop,lloop,loopct,loopni,loopnp,loopnl,
* nname,nhash,cifdev,dirdev,errdev,jchar,pchar,
* iname,ploopn,ploopc,nbloc,jrecd
C
common/tbxr/ numbtb,sdevtb
C
C
C
C Align loop active flag (true/false)
logical align_
C Text active flag (true/false)
logical text_
C Loop active flag (true/false)
logical loop_
C Length of current data item in strg_
integer long_
C Loop block number of current item
integer list_
C Length of current filename in file_
integer longf_
C Name of current data block
character bloc_*32
C Character image of current data item
character strg_*80
C File name of current CIF
character file_*80
C Data item type
character type_*4
C
common/tbuc/ strg_,bloc_,file_,type_
C
common/tbui/ list_,long_,longf_
C
common/tbul/ loop_,text_,align_
C
C
C--------cut here------------------------------------------------------------
C
C
C >>>>>> Common declararations 'ciftbx.cmn'
C
C For inclusion in user applications
C
C
C Logical function init_
logical init_
C Logical function dict_
logical dict_
C Logical function open_
logical open_
C Logical function data_
logical data_
C Logical function test_
logical test_
C Logical function name_
logical name_
C Logical function numb_
logical numb_
C Logical function char_
logical char_
C Logical function pfile_
logical pfile_
C Logical function pdata_
logical pdata_
C Logical function pchar_
logical pchar_
C Logical function pnumb_
logical pnumb_
C Logical function ptext_
logical ptext_
C Logical function ploop_
logical ploop_
C Align loop active flag (true/false)
logical align_
C Text active flag (true/false)
logical text_
C Loop active flag (true/false)
logical loop_
C Length of current data item in strg_
integer long_
C Loop block number of current item
integer list_
C Length of current filename in file_
integer longf_
C Name of current data block
character bloc_*32
C Character image of current data item
character strg_*80
C File name of current CIF
character file_*80
C Data item type
character type_*4
C
common/tbuc/ strg_,bloc_,file_,type_
C
common/tbui/ list_,long_,longf_
C
common/tbul/ loop_,text_,align_
C
C
C--------cut here-------------------------------------------------------------
C
C
C
C CIF Tool Box Application 'tbx_ex.f'
C ------------------------
C Version: July 17 1994
C
C
C This file contains four separate examples of how to apply the
C the CIF tool box 'CIFtbx'. These are simple software tools for
C accessing and creating data in CIF format. A description of the
C CIFtbx functions and user-accessible system variables is given
C at the start of the tool box source file 'ciftbx.f'.
C
C A full description of a CIF is given in the paper Hall, Allen
C and Brown (1991) Acta Cryst. A47 pp655-685.
C
C Communications about the application of the CIF tool box may be
C directed to: Syd Hall fx:61(9)3801118 em:syd@crystal.uwa.edu.au
C
C The examples shown below extract data from the supplied CIF
C 'test.cif'. The third example reads a list of data requests from
C a supplied file 'test.req'. As distributed, 'tbx_ex.f' attaches
C 'test.cif' to device 1, a scratch direct access file to device 3
C and the error message file to device 6 (i.e. stdout). The fourth
C example creates a new CIF called 'test.new'. This output file is
C attached to device 2. On some machines these may not be suitable
C device numbers and they may be changed within the application
C with the init_ call.
C
C The print file for this application is assumed to be stdout (i.e.
C device number 6). The dictionary checking option dict_ has been
C invoked in these examples. In this case the standard Core
C dictionary file 'cifdic.c91' has been used [note that other
C dictionaries may be added by repetitive invocation of dict_]. If
C it is not present a warning message will be issued and the run
C will proceed without data name validation.
C
C
C The user should note that most CIFtbx tools are logical functions.
C If their invocation succeeds they are returned with value .true.
C otherwise .false. This means that for each invocation the program
C can take appropriate action. For example if a request to open_ a
C specific CIF fails, the program can exit, or try another CIF. The
C same philosophy applies to data_ and all CIFtbx functions. However,
C if a function discovers a logical construction error in the CIF,
C the whole process will stop with an error message.
C
C
C
C Note the following requirements for any CIFtbx application.
C
C....... The tool box fortran source file 'ciftbx.f' must be included
C once in the application source (as shown below), OR the object
C file 'ciftbx.o' must be included in the link process.
C
include 'ciftbx.f'
C
C
C....... The tool box common variable file 'ciftbx.cmn' must be present
C at the start of EACH routine using the CIFtbx functions.
C
include 'ciftbx.cmn'
C
C
C
logical f1,f2,f3
character*32 name
character*80 line
character*4 label(6)
character*26 alpha
real cela,celb,celc,siga,sigb,sigc
real x,y,z,u,sx,sy,sz,su
real numb,sdev,dum
real xf(6),yf(6),zf(6),uij(6,6)
integer i,j,nsite
data alpha /'abcdefghijklmnopqrstuvwxyz'/
data cela,celb,celc,siga,sigb,sigc/6*0./
data x,y,z,u,sx,sy,sz,su/8*0./
data xf,yf,zf,uij/54*0./
C
C
C
C........................... Example 1 .......................................
C
C
C This example illustrates how to extract non-loop and loop items.
C Note carefully how the logical functions numb_ and char_ signal if
C the request has been successful or not. Note how the logical variables
C text_ and loop_ are used to control the text lines and the data loops.
C
C
C
C....... Assign the CIFtbx files
C
f1 = init_( 1, 2, 3, 6 )
C
C....... Request dictionary validation check
C
if(dict_('cifdic.c91','valid')) goto 100
write(6,'(/a/)') ' Requested Core dictionary not present'
C
C....... Open the CIF to be accessed
C
100 name='test.cif'
write(6,'(/2a/)') ' Read data from CIF ',name
if(open_(name)) goto 120
write(6,'(a///)') ' >>>>>>>>> CIF cannot be opened'
stop
C
C....... Assign the data block to be accessed
C
120 if(data_(' ')) goto 130
write(6,'(/a/)') ' >>>>>>> No data_ statement found'
stop
130 write(6,'(/a,a/)') ' Access items in data block ',bloc_
C
C
C....... Extract some cell dimensions; test all is OK
C
f1 = numb_('_cell_length_a', cela, siga)
f2 = numb_('_cell_length_b', celb, sigb)
f3 = numb_('_cell_length_c', celc, sigc)
if(.not.(f1.and.f2.and.f3))
* write(6,'(a)') ' Cell dimension(s) missing!'
write(6,'(/a,3f10.4)') ' Cell ',cela,celb,celc
write(6,'(a,3f10.4/)') ' ',siga,sigb,sigc
C
C
C....... Extract space group notation (expected char string)
C
f1 = char_('_symmetry_space_group_name_Hall', name)
write(6,'(a,a/)') ' Space group ',name(1:long_)
C
C
C....... Get the next name in the CIF and print it out
C
f1 = name_(name)
write(6,'(a,a/)') ' Next data name in CIF is ',name
C
C
C....... List the audit record (possible text line sequence)
C
write(6,'(a/)') ' Audit record'
140 f1 = char_('_audit_update_record', line)
write(6,'(a)') line
if(text_) goto 140
C
C
C....... Extract atom site data in a loop
C
write(6,'(/a/)') ' Atom sites'
160 f1 = char_('_atom_site_label', name)
f2 = numb_('_atom_site_fract_x', x, sx)
f2 = numb_('_atom_site_fract_y', y, sy)
f2 = numb_('_atom_site_fract_z', z, sz)
f3 = numb_('_atom_site_U_iso_or_equiv', u, su)
write(6,'(1x,a4,8f8.4)') name,x,y,z,u,sx,sy,sz,su
if(loop_) goto 160
C
C
C
C
C........................... Example 2 .......................................
C
C
C
C In this example two separate data blocks are accessed. The first
C contains looped publication authors and text addresses. The second
C part of this example shows how data from two different loops may
C be merged. Remember that data items from different loops may NOT
C be accessed simultaneously, as this causes the CIFtbx loop counters
C to be reset to the start of the loop (see Example 3).
C
C
C
C....... List the author addresses from publication data block
C
if(data_('publication'))
* write(6,'(//a,a/)') ' Access items in data block ',bloc_
write(6,'(/a)') ' Author list'
C
210 f1 = char_('_publ_author_name', line)
write(6,'(/1x,a)') line(1:long_)
C
220 f1 = char_('_publ_author_address', line)
if(line(1:10).eq.' ') goto 230
write(6,'(1x,a)') line(1:50)
230 if(text_) goto 220
if(loop_) goto 210
C
C
C....... Read and store the atom site data from other data block
C
f1 = data_('mumbo_jumbo')
write(6,'(///a,a/)') ' Access items in data block ',bloc_
C
nsite = 0
240 nsite = nsite+1
f1 = char_('_atom_site_label', label(nsite))
f2 = numb_('_atom_site_fract_x', xf(nsite), sx)
f2 = numb_('_atom_site_fract_y', yf(nsite), sy)
f2 = numb_('_atom_site_fract_z', zf(nsite), sz)
do 250 i=1,6
250 uij(nsite,i)=0.0
if(loop_) goto 240
C
C....... Read the Uij loop and store in the site list
C
260 f1 = char_('_atom_site_aniso_label', name)
do 270 i=1,nsite
if(label(i).eq.name) goto 280
270 continue
write(6,'(a)') ' Label mismatch between atom lists'
280 f1 = numb_('_atom_site_aniso_U_11', uij(i,1), dum)
f1 = numb_('_atom_site_aniso_U_22', uij(i,2), dum)
f1 = numb_('_atom_site_aniso_U_33', uij(i,3), dum)
f1 = numb_('_atom_site_aniso_U_12', uij(i,4), dum)
f1 = numb_('_atom_site_aniso_U_13', uij(i,5), dum)
f1 = numb_('_atom_site_aniso_U_23', uij(i,6), dum)
if(loop_) goto 260
C
C....... List the atom site data
C
write(6,'(/a/)') ' Atom coordinates and Uij'
do 290 i=1,nsite
if(uij(i,1).gt.0.0001) goto 285
write(6,'(1x,a,3f8.4)') label(i),xf(i),yf(i),zf(i)
goto 290
285 write(6,'(1x,a,9f8.4)') label(i),xf(i),yf(i),zf(i),
* (uij(i,j),j=1,6)
290 continue
C
C
C
C
C........................... Example 3 .......................................
C
C
C This example serves to illustrate how a general list of data requests
C may be handled. The logical function test_ is used to identify the
C nature of the requested data item, and then numb_ and char_ are invoked
C when applicable. The supplied list of requests on 'test.req' is not of
C particular significance. They are intentionally jumbled up to show what
C happens if a non-loop item is called within a loop [WARNING: CIFtbx
C interprets this as a signal to end the loop and the next call for a loop
C item will extract data from its first packet! Look at the output listing
C to see what happens.]
C
C
C
C....... Loop over the data request file
C
open(unit=8,file='test.req',status='old')
300 read(8,'(a)',end=400) name
C
f1 = test_(name)
write(6,'(/a,3x,a,2i5)') name,type_,long_,list_
C
if(type_.ne.'numb') goto 320
f1 = numb_(name, numb, sdev)
write(6,'(2f10.4)') numb,sdev
goto 300
C
320 if(type_.ne.'char') goto 340
f1 = char_(name, line)
write(6,'(a)') line(1:long_)
goto 300
C
340 if(type_.ne.'text') goto 300
350 f1 = char_(name, line)
write(6,'(a)') line
if(text_) goto 350
goto 300
C
C
C
C
C........................... Example 4 .......................................
C
C
C
C In this example a new CIF is created. Note that it will not overwrite
C an existing CIF of the same name. Note also that reading and existing
C CIF and writing a new CIF is possible at the same time, so that it is
C feasible to use these tools to update or modify and existing CIF.
C
C
C
C....... Open a new CIF
C
400 if(pfile_('test.new')) goto 450
write(6,'(//a/)') ' Output CIF by this name exists already!'
goto 500
C
C....... Insert a data block code
C
450 f1 = pdata_('whoops_a_daisy')
C
C....... Enter various single data items to show how
C
f1 = pchar_('_audit_creation_method','using CIFtbx')
f1 = pchar_('_audit_creation_extra1','using_CIFtbx')
f1 = pchar_('_audit_creation_extra2',"Terry O'Connell")
f1 = pchar_('_audit_creation_extra3','Terry O"Connell')
C
f1 = ptext_('_audit_creation_record',' Text data may be ')
f1 = ptext_('_audit_creation_record',' entered like this')
f1 = ptext_('_audit_creation_record',' or in a loop.')
C
f1 = pnumb_('_cell_measurement_temperature', 293., 0.)
f1 = pnumb_('_cell_volume', 1759.0, 13.)
f1 = pnumb_('_cell_length_junk', 8.75353553524313,0.)
f1 = pnumb_('_cell_length_c', 19.737, .003)
C
C....... Enter some looped data
C
f1 = ploop_('_atom_type_symbol')
f1 = ploop_('_atom_type_oxidation_number')
f1 = ploop_('_atom_type_number_in_cell')
do 470 i=1,10
f1 = pchar_(' ',alpha(1:i))
f1 = pnumb_(' ',float(i),float(i)*0.1)
470 f1 = pnumb_(' ',float(i)*8.64523,0.)
C
C....... Do it again but as contiguous data with text data
C
f1 = ploop_('_atom_type_symbol')
f1 = ploop_('_atom_type_oxidation_number')
f1 = ploop_('_some_silly_text')
do 480 i=1,3
f1 = pchar_(' ',alpha(1:i))
f1 = pnumb_(' ',float(i),float(i)*0.1)
480 f1 = ptext_(' ',' Hi Ho the diddly oh!')
C
500 call close_
stop
end
C
C
C--------cut here------------------------------------------------------------
C
data_mumbo_jumbo
_audit_creation_date 91-03-20
_audit_creation_method from_xtal_archive_file_using_CIFIO
_audit_update_record
; 91-04-09 text and data added by Tony Willis.
91-04-15 rec'd by co-editor with diagram as manuscript HL7.
91-04-17 adjustments based on first referees report.
91-04-18 adjustments based on second referee's report.
;
_chemical_name_systematic
trans-3-Benzoyl-2-(tert-butyl)-4-(iso-butyl)-1,3-oxazolidin-5-one
_chemical_formula_moiety 'C18 H25 N O3'
_chemical_formula_sum 'C18 H25 N O3'
_chemical_formula_weight 303.40
_chemical_melting_point ?
####_cell_length_a 5.959(1)
_cell_length_b 14.956(1)
_cell_length_c 19.737(3)
_cell_angle_alpha 90
_cell_angle_beta 90
_cell_angle_gamma 90
_cell_volume 1759.0(3)
_cell_formula_units_Z 4
_cell_measurement_temperature 293
_cell_measurement_reflns_used 25
_cell_measurement_theta_min 25
_cell_measurement_theta_max 31
_symmetry_cell_setting orthorhombic
_symmetry_space_group_name_H-M 'P 21 21 21'
_symmetry_space_group_name_Hall P_2ac_2ab
loop_
_atom_type_symbol
_atom_type_oxidation_number
_atom_type_number_in_cell
_atom_type_scat_dispersion_REAL #<< capitals to test case insensitivity
_atom_type_scat_dispersion_imag
_atom_type_scat_source
S 0 6 .319 .557 Int_Tab_Vol_III_p202_Tab._3.3.1a
O 0 6 .047 .032 Cromer,D.T._&_Mann,J.B._1968_AC_A24,321.
C 0 20 .017 .009 Cromer,D.T._&_Mann,J.B._1968_AC_A24,321.
RU 0 1 -.105 3.296 Cromer,D.T._&_Mann,J.B._1968_AC_A24,321.
loop_
_atom_site_label
_atom_site_fract_x
_atom_site_fract_y
_atom_site_fract_z
_atom_site_U_iso_or_equiv
_atom_site_thermal_displace_type
_atom_site_calc_flag
_atom_site_calc_attached_atom
_atom_site_type_symbol
s .20200 .79800 .91667 .030(3) Uij ? ? s
o .49800 .49800 .66667 .02520 Uiso ? ? o
c1 .48800 .09600 .03800 .03170 Uiso ? ? c
loop_
_atom_site_aniso_label
_atom_site_aniso_U_11
_atom_site_aniso_U_22
_atom_site_aniso_U_33
_atom_site_aniso_U_12
_atom_site_aniso_U_13
_atom_site_aniso_U_23
_atom_site_aniso_type_symbol
s .035(4) .025(3) .025(3) .013(1) .00000 .00000 s
loop_ _blat1 _blat2 1 2 3 4 5 6 a b c d 7 8 9 0
data_publication
loop_
_publ_author_name #ActaC
_publ_author_address #ActaC
'Furber, Mark'
;
Research School of Chemistry
Australian National University
GPO Box 4
Canberra, A.C.T.
Australia 2601
;
'Mander, Lewis N.'
;
Research School of Chemistry
Australian National University
GPO Box 4
Canberra, A.C.T.
Australia 2601
;
'Patrick, Graham L.'
;
Research School of Chemistry
Australian National University
GPO Box 4
Canberra, A.C.T.
Australia 2601
;
'Willis, Anthony C.'
;
Research School of Chemistry
Australian National University
GPO Box 4
Canberra, A.C.T.
Australia 2601
;
#----------------------------cut here-------------------------------------------
_audit_creation_date
_audit_creation_method
_audit_update_record
_chemical_name_systematic
_chemical_formula_moiety
_chemical_formula_sum
_chemical_formula_weight
_chemical_melting_point
_cell_length_a
_cell_length_b
_cell_length_c
_cell_angle_alpha
_cell_angle_beta
_cell_angle_gamma
_cell_volume
_cell_formula_units_Z
_cell_measurement_temperature
_cell_measurement_reflns_used
_cell_measurement_theta_min
_cell_measurement_theta_max
_blat2
_blat1
_blat2
_blat1
_blat2
_blat1
_blat2
_blat1
_blat2
_blat1
_symmetry_cell_setting
_symmetry_space_group_name_H-M
_symmetry_space_group_name_Hall
_atom_type_symbol
_atom_type_oxidation_number
_atom_type_number_in_cell
_atom_type_scat_dispersion_real
_atom_type_scat_dispersion_imag
_atom_type_scat_source
_atom_type_symbol
_atom_type_oxidation_number
_atom_type_number_in_cell
_atom_type_number_in_cell
_atom_type_oxidation_number
_atom_type_scat_dispersion_real
_atom_site_label
_atom_site_fract_x
_atom_site_fract_y
_atom_site_fract_z
_atom_site_U_iso_or_equiv
_atom_site_thermal_displace_type
_atom_site_calc_flag
_atom_site_calc_attached_atom
_atom_site_type_symbol
_atom_site_type_symbol
_atom_site_type_symbol
_atom_site_type_symbol
_rubish_here
_atom_site_type_symbol
_atom_site_type_symbol
_atom_site_type_symbol
_symmetry_space_group_name_Hall
_atom_site_type_symbol
_atom_site_type_symbol
_atom_site_type_symbol
_atom_site_type_symbol
_atom_site_aniso_label
_atom_site_aniso_U_11
_atom_site_aniso_U_22
_atom_site_aniso_U_33
_atom_site_aniso_U_12
_atom_site_aniso_U_13
_atom_site_aniso_U_23
_atom_site_aniso_type_symbol
_atom_site_aniso_U_12
_atom_site_aniso_U_12
_atom_site_aniso_U_12
#----------------------------cut here-------------------------------------------
Read data from CIF test.cif
Warning: data name _blat1 not in dictionary!
Warning: data name _blat2 not in dictionary!
Access items in data block mumbo_jumbo
Cell dimension(s) missing!
Cell 0.0000 14.9560 19.7370
0.0000 0.0010 0.0030
Space group P_2ac_2ab
Next data name in CIF is _atom_type_symbol
Audit record
91-04-09 text and data added by Tony Willis.
91-04-15 rec'd by co-editor with diagram as manuscript HL7.
91-04-17 adjustments based on first referees report.
91-04-18 adjustments based on second referee's report.
Atom sites
s 0.2020 0.7980 0.9167 0.0300 0.0000 0.0000 0.0000 0.0030
o 0.4980 0.4980 0.6667 0.0252 0.0000 0.0000 0.0000 0.0030
c1 0.4880 0.0960 0.0380 0.0317 0.0000 0.0000 0.0000 0.0030
Access items in data block publication
Author list
Furber, Mark
Research School of Chemistry
Australian National University
GPO Box 4
Canberra, A.C.T.
Australia 2601
Mander, Lewis N.
Research School of Chemistry
Australian National University
GPO Box 4
Canberra, A.C.T.
Australia 2601
Patrick, Graham L.
Research School of Chemistry
Australian National University
GPO Box 4
Canberra, A.C.T.
Australia 2601
Willis, Anthony C.
Research School of Chemistry
Australian National University
GPO Box 4
Canberra, A.C.T.
Australia 2601
Warning: data name _blat1 not in dictionary!
Warning: data name _blat2 not in dictionary!
Access items in data block mumbo_jumbo
Atom coordinates and Uij
s 0.2020 0.7980 0.9167 0.0350 0.0250 0.0250 0.0130 0.0000 0.0000
o 0.4980 0.4980 0.6667
c1 0.4880 0.0960 0.0380
_audit_creation_date char 8 0
91-03-20
_audit_creation_method char 34 0
from_xtal_archive_file_using_CIFIO
_audit_update_record text 80 0
91-04-09 text and data added by Tony Willis.
91-04-15 rec'd by co-editor with diagram as manuscript HL7.
91-04-17 adjustments based on first referees report.
91-04-18 adjustments based on second referee's report.
_chemical_name_systematic char 65 0
trans-3-Benzoyl-2-(tert-butyl)-4-(iso-butyl)-1,3-oxazolidin-5-one
_chemical_formula_moiety char 12 0
C18 H25 N O3
_chemical_formula_sum char 12 0
C18 H25 N O3
_chemical_formula_weight numb 6 0
303.4000 0.0000
_chemical_melting_point null 1 0
_cell_length_a null 1 0
_cell_length_b numb 9 0
14.9560 0.0010
_cell_length_c numb 9 0
19.7370 0.0030
_cell_angle_alpha numb 2 0
90.0000 0.0030
_cell_angle_beta numb 2 0
90.0000 0.0030
_cell_angle_gamma numb 2 0
90.0000 0.0030
_cell_volume numb 9 0
1759.0000 0.3000
_cell_formula_units_Z numb 1 0
4.0000 0.3000
_cell_measurement_temperature numb 3 0
293.0000 0.3000
_cell_measurement_reflns_used numb 2 0
25.0000 0.3000
_cell_measurement_theta_min numb 2 0
25.0000 0.3000
_cell_measurement_theta_max numb 2 0
31.0000 0.3000
null 1 0
_blat2 numb 1 4
2.0000 0.3000
_blat1 numb 1 4
1.0000 0.3000
_blat2 numb 1 4
4.0000 0.3000
_blat1 numb 1 4
3.0000 0.3000
_blat2 numb 1 4
6.0000 0.3000
_blat1 numb 1 4
5.0000 0.3000
_blat2 char 1 4
b
_blat1 char 1 4
a
_blat2 char 1 4
d
_blat1 char 1 4
c
null 1 4
_symmetry_cell_setting char 12 0
orthorhombic
_symmetry_space_group_name_H-M char 10 0
P 21 21 21
_symmetry_space_group_name_Hall char 9 0
P_2ac_2ab
null 1 0
_atom_type_symbol char 1 1
S
_atom_type_oxidation_number numb 1 1
0.0000 0.3000
_atom_type_number_in_cell numb 1 1
6.0000 0.3000
_atom_type_scat_dispersion_real numb 4 1
0.3190 0.3000
_atom_type_scat_dispersion_imag numb 4 1
0.5570 0.3000
_atom_type_scat_source char 32 1
Int_Tab_Vol_III_p202_Tab._3.3.1a
_atom_type_symbol char 1 1
O
_atom_type_oxidation_number numb 1 1
0.0000 0.3000
_atom_type_number_in_cell numb 1 1
6.0000 0.3000
_atom_type_number_in_cell numb 1 1
6.0000 0.3000
_atom_type_oxidation_number numb 1 1
0.0000 0.3000
_atom_type_scat_dispersion_real numb 4 1
0.0170 0.3000
null 1 1
null 1 1
_atom_site_label char 1 2
s
_atom_site_fract_x numb 6 2
0.2020 0.3000
_atom_site_fract_y numb 6 2
0.7980 0.3000
_atom_site_fract_z numb 6 2
0.9167 0.3000
_atom_site_U_iso_or_equiv numb 7 2
0.0300 0.0030
_atom_site_thermal_displace_type char 3 2
Uij
_atom_site_calc_flag null 1 2
_atom_site_calc_attached_atom null 1 2
_atom_site_type_symbol char 1 2
s
_atom_site_type_symbol char 1 2
s
_atom_site_type_symbol char 1 2
s
_atom_site_type_symbol char 1 2
s
_rubish_here null 1 2
_atom_site_type_symbol char 1 2
o
_atom_site_type_symbol char 1 2
o
_atom_site_type_symbol char 1 2
o
_symmetry_space_group_name_Hall char 9 0
P_2ac_2ab
_atom_site_type_symbol char 1 2
s
_atom_site_type_symbol char 1 2
s
_atom_site_type_symbol char 1 2
s
_atom_site_type_symbol char 1 2
s
null 1 2
_atom_site_aniso_label char 1 3
s
_atom_site_aniso_U_11 numb 7 3
0.0350 0.0040
_atom_site_aniso_U_22 numb 7 3
0.0250 0.0030
_atom_site_aniso_U_33 numb 7 3
0.0250 0.0030
_atom_site_aniso_U_12 numb 7 3
0.0130 0.0010
_atom_site_aniso_U_13 numb 6 3
0.0000 0.0010
_atom_site_aniso_U_23 numb 6 3
0.0000 0.0010
_atom_site_aniso_type_symbol char 1 3
s
_atom_site_aniso_U_12 numb 7 3
0.0130 0.0010
_atom_site_aniso_U_12 numb 7 3
0.0130 0.0010
_atom_site_aniso_U_12 numb 7 3
0.0130 0.0010
#------------------------------cut here---------------------------------------
data_whoops_a_daisy
_audit_creation_method 'using CIFtbx'
_audit_creation_extra1 using_CIFtbx #< not in dictionary
_audit_creation_extra2 "Terry O'Connell" #< not in dictionary
_audit_creation_extra3 'Terry O"Connell' #< not in dictionary
_audit_creation_record #< not in dictionary
;
Text data may be
entered like this
or in a loop.
;
_cell_measurement_temperature 293
_cell_volume 1759(13)
_cell_length_junk 8.753535 #< not in dictionary
_cell_length_c 19.736(3)
loop_
_atom_type_symbol
_atom_type_oxidation_number
_atom_type_number_in_cell
a 1.0(1) 8.645230
ab 2.0(2) 17.290460
abc 3.0(3) 25.935691
abcd 4.0(4) 34.580921
abcde 5.0(5) 43.226150
abcdef 6.0(6) 51.871383
abcdefg 7.0(6) 60.516613
abcdefgh 8.0(8) 69.161842
abcdefghi 9.0(9) 77.807075
abcdefghij 10(1) 86.452301
loop_
_atom_type_symbol
_atom_type_oxidation_number
_some_silly_text #< not in dictionary
a 1.0(1)
;
Hi Ho the diddly oh!
;
ab 2.0(2)
;
Hi Ho the diddly oh!
;
abc 3.0(3)
;
Hi Ho the diddly oh!
;
#------------------------------cut here---------------------------------------