      subroutine blojob(ok)

C*************************************************
C
C This rather long subroutine reads lines from a
C file (or stdin) with file handle fhandl, and
C parses them, setting up all the pulsational
C and stellar parameters which bruce needs to
C perform its calculations. Any error conditions
C result in a report written out to file handle
C chandl; when blojob returns, ok is set up to
C be .true. for an ok exit, or .false. for an
C error condition. Most of the variables used
C are declared in common block include files -
C these files contain all the documentation regarding
C what the variables are.
C
C PS blojob = Bruce LOad JOB parameters, ok?
C
C Started :19/9/95
C Modified:25/9/95
C          4/12/95: To allow the user to define off-axis modes
C          7/12/95: To make aux writing switchable, and to neaten
C                   up the command naming
C          15/4/96: To allow users to specify PHYSICAL_AMPLITUDES
C                   in the fields command; this means that the
C                   actual amplitudes on the surface of the star
C                   should be the same as (or very close to) the
C                   amplitudes specified by the user.
C          26/2/97: Renamed LEE&SAIO: to MATRIX_DIMENSION:
C
C          12/8/97: Fixed a problem with the SMread flag, and corrected
C                   the string length specification of a POLAR_MKS_GRAVITY
C                   command. Also, sorted the STELLAR_MASS so that it
C                   is given by solar masses and not by kg's (which was
C                   of course wrong)
C
C          23/12/98:Added INCLUDE_ENDPOINTS switch to allow for different time 
C                   sampling. This uses the IncEnd variable
C
C          23/12/98:Added WRITE_TIMINGS_FILE switch to allow the writing of timings
C                   to a text file
C
C          1/25/99 :Added READ_TIMINGS_FILE parameter to allow times to be read in
C                   from a file. This involves modifying the way times are stored;
C                   rather than using a start and end time, times are now stored
C                   in an array. This array is established depending on whether
C                   READ_TIMINGS_FILE is used, or whether START_TIME etc is used.
C
C          14/6/99 :Added HORIZONTAL_PHASE_SHIFT parameter to allow phase shifts 
C                   in the horizontal velocity fields to be modelled (this is 
C                   primarily for simulations of wave leakage)
C
C          14/6/99 :Modified so that the maximum number of parameters is now
C                   stored in the parameter maxpar (set at 20).
C
C          22/6/00 :Changed NA_AMPLITUDE_SHIFT and NA_PHASE shift to TEMPERATURE_AMPLITUDE
C                   and TEMPERATURE_PHASE, respectively, to accompany the new variables
C                   TAmode and TPmode
C
C          22/6/00 :Removed the K_VALUE_OVERRIDE parameter, and replaced it with 
C                   HORIZONTAL_VELOCITY_AMPLITUDE, which sets HAmode
C
C          22/6/00 :Renamed the HORIZONTAL_PHASE_SHIFT to HORIZONTAL_VELOCITY_PHASE
C
C          25/6/00 :Replaced PERIOD_FROM_NU with NU
C
C          26/6/00 :Fixed the physical amplitudes scaling
C
C          20/8/00 :Added in code to support the new PRESSURE_EFFECTS, PRESSURE_AMPLITUDE
C                   and PRESSURE_PHASE parameters
C
C (c) Richard Townsend 1995,1996,1997,1998,1999,2000
C***************************************************** 

C Turn of implicit typing

      implicit none

C Define the hard-wired parameters

      include "bruce.compar_define.inc"

C Load in the Stellar parameters common block

      include "bruce.stepar_common.inc"

C Load in the Mode definition common block

      include "bruce.moddef_common.inc"

C Load in the File names common block

      include "bruce.filnam_common.inc"

C Load in the Field definition common block

      include "bruce.flddef_common.inc"

C Load in the Field switches common block

      include "bruce.fldswi_common.inc"

C Declare the parameters

      integer maxpar
      parameter(maxpar=40)      ! Maximum number of parameters in a command

      integer parlen          
      parameter(parlen=255)     ! Maximum parameter length

C Declare the passed variables

      logical ok		! The exit status of the subroutine

C Declare the in-program variables

      character*(parlen) commnd         ! Character string to hold commands read
      character*(parlen) params(maxpar) ! Array to hold the parameters read
      
      integer stat                ! Returned status value from lparse
      integer nline               ! Current line being parsed in input file
      integer parcnt		  ! A counter used to read the parameters in
      integer mcount              ! A counter to step through modes when setting them up
      integer fcount              ! A counter to step through fields when setting up times
  
      double precision period	  ! Holds the corotating/observers period for an individual mode
      double precision discrm	  ! Used to work out the parity of a mode
      double precision rapmatx    ! The function which returns the roAp rotation group matrix element
      double precision bgetmax 	  ! The function which returns the maximum NRP amplitude
      double precision TStart     ! The start time of field calculations
      double precision TEnd       ! The end time of field calculations
      double precision Time       ! Time value read in from the input timings file

      double precision nutemp     ! Temporary value of nu for doing amplitude scalings
      double precision HAtemp     ! Temporary value of HA for doing amplitude scalings

      integer modper		  ! The mode number to get the timings from
      integer roApM(maxmde)	  ! The roAp mode m-value to use for each mode, if required
      logical IncEnd              ! The end-points inclusion flag

C Declare the in-program control flags

      logical timcom              ! Flag for whether a #Timings command was found
      logical fiecom              ! Flag for whether a #Fields command was found
      logical stecom		  ! Flag for whether a #Stellar command was found
  
      logical Lread            	  ! The flag for when L is read
      logical Mread            	  ! The flag for when M is read
      logical VAread		  ! The flag for when the amplitude is read
      logical pread		  ! The flag for when either type of period is read
      logical TAread		  ! The flag for when the temperature amplitude is read
      logical TPread		  ! The flag for when the temperature phase is read
      logical PAread		  ! The flag for when the pressure amplitude is read
      logical PPread		  ! The flag for when the pressure phase is read
      logical IPread		  ! The flag for when the initial phase is read
      logical HAread              ! The flag for when the horizontal velocity field amplitude is read
      logical HPread              ! The flag for when the horizontal velocity field phase is read
      logical BTread   		  ! The flag for when the start-time is read
      logical ETread		  ! The flag for when the end-time is read
      logical NFread		  ! The flag for when the number of fields is read
      logical SRread		  ! The flag for when the polar radius is read
      logical STread		  ! The flag for when the stellar temp. is read
      logical SGread		  ! The flag for when the stellar gravity is read
      logical SMread		  ! The flag for when the stellar mass is read
      logical SVread		  ! The flag for when VEq is read
      logical DIread		  ! The flag for when the stellar inclination is read
      logical Dmread		  ! The flag for when the dump filestub is read
      logical VBread		  ! The flag for when Von Zeipel Beta is read
      logical RTread              ! The flag for when the input timings filename flag is read
      logical nuread              ! The flag for when nu is read
  
      logical PhyAmp		  ! The flag to use physical rather than mathematical amplitudes
   
      logical ppend(maxmde)       ! The pending flag for using an observers period for a given mode
      logical Apend(maxmde)	  ! The pending flag for specifying roApM to get the roAp amplitude
      logical MPpend		  ! The pending flag for getting the timings from a mode period

C Include the constants file and the stellar file

      include 'constants.inc'
      include 'angles.inc'

C Initialise any variables which need to be done before reading
C the parameters

      ok=.false.

      nmodes=0
      timcom=.false.
      fiecom=.false.
      stecom=.false.

C 
      RTread=.false.                    ! The flag for when the input timings filename is read

      write(chandl,'('' Parsing file....'')')

C Now we read lines from the file, using lparse, which parses the
C the input file and gets command/parameter pairs. parser returns
C a value in stat which remarks on the success of the read.

C First initialise nline to be 0...

      nline=0

 1000 continue

C Set up stat to be equal to the dimension of params

      stat=maxpar 

      call parser(fhandl,chandl,commnd,params,stat,nline)

C Now, if stat is greater than zero, interpret the command
C in a huge if_then loop. Note that indenting is not used here.

      if(stat.gt.0) then

C************************************************************************

C Deal with the MODE command, incrementing NModes each time it is read

      if(commnd.eq.'MODE') then

      NModes=NModes+1

C Heck that we have not exceeded maxmde...

      if(NModes.gt.maxmde) then
        write(chandl,
     :  '(''*** There were too many mode commands (maximum '',
     :  I2,'') - Please request a recompile'')') maxmde
        goto 9000
      endif

C Set up the default values

      TAmode(NModes)=0.D0
      TPmode(NModes)=0.D0
      PAmode(NModes)=0.D0
      PPmode(NModes)=0.D0
      IPmode(NModes)=0.D0
      HAmode(NModes)=0.D0
      HPmode(NModes)=0.D0
      numode(NModes)=0.D0

C Set up all of the flags for the parameters which have to be found, and also flags for ones
C which dont have to be found, but must not be duplicated...

      Lread=.false.               	! The flag for when L is read
      Mread=.false.                  	! The flag for when M is read
      VAread=.false.                    ! The flag for when the amplitude is read
      pread=.false.                     ! The flag for when either type of period is read
      TAread=.false.			! The flag for when TA is read
      TPread=.false.			! The flag for when TP is read
      PAread=.false.			! The flag for when PA is read
      PPread=.false.			! The flag for when PP is read
      HAread=.false.                    ! The flag for when HA is read
      HPread=.false.                    ! The flag for when HP is read
      IPread=.false.			! The flag for when the initial phase is read
      nuread=.false.                    ! The flag for when nu is read

C Set up the flags marking pending variables. Apend is used to flag when there is a pending roAp normalising
C amplitude to be read in once the axis offset angle has been read, and ppend indicates that the co-rotating
C period is pending.

      ppend(NModes)=.false.
      Apend(NModes)=.false.

C Interpret the parameters by looping up to stat. I have now put in checks to see if a parameter has
C already been read - if it has, we goto 6500

      do parcnt=1,stat,1

      if(params(parcnt)(1:8).eq.
     :  'L_VALUE:') then
        if(Lread) goto 6500
        read(params(parcnt)(9:),'(I5)',err=8500) Lmode(NModes)
        Lread=.true.
      elseif(params(parcnt)(1:8).eq.
     :  'M_VALUE:') then
        if(Mread) goto 6500
        read(params(parcnt)(9:),'(I5)',err=8500) Mmode(NModes)
        Mread=.true.
      elseif(params(parcnt)(1:19).eq.
     :  'VELOCITY_AMPLITUDE:') then
        if(VAread) goto 6500
        read(params(parcnt)(20:),'(F20.0)',err=8500) VAmode(NModes)
        VAread=.true.
        VAmode(NModes)=VAMode(NModes)*1000.D0
      elseif(params(parcnt)(1:13).eq.
     :  'ROAP_M_VALUE:') then
        if(Apend(NModes)) goto 6500
        read(params(parcnt)(14:),'(I5)',err=8500) roApM(NModes)
        Apend(NModes)=.true.
      elseif(params(parcnt)(1:18).eq.
     :  'COROTATING_PERIOD:') then
        if(pread) goto 6500
        read(params(parcnt)(19:),'(F20.0)',err=8500) period
        pread=.true.
        period=period*3600.D0
      elseif(params(parcnt)(1:17).eq.
     :  'OBSERVERS_PERIOD:') then
        if(pread) goto 6500
        read(params(parcnt)(18:),'(F20.0)',err=8500) period
        pread=.true.
        ppend(NModes)=.true.
        period=period*3600.D0
      elseif(params(parcnt)(1:3).eq.
     :  'NU:') then
        if(nuread) goto 6500
        read(params(parcnt)(4:),'(F20.0)',err=8500) numode(NModes)
        nuread=.true.
      elseif(params(parcnt)(1:22).eq.
     :  'TEMPERATURE_AMPLITUDE:') then
        if(TAread) goto 6500
        read(params(parcnt)(23:),'(F20.0)',err=8500) TAmode(NModes)
        TAread=.true.
      elseif(params(parcnt)(1:18).eq.
     :  'TEMPERATURE_PHASE:') then
        if(TPread) goto 6500
        read(params(parcnt)(19:),'(F20.0)',err=8500) TPmode(NModes)
        TPmode(NModes)=D360*TPmode(NModes)/360.D0
        TPread=.true.
      elseif(params(parcnt)(1:19).eq.
     :  'PRESSURE_AMPLITUDE:') then
        if(PAread) goto 6500
        read(params(parcnt)(20:),'(F20.0)',err=8500) PAmode(NModes)
        PAread=.true.
      elseif(params(parcnt)(1:15).eq.
     :  'PRESSURE_PHASE:') then
        if(PPread) goto 6500
        read(params(parcnt)(16:),'(F20.0)',err=8500) PPmode(NModes)
        PPmode(NModes)=D360*PPmode(NModes)/360.D0
        PPread=.true.
      elseif(params(parcnt)(1:30).eq.
     :  'HORIZONTAL_VELOCITY_AMPLITUDE:') then
        if(HAread) goto 6500
        read(params(parcnt)(31:),'(F20.0)',err=8500) HAmode(NModes)
        HAread=.true.
      elseif(params(parcnt)(1:26).eq.
     :  'HORIZONTAL_VELOCITY_PHASE:') then
        if(HPread) goto 6500
        read(params(parcnt)(27:),'(F20.0)',err=8500) HPmode(NModes)
        HPmode(NModes)=D360*HPmode(NModes)/360.D0
        HPread=.true.
      elseif(params(parcnt)(1:14).eq.
     :  'INITIAL_PHASE:') then
        if(IPread) goto 6500
        read(params(parcnt)(15:),'(F20.0)',err=8500) IPmode(NModes)
        IPmode(NModes)=IPmode(NModes)*D360/360.D0
        IPread=.true.
      else
        goto 7500
      endif

      enddo

C OK, now check we have all of the parameters...

      if(.not.Lread) then
        write(chandl,
     :  '(''*** L_Value was not defined in #Mode #'',I3)') NModes
        goto 9000
      elseif(.not.Mread) then
        write(chandl,
     :  '(''*** M_Value was not defined in #Mode #'',I3)') NModes
        goto 9000
      elseif(.not.VAread) then
        write(chandl,
     :  '(''*** Velocity_Amplitude was not defined in #Mode #'',
     :  I3)') NModes
        goto 9000  
      elseif(.not.pread) then
        write(chandl,
     :  '(''*** Corotating_Period/Observers_Period was not '',
     :  ''defined in #Mode #'',I3)') NModes
        goto 9000
      endif

C Using Lmode and Mmode, get the j-value Jmode and the parity
C First work out a discriminant of the parity...

      discrm=(Lmode(NModes)-iabs(Mmode(NModes)))/2.D0

C Then set up the parity and j

      if(discrm.eq.int(discrm)) then
        Jmode(NModes)=int(discrm+1)
        parity(NModes)=.true.
      else
        JMode(NModes)=int(discrm+0.5)
        parity(NModes)=.false.
      endif

C Convert the period into an angular frequency, checking if the period
C is zero, if the period was set

      if(period.eq.0.D0) then
        write(chandl,
     :  '(''*** A period value of 0 was found in #Mode #'',I3)') NModes
        goto 9000
      else
        CFmode(NModes)=D360/(period)
      endif

C Check that L has an OK value

      if(Lmode(NModes).lt.0) then
        write(chandl,
     :  '(''*** L_Value was less than 0 in #Mode #'',I3)') NModes
        goto 9000
      endif

C Check that M has an OK value

      if(abs(Mmode(NModes)).gt.Lmode(NModes)) then
        write(chandl,
     :  '(''*** |M_Value| exceeded L_Value in #Mode #'',I3)') NModes
        goto 9000
      endif

C Check that, if it was set, roApM has an ok value

      if(abs(roApM(NModes)).gt.Lmode(NModes)
     :   .and.Apend(NModes)) then
        write(chandl,
     :  '(''*** |roAp_M_Value| exceeded L_Value '',
     :  ''in #Mode #'',I3)') NModes
        goto 9000
      endif

C All the other checks are done at the end of the parsing, since we
C set up the pending CFmode and KMode variables there...

C**************************************************************************

C OK, now deal with the timings command

      elseif(commnd.eq.'TIMINGS') then

C Check that this is the only timings command - if not, bum out

      if(timcom) then
        write(chandl,
     :  '(''*** A spurious #Timings command was found at line '',
     :  I2)') nline
        goto 9000
      else
        timcom=.true.
      endif

C Set up all of the flags for the parameters which have to be used

      BTread=.false.           		! The flag for when the start-time is read
      ETread=.false.                    ! The flag for when the end-time is read

C Set up the default parameters

      IncEnd=.false.                    ! The end-points inclusion switch  
      WrtTim=.false.                    ! The write timings file switch
      TmFile= ' '                       ! The input times filename

C Set up the flags for the pending variables

      MPpend=.false.                    ! The pending flag for getting the timings from a mode period

C Interpret all of the parameters

      do parcnt=1,stat,1

      if(params(parcnt)(1:16).eq.
     :  'USE_MODE_PERIOD:') then
        if(BTread.or.ETread) goto 6500
        read(params(parcnt)(17:),'(I5)',err=8500) modper
        BTread=.true.
        ETread=.true.
        MPpend=.true.
      elseif(params(parcnt)(1:11).eq.
     :  'START_TIME:') then
        if(BTread) goto 6500
        read(params(parcnt)(12:),'(F20.0)',err=8500) TStart
        BTread=.true.
      elseif(params(parcnt)(1:12).eq.
     :  'FINISH_TIME:') then
        if(ETread) goto 6500
        read(params(parcnt)(13:),'(F20.0)',err=8500) TEnd
        ETread=.true.
      elseif(params(parcnt)(1:17).eq.
     :  'INCLUDE_ENDPOINTS') then
        if(IncEnd) goto 6500
        IncEnd=.true.
      elseif(params(parcnt)(1:18).eq.
     :  'WRITE_TIMINGS_FILE') then
        if(WrtTim) goto 6500
        WrtTim=.true.
      elseif(params(parcnt)(1:18).eq.
     :  'READ_TIMINGS_FILE:') then
        if(RTread.or.BTread.or.ETread.or.NFRead.or.MPpend) goto 6500
        read(params(parcnt)(19:),'(A)') TmFile
        RTread=.true.
        BTread=.true.
        ETread=.true.
      else
        goto 7500
      endif

      enddo

C Check we have all of the parameters...

      if(.not.BTread) then
        write(chandl,
     :  '(''*** Start_Time/Use_Mode_Period was not defined
     : in #Spectra command'')')
        goto 9000
      elseif(.not.ETread) then
        write(chandl,
     :  '(''*** Finish_Time/Use_Mode_Period was not defined
     : in #Spectra command'')')
        goto 9000
      endif

C Check that the start time preceeds the finish time (if the use_mode_period
C pending flag is not set)

      if(Tstart.ge.Tend.and..not.MPpend.and..not.RTread) then
        write(chandl,
     :  '(''*** Start_Time is greater than or equal to
     : Finish_Time in #Timings command'')')
        goto 9000
      endif

C We set up the timings for the use_mode_period command at the
C end of this subroutine.


C**************************************************************************

C OK, now deal with the fields commands...

      elseif(commnd.eq.'FIELDS') then
     
C Check that this is the only fields command - if not, bum out

      if(fiecom) then
        write(chandl,
     :  '(''*** A spurious #Fields command was found at line '',
     :  I2)') nline
        goto 9000
      else
        fiecom=.true.
      endif
 
C Set up the default parameters

      LSDEff=.false.
      roAEff=.false.
      NrmEff=.false.
      SrfEff=.false.
      GrvFld=.false.
      TmpEff=.false.
      PreEff=.false.
      HorEff=.false.
      ColNrm=.false.
      WrtAux=.false.
      MatDim=DimMax
      RAxOff=0.D0

      PhyAmp=.false.
           
C Set up all of the flags for the parameters which must be found to be false/ which have to be read once...

      NFread=.false.			! The flag for when the number of fields is read
      DmRead=.false.			! The dump fields flag

C Interpret all of the parameters

      do parcnt=1,stat,1

      if(params(parcnt)(1:17).eq.
     :  'NUMBER_OF_FIELDS:') then
        if(NFread.or.RTread) goto 6500
        read(params(parcnt)(18:),'(I5)',err=8500) NField
        NFread=.true.
      elseif(params(parcnt)(1:17).eq.
     :  'MATRIX_DIMENSION:') then
        if(LSDEff) goto 6500
        read(params(parcnt)(18:),'(I5)',err=8500) MatDim
        LSDEff=.true.      
      elseif(params(parcnt)(1:5).eq.
     :  'ROAP:') then
        if(roAEff) goto 6500
        read(params(parcnt)(6:),'(F20.0)',err=8500) RAxOff
        RAxOff=RAxOff*D360/360.D0
        roAEff=.true.
      elseif(params(parcnt).eq.
     :  'NORMAL_FIELDS') then
        if(GrvFld) goto 6500
        GrvFld=.true.
      elseif(params(parcnt).eq.
     :  'AREA_EFFECTS') then
        if(SrfEff) goto 6500
        SrfEff=.true.
      elseif(params(parcnt).eq.
     :  'NORMAL_EFFECTS') then
        if(NrmEff) goto 6500
        NrmEff=.true.
      elseif(params(parcnt)(1:19).eq.
     :  'TEMPERATURE_EFFECTS') then
        if(TmpEff) goto 6500
        TmpEff=.true.
      elseif(params(parcnt)(1:16).eq.
     :  'PRESSURE_EFFECTS') then
        if(PreEff) goto 6500
        PreEff=.true.
      elseif(params(parcnt)(1:26).eq.
     :  'HORIZONTAL_VELOCITY_FIELDS') then
        if(HorEff) goto 6500
        HorEff=.true.
      elseif(params(parcnt)(1:24).eq.
     :  'COLATITUDE_NORMALISATION') then
        if(ColNrm) goto 6500
        ColNrm=.true.
      elseif(params(parcnt)(1:19).eq.
     :  'PHYSICAL_AMPLITUDES') then
        if(PhyAmp) goto 6500
        PhyAmp=.true.
      elseif(params(parcnt)(1:15).eq.
     :  'WRITE_AUX_FILES') then
        if(WrtAux) goto 6500
        WrtAux=.true.
      elseif(params(parcnt)(1:14).eq.
     :  'DUMP_FILESTUB:') then
        if(DmRead) goto 6500
        read(params(parcnt)(15:),'(A)') DmStub
        DmRead=.true.
      else
        goto 7500
      endif

      enddo

C Check we have all of the parameters (NField is checked right
C at the end...)

      if(.not.Dmread) then
        write(chandl,
     :  '(''*** Dump_Filestub was not defined in'',
     :  '' #Fields command'')')
        goto 9000
      endif
          
C Check that Lee & Saio and roAp have not been used together

      if(roAEff.and.LSDEff) then
        write(chandl,
     :  '(''*** roAp and Lee&Saio may not be used together'')')
        goto 9000
      endif

C Check that the Lee & Saio matrix dimension was reasonable...

      if(MatDim.lt.1.and.LSDEff) then
        write(chandl,
     :  '(''*** Lee&Saio was less than 1
     : in #Fields command'')')
        goto 9000
      elseif(MatDim.gt.dimmax) then
        write(chandl,
     :  '(''*** Lee&Saio was too large (maximum '',
     :  I2,'') in #Fields command - Please '',
     :  ''request a recompile'')') dimmax
        goto 9000
      endif

C**************************************************************************

C OK now deal with the Stellar command...

      elseif(commnd.eq.'STELLAR') then
       
C Check that this is the only stellar command - if not, bum out...

      if(stecom) then
        write(chandl,
     :  '(''*** A spurious #Stellar command was found at line '',
     :  I2)') nline
        goto 9000
      else
        stecom=.true.
      endif

C Set up the default parameters

      DIncl=D90

C Set up the flags for the parameters which have to be set up, or cannot be duplicated...

      SRread=.false.
      STread=.false.
      SGRead=.false.
      SMread=.false.
      SVRead=.false.
      DIread=.false.
      VBread=.false.

C OK, now interpret the parameters...

      do parcnt=1,stat,1

      if(params(parcnt)(1:13).eq.
     :  'POLAR_RADIUS:') then
        if(SRread) goto 6500
        read(params(parcnt)(14:),'(F20.0)',err=8500) RPole
        RPole=RPole*RSun
        SRread=.true.
      elseif(params(parcnt)(1:18).eq.
     :  'POLAR_TEMPERATURE:') then
        if(STread) goto 6500
        read(params(parcnt)(19:),'(F20.0)',err=8500) TPole
        STread=.true.
      elseif(params(parcnt)(1:18).eq.
     :  'POLAR_LOG_GRAVITY:') then
        if(SGread.or.SMread) goto 6500
        read(params(parcnt)(19:),'(F20.0)',err=8500) GPole
        GPole=10.D0**(GPole-2.D0)
        SGread=.true.
      elseif(params(parcnt)(1:18).eq.
     :  'POLAR_MKS_GRAVITY:') then
        if(SGread.or.SMread) goto 6500
        read(params(parcnt)(19:),'(F20.0)',err=8500) GPole
        SGread=.true.
      elseif(params(parcnt)(1:13).eq.
     :  'STELLAR_MASS:') then
        if(SMread.or.SGread) goto 6500
        read(params(parcnt)(14:),'(F20.0)',err=8500) MStar
        MStar=MStar*MSun
        SMread=.true.
      elseif(params(parcnt)(1:20).eq.
     :  'EQUATORIAL_VELOCITY:') then
        if(SVread) goto 6500
        read(params(parcnt)(21:),'(F20.0)',err=8500) VEq
        VEq=VEq*1000.D0
        SVread=.true.
      elseif(params(parcnt)(1:18).eq.
     :  'POLAR_INCLINATION:') then
        if(DIread) goto 6500
        read(params(parcnt)(19:),'(F20.0)',err=8500) DIncl
        DIncl=D360*DIncl/(360.D0)
        DIread=.true.
      elseif(params(parcnt)(1:12).eq.
     :  'ZEIPEL_BETA:') then
        if(VBread) goto 6500
        read(params(parcnt)(13:),'(F20.0)',err=8500) Beta
        VBread=.true.
      else
        goto 7500
      endif

      enddo

C Check that all the necessary parameters have been read.

      if(.not.SRread) then
        write(chandl,
     :  '(''*** Polar_Radius was not defined in #Stellar command'')')
        goto 9000
      elseif(.not.STread) then
        write(chandl,
     :  '(''*** Polar_Temperature was not defined
     : in #Stellar command'')')
        goto 9000
      elseif(.not.SVread) then
        write(chandl,
     :  '(''*** Equatorial_Velocity was not defined
     :  in #Stellar command'')')
        goto 9000
      endif

C Now we do a bit of validation on the figures. We do not validate Veq to
C allow for negative Omega's

      if(Rpole.le.0.D0) then
        write(chandl,
     :  '(''*** Polar_Radius was 0 or less in #Stellar command'')')
        goto 9000
      elseif(TPole.le.0.D0) then
        write(chandl,
     :  '(''*** Polar_Temperature was 0 or less in #Stellar command'')')
        goto 9000
      endif

C When we do the check for SMread and SGread, we must just check that neither
C of them is defined...

      if(SGread) then
        MStar=GPole*RPole**2/BigG
      elseif(SMread) then
        GPole=BigG*MStar/RPole**2
      else
        write(chandl,
     :  '(''*** Polar_Gravity/Stellar_Mass was not defined '',
     :  ''in #Stellar Command'')')
        goto 9000
      endif

C Validate that MStar is gt 0 - this will check GPole also

      if(MStar.le.0.D0) then
        write(chandl,
     :  '(''*** Stellar_Mass/Polar_Gravity is 0 or less '',
     :  ''in #Stellar command'')')
        goto 9000
      endif

C OK, now check that the rotation is sub-critical - if it is, set up Omega from
C Veq and Req, otherwise bum out...

      VCrit=sqrt(BigG*MStar/(1.5D0*Rpole))

      if(Veq.ge.VCrit) then
        write(chandl,
     :  '('' *** Equatorial_Velocity in #Stellar command leads to '',
     :  ''super-critical rotation (VCrit='',F10.3,'')'')') VCrit
        goto 9000
      endif

      REq=BigG*MStar/(BigG*MStar/RPole-0.5D0*VEq**2)

      Omega=VEq/REq

C If Beta was not specified, it defaults to 0.25:

      if(.not.VBread) Beta=0.25D0

C Ok, go on to the next bit...


C**************************************************************************

C This part is for unrecognised commands.....

      else
        write(6,
     : '(''*** An unrecognised command was found at line '',I2)') nline
        goto 9000
      endif

C**************************************************************************

C Now we deal with the cases where stat <= 0

C Checks to see if stat was zero - if it was, jump out...

      elseif(stat.eq.0) then
        goto 5000

C Otherwise, we have had an error - give a report...

      elseif(stat.eq.-1) then
        write(chandl,
     :  '(''*** Unknown command found at line '',I2)') nline
        stop
      elseif(stat.eq.-2) then
        write(chandl,
     :  '(''*** Command too long at line '',I2)') nline
        stop
      elseif(stat.eq.-3) then
        write(chandl,
     :  '(''*** A command was not followed by { on line '',I2)') nline
        stop
      elseif(stat.eq.-4) then
        write(chandl,
     :  '(''*** A spurious { was found at line '',I2)') nline
        stop
      elseif(stat.eq.-5) then
        write(chandl,
     :  '(''*** There were too many parameters (runaway list?) at
     : line '',I2)') nline
        stop
      elseif(stat.eq.-6) then
        write(chandl,
     :  '(''*** Parameter too long at line '',I2)') nline
        stop
      elseif(stat.eq.-7) then
        write(chandl,
     :  '(''*** End-of-file found when reading parameters at '',
     :  ''line '',I2)') nline
        stop
      elseif(stat.eq.-8) then
        write(chandl,
     :  '(''*** There was a general error reading line '',I2)') nline
      else
        write(chandl,
     :  '(''*** There was an unspecified error reading line '',
     :  I2)') nline
        stop
      endif

C Loop back around to read the next line...
 
      goto 1000

C This is the jump-in point for a `legal' end-of-file

 5000 continue

C First check if any modes have been defined - we have to do this here
C because the MODE command may be used more than once

      if(NModes.eq.0) then
        write(chandl,
     : '(''*** There were no #Modes commands found'')')
        goto 9000
      endif

C Now check that the other commands have been used.

      if(.not.timcom) then
        write(chandl,
     :  '(''*** There was no #Timings command found'')')
        goto 9000
      elseif(.not.fiecom) then
        write(chandl,
     :  '(''*** There was no #Fields command found'')')
        goto 9000
      elseif(.not.stecom) then
        write(chandl,
     :  '(''*** There was no #Stellar command found'')')
        goto 9000
      endif


C Now loop over the mode definitions to see of they have any pending variables
C which need setting up...

      do mcount=1,NModes,1

C If ppend is true, the observers period for this mode was given instead of the corotating
C period, so the angular frequency must be adjusted to get CFmode to a
C corotating rather than observers value. 

      if(ppend(mcount)) then 
        CFmode(mcount)=CFmode(mcount)+Mmode(mcount)*Omega
      endif

C Set up the value of K

      Kmode(mcount)=Gpole/(Rpole*CFmode(mcount)**2)

C If the Apend flag is true, we set up the roAp adjustment amplitude for the mode using
C the polar axis RAxOff - otherwise, we set the amplitude adjustment to unity

      if(Apend(mcount)) then 
        NAmode(mcount)=rapmatx(RAxOff,Lmode(mcount),roApM(mcount),
     :  Mmode(mcount)) 
      else
        NAmode(mcount)=1.D0
      endif

C If Lee & Saio modes are used, we check that none of the modes have m=0

      if(LSDEff.and.Mmode(mcount).eq.0) then
        write(chandl,
     :  '(''*** Lee&Saio cannot be used on modes with M_Value=0'')')
        goto 9000
      endif

C Now we see if the user has specified physical amplitudes. If they have, we
C loop over the modes to turn the mathematical amplitudes into real amplitudes.

      if(PhyAmp) then

         if(numode(mcount).eq.0.) then
            nutemp = 2.D0*Omega/CFmode(mcount)
         else
            nutemp = numode(mcount)
         endif
         if(HAmode(mcount).eq.0.) then
            HAtemp = Kmode(mcount)
         else
            HAtemp = HAmode(mcount)
         endif

         VAmode(mcount)=VAmode(mcount)/
     :        bgetmax(nutemp,HAtemp,
     :        Mmode(mcount),Jmode(mcount),parity(mcount))

      endif

C Loop back around...

      enddo

C Set up the timings array based on user information. If a timings file is
C specified, read it in; otherwise, use Tstart and Tend, calculating them
C from one of the mode periods if needs be

      if(RTread) then
        open(unit=thandl,file=TmFile,status='old',err=8600)

        NField=0

        write(chandl,'(''  Reading timings from file '',A)') TmFile

 5100   continue
        read(thandl,*,end=5200,err=8600) Time
        NField=NField+1
        if(NField.gt.maxfld) goto 8700
        Times(NField)=Time*3600.D0
        goto 5100

 5200   continue

        close(thandl)

      else

C Set up Tstart and Tend if timings are to come from a mode (these
C are in seconds)

        if(MPpend) then
          if(modper.le.NModes.and.modper.gt.0) then
            TStart=0.D0
            TEnd=dabs(D360/((CFmode(modper)-Mmode(modper)*Omega)*
     :                3600.D0))
          else
            write(chandl,'(''*** Faliure trying to obtain timings '',
     :    ''from undefined mode'')')
            goto 9000
          endif
        endif

C Do a consistency check if IncEnd is .true.

        if(IncEnd.and.NField.lt.2) then
          write(chandl,
     :    '(''*** Include_Endpoints requires at least 2 fields'')')
          goto 9000
        endif

C Check that the NField value is OK

        if(.not.NFread) then
          write(chandl,
     :    '(''*** Number of fields has not been defined'')')
          goto 9000
        endif

        if(NField.le.0) then
          write(chandl,
     :    '(''*** Number of fields is less than 1'')')
          goto 9000
        elseif(NField.gt.maxfld) then
          goto 8700
        endif


C Based on these values, set up the timings array

        do fcount=1,NField
          if(IncEnd) then
            Times(fcount)=(TStart+(fcount-1.0D0)/(NField-1.D0)*
     :                    (TEnd-TStart))*3600.D0
          else
            Times(fcount)=(TStart+(fcount-0.5D0)/dble(NField)*
     :                    (TEnd-TStart))*3600.D0
          endif
        enddo

      endif

C Set up ok for a normal exit status...

      ok=.true.

      goto 9000

C This is the jump in point for a duplicated parameter...

 6500 continue

      write(chandl,
     :  '(''*** A duplicated parameter was found in the #'',A,
     :''command at line '',I2,'' : '',A)') 
     : commnd(1:index(commnd,' ')),nline,params(parcnt)

        goto 9000

C This is the jump-in point for an unknown parameter error

 7500   write(chandl,
     :  '(''*** An undefined parameter was found in the #'',A,
     :''command at line '',I2,'' : '',A)') 
     :  commnd(1:index(commnd,' ')),nline,params(parcnt)
        goto 9000

C This is the jump-in point for float read errors

 8500 continue

      write(chandl,
     :  '(''*** There was an error reading a number at line'',
     :  I3)') nline
      goto 9000

C This is the jump in point for an error reading a timings file

 8600 continue

      write(chandl,
     : '(''*** An error was encountered whilst reading the '',
     : ''timings file '',A)') TmFile
      goto 9000
       

C This is the jump-in point for too many fields

 8700 continue

       write(chandl,
     : '(''*** Too many fields were defined (maximum '',
     : I2,'') - Please request a recompile'')') maxfld
       goto 9000

C This is the jump-in point for exiting

 9000 continue

      return

      end
