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
