!+ Program to perform an ESFT fit to transmission data.
!
! Method:
!	A spectral file is read in together with gaseous 
!	transmission data averaged across the bands. For
!	each gas and band pressures and temperatures for fitting
!	are selected and and an ESFT fit and a scaling function
!	are determined.
!	
!
! Current Owner of Code: J. M. Edwards
!
! History:
!	 Version 	   Date	  		Comment
!   
!	 1.0		   12-04-95		First Version under RCS
!						(J. M. Edwards)
!
! Description of Code:
!   FORTRAN 77 with extensions listed in documentation. 
!
!- ---------------------------------------------------------------------
      PROGRAM ESFT
!
!
!
      IMPLICIT NONE
!
!
!     INCLUDE HEADER FILES.
      INCLUDE 'incl/dimensions_spec.ucf'
      INCLUDE 'incl/dimensions_pp.ucf'
      INCLUDE 'incl/def_std_io.icf'
      INCLUDE 'incl/def_pp_io.icf'
      INCLUDE 'incl/gas_list.pcf'
      INCLUDE 'incl/gas_list.ncf'
      INCLUDE 'incl/esft_scale.pcf'
      INCLUDE 'incl/scale_fnc.pcf'
      INCLUDE 'incl/error.pcf'
!
!     DECLARATION OF VARIABLES.
!
      LOGICAL
     &     LOCK_CODE
!             LOGICAL TO FORBID INTERACTIVE LOOPING
      EXTERNAL
     &     LOCK_CODE
!
      CHARACTER
     &     FILE_SPECTRAL*80
!             NAME OF SPECTRAL FILE
     &   , TRANS_TYPE(NPD_SET)*4
!             TYPE OF TRANSMISSION IN SET
     &   , CHAR_IF
!             CHARACTER FOR INTERACTIVE INPUT OR READING FROM FILE
      INTEGER
     &     IERR
!             ERROR FLAG
      INTEGER
     &     N_SET
!             NUMBER OF SETS OF TRANSMISSIONS
     &   , LENGTH_SET(NPD_SET)
!             LENGTHS OF SETS
     &   , LENGTH_SET_SCALE(0: NPD_SET_SCALE)
!             LENGTHS OF SETS TO SCALE
     &   , BAND_SET(NPD_SET)
!             BAND NUMBERS OF SETS
     &   , TYPE_SET(NPD_SET)
!             TYPE OF ABSORBER IN EACH SET
     &   , INDEX_SET(NPD_SET)
!             INDEXING NUMBERS FOR EACH SET
     &   , I_FIRST_RECORD(NPD_SET)
!             FIRST RECORDS OF SETS
     &   , N_PER_TRANS_RECORD
!             NUMBER OF POINTS PER RECORD
     &   , N_OTHER
!             NUMBER OF SIMILAR SETS
     &   , LIST_OTHER(NPD_SET_SCALE)
!             NUMBERS OF THESE SETS
     &   , I_ABSORB
!             INDEX OF ABSORBER
     &   , I_SET
!             IDENTIFIED NUMBER OF SET
     &   , N_MAX_TERM
!             MAXIMUM NUMBER OF ESFT TERMS
     &   , N_TERM
!             NUMBER OF ESFT TERMS
     &   , I_SCALE
!             SCALING SCHEME
     &   , I_SCALE_FUNCTION
!             TYPE OF SCALING FUNCTION
      INTEGER	
     &     I
!             LOOP VARIABLE
     &   , J
!             LOOP VARIABLE
     &   , K
!             LOOP VARIABLE
     &   , L
!             LOOP VARIABLE
      INTEGER
     &     N_INDEX
!             NUMBER OF INDICES IN DATA
     &   , LIST_INDEX(NPD_SET)
!             LIST OF INDEX TYPES
     &   , N_INDEX_BAND(NPD_SPECIES)
!             NUMBER OF BANDS FOR EACH INDEX
     &   , LIST_BAND(NPD_SPECIES, NPD_BAND)
!             LIST OF BANDS IN WHICH INDEX FALLS
     &   , J_FOUND
!             INDEX OF ABSORBER
     &   , IOS
!             I/O ERROR FLAG
      LOGICAL
     &     L_BAND_PRESENT(NPD_BAND)
!             TRUE IF BAND IS PRESENT
     &   , L_FOUND
!             FLAG TO SAY INDEX IS FOUND
     &   , L_FOUND_BAND
!             TRUE IF BAND IS FOUND
      REAL*8
     &     P_SET(NPD_SET)
!             PRESSURES OF EACH SET
     &   , T_SET(NPD_SET)
!             TEMPERATURES OF SETS
     &   , TOL_FIT
!             TOLERANCE FOR ESFT FIT
     &   , P_SET_SCALE(0: NPD_SET_SCALE)
!             PRESSURES OF EACH SCALING SET
     &   , T_SET_SCALE(0: NPD_SET_SCALE)
!             TEMPERATURES OF SCALING SETS
     &   , U_SET(NPD_AMOUNT, 0: NPD_SET_SCALE)
!             AMOUNTS OF ABSORBER
     &   , TRANS_SET(NPD_AMOUNT, 0: NPD_SET_SCALE)
!             TRANSMITTANCES
     &   , TRANS_CALC(NPD_AMOUNT+1, 0: NPD_SET_SCALE)
!             CALCULATED TRANSMITTANCES
     &   , K_ESFT_SET(NPD_ESFT_TERM)
!             ESFT EXPONENTS FOR SET
     &   , W_ESFT_SET(NPD_ESFT_TERM)
!             ESFT WEIGHTS FOR SET
     &   , SCALE_VECTOR_SET(NPD_SCALE_VARIABLE, NPD_ESFT_TERM)
!             SCALING PARAMETERS FOR SET
      REAL*8
     &     R_DUMMY_SET(NPD_SET)
!             DUMMY VARIABLE FOR READING SETS
!
!     INCLUDE DECLARATIONS FOR SPECTRAL FILES.
      INCLUDE 'dec_spec.finc'
!
!     INCLUDE HEADER FILES.
      INCLUDE 'incl/gas_names.dcf'
      INCLUDE 'incl/scale_fnc.dcf'
!
!     SUBROUTINES CALLED:
      EXTERNAL
     &     IN_SPECTRUM, OPEN_TRANS_IN, READ_TRANS_SUMMARY
     &   , READ_REF_PT, OPEN_FILE_OUT, FIND_SET, READ_TRANS_DATA
     &   , ESFT_FIT, SCALE_FIT, WRITE_FIT
!
!
      DATA IERR/I_NORMAL/
!
!
!
!     REQUEST THE NAME OF THE FILE CONTAINING SPECTRAL DATA.
100   WRITE(IU_USER, '(/A/)')
     &   'GIVE THE NAME OF THE FILE CONTAINING THE SPECTRAL DATA.'
      READ(IU_STDIN, '(A)') FILE_SPECTRAL
!
      INCLUDE 'read_spec.finc'
!
      IF (IERR.NE.I_NORMAL) THEN
         IF (IERR.EQ.I_ERR_EXIST) THEN
!           RECOVER FROM THE ERROR AND TAKE APPROPRIATE ACTION.
            IERR=I_NORMAL
            GOTO 100
         ELSE
            STOP
         ENDIF
      ENDIF
!
!     OPEN THE FILE CONTAINING THE TRANSMISSION DATA.
      CALL OPEN_TRANS_IN(IERR, N_PER_TRANS_RECORD)
      IF (IERR.NE.I_NORMAL) STOP
!     AND READ IN THE SUMMARY OF THE SETS OF DATA.
      CALL READ_TRANS_SUMMARY(IERR, .FALSE.
     &   , TRANS_TYPE
     &   , N_SET, LENGTH_SET, P_SET, T_SET
     &   , R_DUMMY_SET, R_DUMMY_SET
     &   , BAND_SET, TYPE_SET, INDEX_SET
     &   , I_FIRST_RECORD)
      IF (IERR.NE.I_NORMAL) STOP
!
!     FIND WHICH INDICES ARE PRESENT.
!     NOTE THAT THE FIRST INDEX IN LIST_BAND IS THE TRUE INDEX OF THE
!     GAS, NOT MERELY THE LOOP VARIABLE: THIS MAKES THIS SECTION A 
!     LITTLE OPAQUE, BUT IS MORE CONVENIENT BELOW.
      N_INDEX=0
      DO I=1, N_SET
         L_FOUND=.FALSE.
         DO J=1, N_INDEX
            IF (INDEX_SET(I).EQ.LIST_INDEX(J)) THEN
               L_FOUND=.TRUE.
               J_FOUND=LIST_INDEX(J)
            ENDIF
         ENDDO
         IF (L_FOUND) THEN
            L_FOUND_BAND=.FALSE.
            DO K=1, N_INDEX_BAND(J_FOUND)
               IF (BAND_SET(I).EQ.LIST_BAND(J_FOUND, K)) THEN
                  L_FOUND_BAND=.TRUE.
               ENDIF
            ENDDO
            IF (.NOT.L_FOUND_BAND) THEN
               N_INDEX_BAND(J_FOUND)=N_INDEX_BAND(J_FOUND)+1
               LIST_BAND(J_FOUND, N_INDEX_BAND(J_FOUND))=BAND_SET(I)
            ENDIF
         ELSE
            N_INDEX=N_INDEX+1
            LIST_INDEX(N_INDEX)=INDEX_SET(I)
            N_INDEX_BAND(LIST_INDEX(N_INDEX))=1
            LIST_BAND(LIST_INDEX(N_INDEX), 1)=BAND_SET(I)
         ENDIF
      ENDDO
!
!     REQUEST THE REFERENCE PRESSURE AND TEMPERATURE
      WRITE(IU_USER, '(/A, /A)')
     &   'DO YOU WANT TO SPECFIFY REFERENCE CONDITIONS INTERACTIVELY'
     &   ,'OR READ THEM FROM A FILE? (I/F)'
1     READ(IU_STDIN, '(A)') CHAR_IF
      IF ( (CHAR_IF.EQ.'I').OR.(CHAR_IF.EQ.'i') ) THEN
         WRITE(IU_USER, '(/A/)') 'SPECIFY THE REFERENCE PRESSURES AND '
     &      //'TEMPERATURES FOR PERFORMING THE FIT.'
         DO J=1, N_INDEX
            I=LIST_INDEX(J)
            DO K=1, N_INDEX_BAND(I)
               WRITE(IU_USER, '(A29, A20, A9, I5)')
     &            'PRESSURE AND TEMPERATURE FOR '
     &            , NAME_ABSORB(TYPE_ABSORB(I))
     &            , ' IN BAND ', LIST_BAND(I, K)
2              READ(IU_STDIN, *, IOSTAT=IOS)
     &             P_REFERENCE(I, LIST_BAND(I, K))
     &           , T_REFERENCE(I, LIST_BAND(I, K))
               IF (IOS.NE.0) THEN
                  WRITE(IU_ERR, '(A)') '+++ UNEXPECTED RESPONSE.'
                  IF (LOCK_CODE(.TRUE.)) THEN
                     INCLUDE 'batch_error_main.finc'
                  ELSE
                     WRITE(IU_ERR, '(A)') 'PLEASE RE-TYPE.'
                     GOTO 2
                  ENDIF
               ENDIF
            ENDDO
         ENDDO
      ELSE IF ( (CHAR_IF.EQ.'F').OR.(CHAR_IF.EQ.'f') ) THEN
         CALL READ_REF_PT(IERR
     &      , N_ABSORB, TYPE_ABSORB
     &      , N_INDEX, LIST_INDEX, N_INDEX_BAND, LIST_BAND
     &      , P_REFERENCE, T_REFERENCE
     &      )
         IF (IERR.EQ.I_ERR_FATAL) STOP
      ELSE
         WRITE(IU_ERR, '(A)') '+++ UNEXPECTED RESPONSE.'
         IF (LOCK_CODE(.TRUE.)) THEN
            INCLUDE 'batch_error_main.finc'
         ELSE
            WRITE(IU_ERR, '(A)') 'PLEASE RE-TYPE.'
            GOTO 1
         ENDIF
      ENDIF
!
!     OPEN THE OUTPUT FILE.
      CALL OPEN_FILE_OUT(IERR, IU_ESFT_OUT
     &   , 'ENTER NAME OF OUTPUT FILE.')
      IF (IERR.NE.I_NORMAL) STOP
!
!     THE DETAILED OUTPUT IS WRITTEN TO THE MONITOR FILE.'
      OPEN(UNIT=IU_MONITOR, FILE='fit.monitor', IOSTAT=IOS
     &   , STATUS='UNKNOWN'
     &   )
      IF (IOS.NE.0) THEN
         WRITE(IU_ERR, '(/A)') 
     &      '*** ERROR: MONITOR FILE COULD NOT BE OPENED.'
         IERR=I_ERR_FATAL
         STOP
      ENDIF
!
!     DETERMINE THE TOLERANCE FOR THE FIT.
      WRITE(IU_USER, '(/A)') 'ENTER THE TOLERANCE FOR THE FIT.'
3     READ(IU_STDIN, *, IOSTAT=IOS) TOL_FIT
      IF (IOS.NE.0) THEN
         WRITE(IU_ERR, '(A)') '+++ INVALID RESPONSE.'
         IF (LOCK_CODE(.TRUE.)) THEN
            INCLUDE 'batch_error_main.finc'
         ELSE
            WRITE(IU_ERR, '(A)') 'PLEASE RE-ENTER.'
            GOTO 3
         ENDIF
      ENDIF
!
!     SELECT BETWEEN WEIGHTING WITH A SINGLE SCALING FOR EACH ESFT FIT
!     AND WEIGHTING EACH ESFT TERM.
      WRITE(IU_USER, '(/A)') 'ENTER TYPE OF SCALING.'
      WRITE(IU_USER, '(I5, A3, A)') IP_SCALE_BAND, '). '
     &   , 'ONE SCALING FOR EACH FIT.'
      WRITE(IU_USER, '(I5, A3, A)') IP_SCALE_TERM, '). '
     &   , 'A SEPARATE SCALING FOR EACH TERM.'
      WRITE(IU_USER, '(/)')
4     READ(IU_STDIN, *) I_SCALE
      IF (IOS.NE.0) THEN
         WRITE(IU_ERR, '(/A)') '+++ UNRECOGNIZED RESPONSE.'
         IF (LOCK_CODE(.TRUE.)) THEN
            INCLUDE 'batch_error_main.finc'
         ELSE
            WRITE(IU_ERR, '(/A)') 'PLEASE RE-ENTER.'
            GOTO 4
         ENDIF
      ENDIF
      IF ( (I_SCALE.NE.IP_SCALE_BAND)
     &   .AND.(I_SCALE.NE.IP_SCALE_TERM) ) THEN
         WRITE(IU_ERR, '(/A)') '+++ INPUT IS OUT OF RANGE.'
         IF (LOCK_CODE(.TRUE.)) THEN
            INCLUDE 'batch_error_main.finc'
         ELSE
            WRITE(IU_ERR, '(/A)') 'PLEASE RE-ENTER.'
            GOTO 4
         ENDIF
      ENDIF
!
!     SELECT THE TYPE OF SCALING FUNCTION REQUIRED.
      WRITE(IU_USER, '(/A)') 'ENTER TYPE OF SCALING FUNCTION.'
      WRITE(IU_USER, '(I5, A3, A)') IP_SCALE_POWER_LAW, '). '
     &   , 'A POWER LAW IN PRESSURE AND TEMPERATURE.'
      WRITE(IU_USER, '(I5, A3, A)') IP_SCALE_POWER_QUAD, '). '
     &   , 'A POWER LAW IN PRESSURE AND A QUADRATIC IN TEMPERATURE.'
      WRITE(IU_USER, '(I5, A3, A, /8X, A)') IP_SCALE_DOPPLER_QUAD, '). '
     &   , 'A POWER LAW IN PRESSURE AND A QUADRATIC IN TEMPERATURE.'
     &   , 'WITH A DOPPLER CORRECTION TO THE PRESSURE'
      WRITE(IU_USER, '(/)')
5     READ(IU_STDIN, *) I_SCALE_FUNCTION
      IF (IOS.NE.0) THEN
         WRITE(IU_ERR, '(/A)') '+++ UNRECOGNIZED RESPONSE.'
         IF (LOCK_CODE(.TRUE.)) THEN
            INCLUDE 'batch_error_main.finc'
         ELSE
            WRITE(IU_ERR, '(/A)') 'PLEASE RE-ENTER.'
            GOTO 5
         ENDIF
      ENDIF
      IF ( (I_SCALE_FUNCTION.NE.IP_SCALE_POWER_LAW).AND.
     &     (I_SCALE_FUNCTION.NE.IP_SCALE_POWER_QUAD).AND.
     &     (I_SCALE_FUNCTION.NE.IP_SCALE_DOPPLER_QUAD) ) THEN
         WRITE(IU_ERR, '(/A)') '+++ INPUT IS OUT OF RANGE.'
         IF (LOCK_CODE(.TRUE.)) THEN
            INCLUDE 'batch_error_main.finc'
         ELSE
            WRITE(IU_ERR, '(/A)') 'PLEASE RE-ENTER.'
            GOTO 5
         ENDIF
      ENDIF
!
!
!     FIND WHICH BANDS ARE PRESENT.
      DO I=1, N_BAND
         L_BAND_PRESENT(I)=.FALSE.
      ENDDO
      DO I=1, N_SET
         L_BAND_PRESENT(BAND_SET(I))=.TRUE.
      ENDDO
!
!     FOR EACH BAND FIND THE SET WHICH MATCHES THE REFERENCE CONDITIONS
!     MOST CLOSELY AND PERFORM THE FIT.
      DO I=1, N_BAND
         IF (L_BAND_PRESENT(I)) THEN
            DO J=1, N_BAND_ABSORB(I)
!
               I_ABSORB=INDEX_ABSORB(J, I)
!
               CALL FIND_SET(IERR, I, I_ABSORB, TYPE_ABSORB(I_ABSORB)
     &            , P_REFERENCE(I_ABSORB, I)
     &            , T_REFERENCE(I_ABSORB, I)
     &            , N_SET, BAND_SET, INDEX_SET, T_SET, P_SET
     &            , I_SET, N_OTHER, LIST_OTHER)
               IF (IERR.NE.I_NORMAL) STOP
!
               IF (I_SET.GT.0) THEN
!                 A SET TO FIT HAS BEEN FOUND.
!
                  WRITE(IU_STDOUT, '(///A)')
     &               '================================================='
                  WRITE(IU_STDOUT, '(/A)')
     &               'FITTING A NEW GAS AND BAND:'
                  WRITE(IU_STDOUT, '(6X, A7, 8X, I5)')
     &               'BAND = ', I
                  WRITE(IU_STDOUT, '(6X, A15, I5)')
     &               'INDEX OF GAS = ', I_ABSORB
                  WRITE(IU_MONITOR, '(///A)')
     &               '================================================='
                  WRITE(IU_MONITOR, '(/A)')
     &               'FITTING A NEW GAS AND BAND:'
                  WRITE(IU_MONITOR, '(6X, A7, 8X, I5)')
     &               'BAND = ', I
                  WRITE(IU_MONITOR, '(6X, A15, I5)')
     &               'INDEX OF GAS = ', I_ABSORB
!
!                 READ IN THE TRANSMISSION DATA FOR THIS SET.
                  CALL READ_TRANS_DATA(I_FIRST_RECORD(I_SET)
     &               , LENGTH_SET(I_SET), U_SET(1, 0)
     &               , TRANS_SET(1, 0)
     &               , N_PER_TRANS_RECORD
     &               )
                  P_SET_SCALE(0)=P_SET(I_SET)
                  T_SET_SCALE(0)=T_SET(I_SET)
                  LENGTH_SET_SCALE(0)=LENGTH_SET(I_SET)
!                 SET THE DATA FOR THE OTHER SETS WHICH WILL BE FITTED.
                  DO K=1, N_OTHER
                     P_SET_SCALE(K)=P_SET(LIST_OTHER(K))
                     T_SET_SCALE(K)=T_SET(LIST_OTHER(K))
                     CALL READ_TRANS_DATA(I_FIRST_RECORD(LIST_OTHER(K))
     &                  , LENGTH_SET(I_SET), U_SET(1, K)
     &                  , TRANS_SET(1, K)
     &                  , N_PER_TRANS_RECORD
     &                  )
                     LENGTH_SET_SCALE(K)=LENGTH_SET(LIST_OTHER(K))
                  ENDDO
!
                  WRITE(IU_STDOUT, '(//, A)')
     &               'ATTEMPTING ESFT FIT TO TRANSMISSION DATA:'
                  WRITE(IU_STDOUT, '(6X, A)')
     &               'THE FIT WILL BE CARRIED OUT AT:'
                  WRITE(IU_STDOUT, '(8X, A11, 3X, 1PE10.3)')
     &               'PRESSURE = ', P_SET(I_SET)
                  WRITE(IU_STDOUT, '(8X, A14, 1PE10.3)')
     &               'TEMPERATURE = ', T_SET(I_SET)
                  WRITE(IU_STDOUT, '(/)')
!
                  WRITE(IU_MONITOR, '(//, A)')
     &               'ATTEMPTING ESFT FIT TO TRANSMISSION DATA:'
                  WRITE(IU_MONITOR, '(6X, A)')
     &               'THE FIT WILL BE CARRIED OUT AT:'
                  WRITE(IU_MONITOR, '(8X, A11, 3X, 1PE10.3)')
     &               'PRESSURE = ', P_SET(I_SET)
                  WRITE(IU_MONITOR, '(8X, A14, 1PE10.3)')
     &               'TEMPERATURE = ', T_SET(I_SET)
                  WRITE(IU_MONITOR, '(/)')
!
                  N_MAX_TERM=NPD_ESFT_TERM
                  CALL ESFT_FIT(IERR, N_MAX_TERM
     &               , TOL_FIT
     &               , LENGTH_SET(I_SET)
     &               , U_SET(1, 0), TRANS_SET(1, 0)
     &               , N_TERM, K_ESFT_SET, W_ESFT_SET
     &               , TRANS_CALC)
!
                  IF (IERR.EQ.I_NORMAL) THEN
!                    FIND THE BEST SCALING FIT TO THE DATA.
!
                     IF (N_OTHER.GT.1) THEN
                        CALL SCALE_FIT(IERR, I_SCALE
     &                     , N_OTHER
     &                     , LENGTH_SET_SCALE, U_SET, TRANS_SET
     &                     , P_SET_SCALE, T_SET_SCALE
     &                     , N_TERM, K_ESFT_SET, W_ESFT_SET
     &                     , I_SCALE_FUNCTION, SCALE_VECTOR_SET)
                        IF (IERR.NE.I_NORMAL) THEN
                           IF (IERR.NE.I_ABORT_CALCULATION) STOP
                        ENDIF
!
!                       ROUND THE SCALING DATA.
                        WRITE(IU_STDOUT, '(//A/)')
     &                     '+++ NOTE: SCALING PARAMETERS'
     &                     //' ARE ROUNDED TO 3 DECIMAL PLACES.'
                        DO K=1, N_TERM
                           DO L=1, N_SCALE_VARIABLE(I_SCALE_FUNCTION)
                              SCALE_VECTOR_SET(L, K)
     &                           =1.0D-04*DBLE(INT(0.5D+00
     &                           +1.0D+04*SCALE_VECTOR_SET(L, K)))
                           ENDDO
                        ENDDO
!
                     ELSE
                        WRITE(IU_STDOUT, '(/A)')
     &                     '+++ WARNING:'
     &                     //' INSUFFICIENT DATA TO DETERMINE'
     &                     //' PRESSURE AND TEMPERATURE SCALING.'
                        WRITE(IU_STDOUT, '(A, I5)')
     &                     'BAND = ', BAND_SET(I_SET)
                        WRITE(IU_STDOUT, '(A, I4, /)')
     &                     'ABSORBER INDEX = ', INDEX_SET(I_SET)
                        DO K=1, N_TERM
                           DO L=1, N_SCALE_VARIABLE(I_SCALE_FUNCTION)
                              SCALE_VECTOR_SET(L, K)=0.0D+00
                           ENDDO
                        ENDDO
                     ENDIF
!
!                    WRITE THE FITTING DATA OUT TO A FILE.
                     CALL WRITE_FIT(.FALSE.
     &                  , BAND_SET(I_SET), INDEX_SET(I_SET)
     &                  , P_SET(I_SET), T_SET(I_SET)
     &                  , LENGTH_SET(I_SET), U_SET(1, 0)
     &                  , TRANS_SET(1, 0), TRANS_CALC
     &                  , N_TERM, K_ESFT_SET, W_ESFT_SET, I_SCALE
     &                  , I_SCALE_FUNCTION, SCALE_VECTOR_SET)
!
                  ENDIF
               ENDIF
!
!              RESET ERROR FLAG FOR NEXT CASE.
               IERR=I_NORMAL
!
            ENDDO
!
         ENDIF
      ENDDO
!
      CLOSE(IU_ESFT_OUT)
!
!
      STOP
      END
