C
C Program BINASC to convert gridded data (data cubes) from binary files
C to formatted ascii files
C
C Version: 5.40
C Date: 2000, May 29
C
C Coded by: Ludek Klimes
C     Department of Geophysics, Charles University Prague,
C     Ke Karlovu 3, 121 16 Praha 2, Czech Republic,
C     E-mail: klimes@seis.karlov.mff.cuni.cz
C
C.......................................................................
C
C Attention:  Functionality of program BINASC is strongly affected by
C the Fortran compiler and by the options of the compiler.
C Program BINASC can work only if the compiler supports unformatted
C direct-access files "without headers".
C Binary data on little-endian hardware (PC's) and big-endian hardware
C (VAX, Alpha, RISC workstations) should strictly be distinguished.
C
C.......................................................................
C                                                    
C Description of data files:
C
C Input data read from the standard input device (*):
C     The data are read by the list directed input (free format) and
C     consist of a single string 'SEP':
C     'SEP'...String in apostrophes containing the name of the input
C             SEP parameter or history file with the input data.
C     No default, 'SEP' must be specified and cannot be blank.
C
C                                                     
C Input data file 'SEP':
C     File 'SEP' has the form of the SEP
C     parameter file.  The parameters, which do not differ from their
C     defaults, need not be specified in file 'SEP'.
C Data specifying dimensions of the input grid:
C     N1=positive integer... Number of gridpoints along the X1 axis.
C             Default: N1=1
C     N2=positive integer... Number of gridpoints along the X2 axis.
C             Default: N2=1
C     N3=positive integer... Number of gridpoints along the X3 axis.
C             Default: N3=1
C Names of the grid files:
C     IN='string'... String with the name of the input unformatted file
C             containing the gridded values.  The file should contain
C             just the 4 byte IEEE reals.  The length of the file is
C             thus exactly 4*N1*N2*N3 bytes.
C             No default, IN must be specified and cannot be blank.
C     ASC='string'... String with the name of the output formatted file
C             to contain the gridded values.  The file contains N1*N2*N3
C             reals designed to be read by a single list directed (free
C             format) read statement.
C             No default, ASC must be specified and cannot be blank.
C Data specifying input/output format:
C     ESIZE=integer... Number of bytes per a real in the input binary
C             file.  Must be ESIZE=4.
C             Default: ESIZE=4
C     NDIG=integer...
C             NDIG=0: Optimization of the output format is entrusted to
C               the subroutines of file 'forms.for'.  This option is
C               recommended for calculations with the data.  The output
C               file will usually be only sligtly longer than twice the
C               input file.
C             NDIG.NE.0: The output format is '(5(Emm.nn,1X))'), with
C               mm=IABS(NDIG)+6, nn=IABS(NDIG).  Value of NDIG=9 is
C               probably the smallest one which enables to read exactly
C               the same values from unformatted and formatted files.
C               For NDIG=9, the output file will be 4 times (Unix) or
C               4.05 times (DOS) longer than the input file.
C               In general, (NDIG+7)/4 times (Unix) or (NDIG+7.2)/4
C               times (DOS).
C               Minus sign disables to read the formatted file and to
C               compare the values read from both the files.  The minus
C               option thus saves the time and requires twice less
C               memory.
C             Default: NDIG=9
C
C=======================================================================
C
C Common block /RAMC/:
      INCLUDE 'ram.inc'
C     ram.inc
C
C.......................................................................
C
      CHARACTER*80 FILE1,FILE2
      INTEGER LU1,LU2
      PARAMETER (LU1=1,LU2=2)
C
      INTEGER NDIG,N1,N2,N3,I1,I2
      REAL DIF
C
C.......................................................................
C
C     Reading main input data:
      WRITE(*,'(A)') '+BINASC: Enter input filename: '
      FILE1=' '
      READ(*,*) FILE1
      IF (FILE1.NE.' ') THEN
        CALL RSEP1(LU1,FILE1)
      ELSE
C       BINASC-01
        CALL ERROR('BINASC-01: SEP file not given')
C       Input file in the form of the SEP (Stanford Exploration Project)
C       parameter or history file must be specified.
C       There is no default filename.
      ENDIF
C
C     Input and output files with gridded data:
      CALL RSEP3T('IN',FILE1,' ')
      IF (FILE1.EQ.' ') THEN
C       BINASC-02
        CALL ERROR('BINASC-02: Input file not specified')
      END IF
      CALL RSEP3T('ASC',FILE2,' ')
      IF (FILE2.EQ.' ') THEN
C       BINASC-03
        CALL ERROR('BINASC-03: Output file not specified')
      END IF
      CALL RSEP3I('ESIZE',I1,4)
      IF (I1.NE.4) THEN
C       BINASC-04
        CALL ERROR('BINASC-04: Binary reals not 4-byte long')
      END IF
      CALL RSEP3I('NDIG',NDIG,9)
C
C     Reading grid dimensions:
      CALL RSEP3I('N1',N1,1)
      CALL RSEP3I('N2',N2,1)
      CALL RSEP3I('N3',N3,1)
      IF (N1*N2*N3.GT.MRAM) THEN
C       BINASC-05
        CALL ERROR('BINASC-05: Small dimension MRAM of array RAM')
      END IF
C
C     Reading input grid values:
      WRITE(*,'(A)') '+BINASC: Reading...            '
      CALL RBIN(LU1,FILE1,RAM,N1*N2*N3)
C
C     Writing output grid values:
      IF (NDIG.EQ.0) THEN
        CALL WARRAY(LU2,FILE2,'FORMATTED',.FALSE.,0.,.FALSE.,0.,
     *                                                     N1*N2*N3,RAM)
      ELSE
        WRITE(*,'(A)') '+BINASC: Writing...            '
        CALL WASC(LU2,FILE2,RAM,N1*N2*N3,NDIG)
      END IF
C
C     Comparison of values read from unformatted and formatted files:
      IF (NDIG.GT.0) THEN
C       Twice the memory is required for the comparison
        IF (2*N1*N2*N3.GT.MRAM) THEN
C         BINASC-06
          CALL ERROR('BINASC-06: Small dimension MRAM of array RAM')
        END IF
C       Reading output grid values
        CALL RARRAY(LU2,FILE2,'FORMATTED',.TRUE.,0.,
     *                                         N1*N2*N3,RAM(N1*N2*N3+1))
C       Comparing grid values
        WRITE(*,'(A)') '+BINASC: Checking...                           '
        DIF=0.
        I2=N1*N2*N3
        DO 10 I1=1,N1*N2*N3
          I2=I2+1
          IF(RAM(I1).NE.RAM(I2)) THEN
            DIF=AMAX1(ABS((RAM(I1)-RAM(I2))/RAM(I1)),DIF)
          END IF
   10   CONTINUE
        WRITE(*,'(A,E15.7)') '+BINASC: Done.  Max.rel.difference: ',DIF
      ELSE
        WRITE(*,'(A)') '+BINASC: Done.                                 '
      END IF
C
      STOP
      END
C
C=======================================================================
C
      SUBROUTINE RBIN(LU,FILE,GRID,N)
      INTEGER LU,N
      CHARACTER*(*) FILE
      REAL GRID(N)
C
C-----------------------------------------------------------------------
C
      INTEGER I
C
C     Any Fortran 77 compiler (option "direct files without headers"):
      OPEN(LU,FILE=FILE,FORM='UNFORMATTED',ACCESS='DIRECT',RECL=4,
     *                                                     STATUS='OLD')
      DO 10 I=1,N
        READ(LU,REC=I) GRID(I)
   10 CONTINUE
C
C     Lahey F77L3 (compiler-dependent Fortran extension):
*     OPEN(LU,FILE=FILE,FORM='UNFORMATTED',ACCESS='TRANSPARENT')
*     READ(LU) GRID
C
      CLOSE(LU)
      RETURN
      END
C
C=======================================================================
C
      SUBROUTINE WASC(LU,FILE,GRID,N,NDIG)
      INTEGER LU,N,NDIG
      CHARACTER*(*) FILE
      REAL GRID(N)
C
C-----------------------------------------------------------------------
C
      INTRINSIC IABS,MOD
      INTEGER IABS,MOD
      CHARACTER*14 FORMAT
C
      OPEN(LU,FILE=FILE,FORM='FORMATTED')
      FORMAT='(5(E06.00,1X))'
      FORMAT(9:9)=CHAR(ICHAR('0')+MOD(IABS(NDIG),10))
      FORMAT(8:8)=CHAR(ICHAR('0')+    IABS(NDIG)/10 )
      FORMAT(6:6)=CHAR(ICHAR('0')+MOD(IABS(NDIG)+6,10))
      FORMAT(5:5)=CHAR(ICHAR('0')+   (IABS(NDIG)+6)/10)
      WRITE(LU,FORMAT) GRID
      CLOSE(LU)
      RETURN
      END
C
C=======================================================================
C
      SUBROUTINE RASC(LU,FILE,GRID,N)
      INTEGER LU,N
      CHARACTER*(*) FILE
      REAL GRID(N)
C
C-----------------------------------------------------------------------
C
      OPEN(LU,FILE=FILE,FORM='FORMATTED',STATUS='OLD')
      READ(LU,*) GRID
      CLOSE(LU)
      RETURN
      END
C
C=======================================================================
C
      INCLUDE 'error.for'
C     error.for
      INCLUDE 'sep.for'
C     sep.for
      INCLUDE 'forms.for'
C     forms.for
      INCLUDE 'length.for'
C     length.for
C
C=======================================================================
C