Table of Contents

Contents
5 Appendix A: Programming Examples
      5.1 C
            5.1.1 icreate.c
            5.1.2 icopy.c
            5.1.3 record_copy.c
      5.2 FORTRAN
            5.2.1 icreate.f
            5.2.2 icopy.f

5 Appendix A: Programming Examples

5.1 C

5.1.1 icreate.c

This first example simply creates a new IBIS file with a number of different formats. No Reading or Writing is performed.

/**
 **	icreate.c: Creates one  new IBIS file.
 **
 **	Uses: Ported VICAR runtime library,
 **	      IBIS2 subroutine library.
 **/

#include "vicmain_c"
#include "ibisfile.h"

main44()
{
	int outunit,status;
	int out;
	int nc, nr;
	int count, def;
	char org[10];
	char format_buf[20][IFMT_SIZE];
	char *fmt_ptr=(char *)0;
	
	zvparm("cform", format_buf, &count, &def, 20, IFMT_SIZE);
	if (!def && count) fmt_ptr=format_buf;
	zvp("nr", &nr, &def );
  
	/* open the output file, or abort on error */
	
	nc=count;
	nr=10;
	
	zvpone( "org", org, 1, 0 );
	zvunit( &outunit, "out", 1, 0);

	status = IBISFileOpen(outunit,&out,IMODE_WRITE, nc,
				 nr, fmt_ptr, org);
	if (status!=1) IBISSignalU( outunit, status, 1);
	
	/* close up shop */
	
	status = IBISFileClose( out );
	if (status != 1) IBISSignalU( outunit, status, 1);
}

5.1.2 icopy.c

This next example will create a copy of another IBIS file. This is a lot more than it seems, as the two files may have different organizations (by Row, Column, or old format), and may be from different hosts. The data is translated into the native format automatically.

/**
 **	icopy.c: Copies one general new IBIS file to another,
 **	possibly with a change in organization (row/column).
 **
 **	Uses: Ported VICAR runtime library,
 **	      IBIS2 subroutine library.
 **/

#include "vicmain_c"
#include "ibisfile.h"

#ifndef MIN
#define MIN(x,y) (((x) < (y)) ? (x) : (y))
#endif

#define DBUFSIZE 1000
#define IBUFSIZE (DBUFSIZE*sizeof(double))

main44()
{
	int inunit,outunit,status;
	long in, out;
	int nc=1, nr=1, col,colsize=1;
	int row, row_inc, nrow,count;
	char *format, org[10];
	double buffer[IBUFSIZE]; /* needs to be byte-aligned */

	/* open the input IBIS file, abort on error */
	
	zvunit( &inunit, "inp", 1, 0);
	status = IBISFileOpen( inunit, &in, IMODE_READ, 0,0,0,0);
	if (status!=1)  IBISSignalU( inunit, status, 1);
	
	/* get the input row & column counts */
	
	IBISFileGet( in, IFILE_NC, &nc, 1, 1, 0 );
	IBISFileGet( in, IFILE_NR, &nr, 1, 1, 0 );
	
	/* allocate and get the input format string */
	
	format = (char *)malloc( IFMT_SIZE * nc );
	if (!format)
	{
		zvmessage( "unable to allocate format string", 0);
		zabend();
	}
	count = IBISFileGet( in, IFILE_FORMAT,format,1,nc, IFMT_SIZE );
	
	/* open the output file, or abort on error */
	
	zvpone( "org", org, 1, 0 );
	zvunit( &outunit, "out", 1, 0);
	status = IBISFileOpen( outunit, &out, 
			IMODE_WRITE, nc, nr, format,org );
	if (status!=1)  IBISSignalU( outunit, status, 1);
	
	/* 
	 * copy the columns -- Note that this is only efficient
	 * for column-oriented files. In general, use of a record
	 * may be be more efficient.
	 */

	for (col=1; col<=nc; col++)
	{
		/* get the column's translated size */
		IBISColumnGet( in, ICOLUMN_U_SIZE, &colsize, col );
		
		/* Compute # rows that will fit into buffer : */
		row_inc = (IBUFSIZE + colsize  - 1)/colsize ;
		
		for (row = 1; row<=nr; row += row_inc)
		{
			nrow = MIN( nr+1-row , row_inc);
			
			status=IBISColumnRead(in,buffer,col, row, nrow );
			if (status != 1) IBISSignal( in, status );

			status =IBISColumnWrite(out,buffer,col,row,nrow );
			if (status != 1) IBISSignal( in, status );			
		}
	}

	/* close up shop */

	IBISFileClose( in, 0 );
	status = IBISFileClose( out, 0 );
	if (status!=1) IBISSignalU( outunit, status, 1);
}

5.1.3 record_copy.c

This example shows how to use records to copy data from one place in a file to another using records. The file will be open in update mode. Note that we should really check each column format beforehand that it can handle the translation format specified by the 'format' parameter (ie, ASCII and numeric are not mixed). We should also be careful about making sure that the output buffer isn't overlapping with the input buffer (we can do this with IBISRecordSet( 'NR' )).

#include "vicmain_c.h"
#include "ibisfile.h"
main44()
{
	int unit;
	int status,def;
	int ibis;
	int row, inrow,outrow,ncols,cols[20];
	int nc, nr;
	int nrows,recrows;
	int col;
	int inrecord,outrecord;
	int fsize;
	int bufsize;
	char format[20];
	char *buffer;
	
 	status=zvunit( &unit, "inp", 1, 0);
	if (status!=1) zvsignal( unit, status, 1);
 
	/* open the output file, or abort on error */
	
	status = IBISFileOpen(unit, &ibis, IMODE_UPDATE, 0, 0, 0, 0);
	if (status!=1) IBISSignalU( unit, status, 1);

	zvp("inrow", &inrow, &def );   /* starting row to read */
	zvp("nrows", &nrows, &def );   /* number of rows to copy */
	zvp("outrow", &outrow, &def ); /* where to write the rows */
	zvp("format", format, &def );  /* what format to translate */
	zvparm("cols",cols,&ncols,&def,0 ); /* which columns to copy */

	/*
	 *  Create a record with the given rows, format translation
	 *  and also resize the buffer to "recrows" rows.
	 */

	status = IBISRecordOpen(ibis,&inrecord, 0, cols,ncols, format);
	if (status != 1) IBISSignal( ibis, status, 1 );
	status = IBISRecordOpen(ibis,&outrecord,0,cols, ncols, format);
	if (status != 1) IBISSignal( ibis, status, 1 );
	
	status = IBISRecordGet(inrecord,IRECORD_REC_SIZE,&bufsize,1,1);
	if (status != 1) IBISSignal( ibis, status, 1 );	
	status = IBISRecordGet( inrecord,IRECORD_U_SIZE, &fsize, 1, 1 );
	if (status != 1) IBISSignal( ibis, status, 1 );
	buffer = (char *)malloc( bufsize );
	if (!buffer) zabend();

	for (row=0;row<nrows;row++)
	{
		status = IBISRecordRead( inrecord, buffer, inrow+row);
		if (status != 1) IBISSignal( ibis, status, 1);
		
		status = IBISRecordWrite( outrecord, buffer, outrow+row);
		if (status != 1) IBISSignal( ibis, status, 1);
	}
	/* close up shop */
	status = IBISFileClose( ibis, 0 );
	if (status != 1) IBISSignalU( unit, status, 1);
}

5.2 FORTRAN

5.2.1 icreate.f

This program is the FORTRAN equivalent to the "icreate.c" program listed above, and performs the same operations.

C
C	icreate.f: Creates one new IBIS file.
C
C	Uses: Ported VICAR runtime library,
C      IBIS2 subroutine library.
C


	include 'VICMAIN_FOR'

	subroutine main44
	integer outunit,status
	integer  out 
	integer nc, nr
	character*16  org 
	character*5 format_buf(20) 
	integer i 
	include 'ibisfile'  !definitions for IBIS-2

	
C	Set up the format_buf as FULL format
	do i=1,20
		format_buf(i) =  IFMT_FULL
	enddo

C Set IBIS columns 7, 8, and 9 as formats half, double and A200

	format_buf(8) =  IFMT_HALF
	format_buf(9) =  IFMT_DOUB
	format_buf(10) = 'a200'    !dont use IFMT_ASCII !!!

C   Determine from the user-arg if 'row' or 'column' oriented files
C   are wanted (default=column)

	call xvpone( 'org', org, 1, 0) 

C   Get the VICAR file unit to pass into ibis_file_open
	call xvunit( outunit, 'out', 1, status, ' ') 

C   Create the output file for writing with 20 columns and 10 rows.
C     This call returns in 'out' the IBIS file handle

	nc=20   !Number of columns
	nr=10 	!Number of rows

	call ibis_file_open( outunit, out, IMODE_WRITE, nc, nr,
     +     format_buf, org, status)
     
	if (status.ne.1) then
		!print error message using VICAR unit and abort
		call ibis_signal_u( outunit, status, 1) 
	endif

C  If you want to initialize the columns, you would use
C  ibis_column_write or ibis_row_write at this point.
C   close the file -- important to do, as this updates the VICAR label 

	call ibis_file_close( out, ' ', status ) 

	return
	end

5.2.2 icopy.f

C
C	icopy.f: Copies one general new IBIS file to another,
C	possibly with a change in organization (row/column).
C
C       This routine gives an example of how to use the IBIS-2
C       subroutine package using the FORTRAN bridges.
C
C	Uses: Ported VICAR runtime library,
C      IBIS-2 subroutine library.
C

	include 'VICMAIN_FOR'

	subroutine main44
	integer inunit,outunit,status
	integer count
	integer  ibis_out,ibis_in,ibufsize
	parameter (ibufsize=250)
	integer nc, nr, col,colsize
	integer row, row_inc, nrow 
	character*16  org 
	character*6 format(1000) 
	character*6 cfmt
	logical ascii
	character*64 cbuffer(ibufsize*8)
	real*8 buffer(ibufsize*64)
	! The equivalence is just to conserve memory:
	equivalence (buffer,cbuffer)
	include 'ibisfile'

C   open the input IBIS file, abort on error. The four '0' arguments
C   in the ibis_file_open are only used for creating output files
	
	call xvunit( inunit, 'inp', 1, status, ' ') 
	call ibis_file_open( inunit, ibis_in, IMODE_READ, 0,
     +      0,' ',' ', status) 
	if (status.ne.1) call ibis_signal_u( inunit, status, 1) 

C  get the # rows & columns and the column-format
C  of the input IBIS file:

	count = ibis_file_get( ibis_in,IFILE_NC, nc, 1,1 )
	if (count.lt.0) call ibis_signal( ibis_in, count, 1)
	count = ibis_file_get( ibis_in,IFILE_NR, nr, 1,1 )
	if (count.lt.0) call ibis_signal( ibis_in, count, 1)
	count = ibis_file_get( ibis_in,IFILE_FORMATS, format, 1, nc )
	if (count.lt.0) call ibis_signal( ibis_in, count, 1)

C open the output file with identical structure. The routine returns
C in variable 'ibis_out' the handle to the IBIS file, which should be used
C in all IBIS file-io operations
	
	call xvpone( 'org', org, 1, 0 ) 
	call xvunit( outunit, 'out', 1,status, ' ') 
	call ibis_file_open( outunit, ibis_out, IMODE_WRITE, nc, 
     +  	             nr, format, org, status ) 
	if (status.ne.1) call ibis_signal_u( outunit, status, 1) 
	
C   copy the column data from input to output

	do col=1,nc
	
		call ibis_column_get( ibis_in, ICOLUMN_FORMAT, 
     +               cfmt, col, status )  
		if (status .ne.1) call ibis_signal( ibis_in, status, 1)
! Determine format -- library alway returns keywords in UPPERCASE.
		ascii = (cfmt(1:1).eq.'A')
		if (ascii) then
			call ibis_column_set( ibis_in, 
     +                    ICOLUMN_U_FORMAT,'a64',col,status)
			if (status .ne.1) call ibis_signal( ibis_in, 
     +                                                    status, 1)
			call ibis_column_set( ibis_out, 
     +                     ICOLUMN_U_FORMAT,'a64',col,status)
			if (status .ne.1) call ibis_signal( ibis_out, 
     +                                                    status, 1)
		endif
		
		! Get the size of a column's buffer element, in bytes
		call ibis_column_get( ibis_in,ICOLUMN_U_SIZE, colsize,
     +                                       col, status ) 
		if (status .ne.1) call ibis_signal( ibis_in, status, 1)
		
		! Compute #elements that will fit into buffer
		row_inc = (ibufsize + colsize  - 1)/colsize  
		
		! Actually do some writing. The ibis_column_read/write calls
		! read/write <nrow> rows of column #<col> from buffer,
		! starting at row #<row>. The data is automatically converted
		! into the native host format of the given column.
		
		do row = 1,nr,row_inc
			nrow = MIN( nr+1-row , row_inc) 

	! If this is an ASCII column, need to use the A*64 buffer:
	! Note that we could have used the same buffer if we 
	! just turned the U_FORMAT to NONE.
			
			if (ascii) then
			   call ibis_column_read( ibis_in, cbuffer, 
     +				col, row, nrow,status )
			else
			   call ibis_column_read( ibis_in, buffer, 
     +				col, row, nrow,status )
			endif
     
     			! We know that ibis_in is a valid IBIS handle here
     			! so in case of error, we can call ibis_signal
     	
			if (status.ne.1) call ibis_signal( ibis_in,
     +                                                    status, 1) 

			! If this is an ASCII column, need to use CHAR:
			if (ascii) then
			   call ibis_column_write( ibis_out, cbuffer, 
     +				col, row, nrow,status )
			else
			   call ibis_column_write( ibis_out, buffer, 
     +				col, row, nrow,status )
			endif
			if (status.ne.1) call ibis_signal( ibis_out,
     +                                                     status, 1) 
		enddo
	enddo

C close up shop 

	call ibis_file_close( ibis_in, ' ', status ) 
	if (status.ne.1) call ibis_signal( ibis_in, status, 1) 
	call ibis_file_close( ibis_out,' ', status )
	if (status.ne.1) call ibis_signal( ibis_out, status, 1) 
	
	return
	end