*------------- Telecommunications & Signal Processing Lab --------------
*                          McGill University
*
*
* Module:
*     SUBROUTINE AXSCAL (VMIN, VMAX, IAX, DMIN, DMAX,
*                        ATICK, ALABEL, NTICK, IEXP)
*
*
* Purpose:
*     Find a plot axis scale and fill in ticks and labels
*
*
* Description:
*     This routine finds an appropriate axis scale in terms of the
*     scaling between data units and plotting units.  Optionally, an
*     array of axis values corresponding to locations for axis ticks is
*     generated.
*
*     For linear scaling, the tick values generated are uniformly
*     spaced.  The character labels corresponding to these ticks are
*     also generated.  Normally only every second tick has a non-null
*     label.
*
*     For logarithmic scaling, the tick values correspond to the decade
*     points 10**n, and for a data range encompassing a small number
*     of decades, intermediate ticks at 2*10**n and 5*10**n are also
*     generated.  For a single decade, ticks at 2*10**n, 3*10**n, ...,
*     9*10**n are generated.  The decade points are always labelled.
*     If the number of decades is small, intermediate ticks are also
*     labelled.
*
*
* Parameters:
* R ->  VMIN   - Minimum data value to be plotted
* R ->  VMAX   - Maximum data value to be plotted
*                Note: Normally VMAX is not equal to VMIN.
* I ->  IAX    - Option value.  The option value has five components.
*                IXAX = ILL + 4*IUL + 16*ITICK + 32*ILABEL + 64*ILOG
*                ILL    = 1 - The lower limit of the graph is to be a
*                             tick value less than or equal to VMIN
*                         2 - The lower limit of the graph is VMIN
*                IUL    = 1 - The upper limit of the graph is to be a
*                             tick value greater than or equal to VMAX
*                         2 - The upper limit of the graph is VMAX
*                ITICK  = 0 - Ticks are generated by this routine
*                         1 - Ticks are supplied as input
*                ILABEL = 0 - Label values are generated by this
*                             routine
*                         1 - Label values are supplied as input.  This
*                             option is incompatible with ITICK=0.
*                ILOG   = 0 - Linear scale
*                         1 - Logarithmic scale
* R <-  DMIN   - Data value corresponding to the beginning of the axis
* R <-  DMAX   - Data value corresponding to the end of the axis
* R <-  ATICK  - Array of data values corresponding to the ticks.  This
*                array is set by this routine for ITICK=0.
* C <-  ALABEL - Character array of labels corresponding to the ticks.
*                These are in one-to-one correspondence with the array
*                of tick values.  Each element of ALABEL should be at
*                least 11 characters in length.  This array is not
*                altered for ILABEL=1.  For ILABEL=0, NTICK labels are
*                generated.  Each of the generated labels is terminated
*                with a null character if it is shorter than the length
*                of the array elements.
* I <-> NTICK  - Number of tick values generated (up to 64).  This is
*                an output value for ITICK=0.  For ITICK=1, NTICK is an
*                input value used to determine the number of tick
*                values in ATICK.
* I <-  IEXP   - Exponent for the axis labels.  The value of the tick
*                corresponding to an axis label is the value coded in
*                the label string times 10**IEXP.  IEXP is returned as
*                a multiple of 3. Note that IEXP will be zero if all of
*                the labels can be represented in 4 significant digits.
*                IEXP is set to zero if the labels are specified
*                (ILABEL=0) and/or if the axis is logarithmic (ILOG=1).
*
*
* Author / revision:
*     P. Kabal
*     $Revision: 1.7 $  $Date: 1995/03/08 15:27:34 $
*
*
*-----------------------------------------------------------------------

      SUBROUTINE AXSCAL (VMIN, VMAX, IAX, DMIN, DMAX,
     -                   ATICK, ALABEL, NTICK, IEXP)


      INTEGER TICKV,EXACTV,INP,LINS,LOGS
      INTEGER NPL
      REAL EPS
      PARAMETER (TICKV=1,EXACTV=2,INP=1,LINS=0,LOGS=1)
      PARAMETER (NPL=6,EPS=1E-5)

      INTEGER IAX,NTICK,IEXP,NAX
      INTEGER ILL,IUL,ITICK,ILABEL,ILOG,NC,I

      REAL VMIN,VMAX,DMIN,DMAX
      REAL TMIN,TMAX,FIRSTV,DELTAV,VLMIN,VLMAX
      REAL FLOORX,CEILX
      REAL ATICK(*)

      CHARACTER*(NPL) CSTR
      CHARACTER*(*) ALABEL(*)


* Separate the axis option codes
      ILL=MOD(IAX,4)
      IUL=MOD(IAX/4,4)
      ITICK=MOD(IAX/16,2)
      ILABEL=MOD(IAX/32,2)
      ILOG=MOD(IAX/64,2)

*==========
* Find appropriate axis limits
      DMIN=MIN(VMIN,VMAX)
      DMAX=MAX(VMIN,VMAX)

* Ticks supplied, find tick values which bound [DMIN, DMAX]
      IF (ITICK.EQ.INP) THEN
        IF (ILL.EQ.TICKV) THEN
          CALL VGLB(ATICK,NTICK,DMIN,TMIN,I)
          DMIN=TMIN
        END IF
        IF (IUL.EQ.TICKV) THEN
          CALL VLUB(ATICK,NTICK,DMAX,TMAX,I)
          DMAX=TMAX
        END IF
        IF (ILABEL.NE.INP) THEN
          DO 100 I=1,NTICK
            CALL LABEL(ATICK(I),NPL,CSTR,NC)
            ALABEL(I)=CSTR(1:NC)//CHAR(0)
 100      CONTINUE
        END IF
        IEXP=0


* Axis definition, linear axis
      ELSE IF (ILOG.EQ.LINS) THEN
        CALL FNDSCL(DMIN,DMAX,4,12,NAX,FIRSTV,DELTAV)
        IF (ILL.EQ.TICKV) DMIN=FIRSTV
        IF (IUL.EQ.TICKV) DMAX=NAX*DELTAV+FIRSTV
        NTICK=NAX+1
        CALL AXTICK(FIRSTV,DELTAV,NTICK,ATICK,ALABEL,IEXP)

* Axis definition, log axis
      ELSE
        IF (DMIN.LE.0.0) THEN
          DMIN=MAX(0.1*DMAX,0.1)
          CALL WARN('AXSCAL - Log scale, nonpositive value')
        END IF
        IF (DMAX.LE.0.0) THEN
          DMAX=10.*DMIN
          CALL WARN('AXSCAL - Log scale, nonpositive value')
        END IF
        VLMIN=LOG10(DMIN)
        VLMAX=LOG10(DMAX)
        IF (ILL.EQ.TICKV) VLMIN=FLOORX(VLMIN+EPS)
        IF (IUL.EQ.TICKV) THEN
          VLMAX=MAX(CEILX(VLMAX-EPS),CEILX(VLMIN))
          IF (VLMIN.GE.VLMAX) VLMAX=VLMAX+1.
        END IF
        DMIN=10.**VLMIN
        DMAX=10.**VLMAX
        CALL LOGTIC(DMIN,DMAX,ATICK,ALABEL,NTICK)
        IEXP=0
      END IF

* Reverse the axis if necessary
      IF (VMIN.GT.VMAX) THEN
        TMIN=DMIN
        DMIN=DMAX
        DMAX=TMIN
      END IF


      RETURN

      END
