C                                                            <HTML><PRE>
C Program MTT to calculate Multivalued Travel Times either on a 3-D grid
C of points, or in specified individual points.
C
C Version: 7.00
C Date: 2013, June 6
C                                                  <A NAME="author"></A>
C Coded by Petr Bulant
C     Department of Geophysics, Charles University Prague,
C     Ke Karlovu 3, 121 16 Praha 2, Czech Republic,
C     http://sw3d.cz/staff/bulant.htm
C
C----------------------------------------------------------------------
C
C The post processing program to the CRT program performs interpolation
C of travel times and other quantities either to the gridpoints of
C arbitrary regular rectangular 3-D grid of points, or to the individual
C points specified by the input file 'PTS'. The interpolation inside ray
C tubes formed by vertices of homogeneous triangles created during 3-D
C two-point ray tracing is realized using the controlled initial-value
C ray tracing algorithm. The interpolation is performed within all of
C the ray tubes stored in the specified CRT output file 'CRT-T'.
C
C The description of the quantities which may be interpolated can be
C found <A HREF="#data">below</A>. The user may include many other
C quantities by editting the file
C <A HREF="mttq.for" TYPE="text/html">mttq.for</A>.
C
C If the I-th and (I+1)-st points of the three rays forming the ray tube
C are situated inside the same complex block, the program performes
C interpolation within ray cells whose bottom is formed by the I-th
C points and top by (I+1)-st points of the rays.  The best results can
C thus be obtained if the travel time is the independent variable for
C numerical integration in CRT program (default).
C
C This version of the program performs bicubic interpolation of
C travel times within ray cells (in the coordinate system connected
C with each cell), other quantities are interpolated bilinearly.
C
C The interpolation is not performed in demarcation belts between
C different ray histories.  The maximum width of the belts is controlled
C by input parameter <A HREF="rpar.for#data2" TYPE="text/html">AERR</A>
C of the program 'crt.for'.
C The typical width of the belts, measured in take-off angles,
C is 0.0001 radians in order of magnitude.  The belts may become wide
C in areas of large geometrical spreading.  The division of rays into
C different histories is, by default, very detailed and is controlled
C by input parameter
C <A HREF="rpar.for#data2" TYPE="text/html">PRM0(3)</A> of the program
C 'crt.for'. Such a behaviour is useful for two-point ray tracing but
C has some awkward consequences on the interpolation.  For example, the
C demarcation belt between the rays incident at different sides of the
C computational volume for ray tracing extends across the whole model,
C causing an artificial gap within the continuous travel times.
C If the ray history does not account for the termination of a ray at
C different sides of the computational volume, the gaps corresponding
C to the edges of the computational volume are removed, but the corners
C along the edges are not filled with the ray cells any more.  Then the
C computational volume for ray tracing should sufficiently exceed the
C extent of target volume covered by the grid for interpolation.
C Input parameter <A HREF="rpar.for#data2" TYPE="text/html">PRM0(3)</A>
C of the program 'crt.for' may thus considerably influence the results
C of the interpolation. However, gaps due to the demarcation belts
C corresponding to structural interfaces cannot be removed within
C the present interpolation algorithm.
C
C The interpolation is not performed within the cells whose bottom
C or top is not formed by different points. This happens mainly
C in the case of point source. To obtain the results of interpolation
C also around the point source, CRT should be run with parameter
C <A HREF="crtin.for#INIT" TYPE="text/html">ADVANC</A>.
C.......................................................................
C                                                    <A NAME="data"></A>
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                                                     <A NAME="SEP"></A>
C Input data file 'SEP':
C     File 'SEP' has the form of the
C     <A HREF="../forms/sep.htm" TYPE="text/html">SEP</A>
C     parameter file.  The parameters, which do not differ from their
C     defaults, need not be specified in file 'SEP'.
C Names of input files related to ray tracing (output of CRT):
C     CRTOUT='string'... File with the names of the output files of
C             program CRT.
C             For general description of file CRTOUT refer to file
C             <A HREF="writ.for#CRTOUT" TYPE="text/html">writ.for</A>.
C             Description specific to this program:
C               Just the first set of CRT output files is read from
C               file CRTOUT.  Only files
C               <A HREF="writ.for#out1" TYPE="text/html">'CRT-R'</A>,
C               <A HREF="writ.for#outi" TYPE="text/html">'CRT-I'</A> and
C               <A HREF="writ.for#outt" TYPE="text/html">'CRT-T'</A>
C               are read by MTT.
C               File 'CRT-R' must contain all rays traced by CRT, not
C               only two-point rays.
C             Default: CRTOUT=' ' which means 'CRT-R'='r01.out',
C             'CRT-I'='r01i.out', 'CRT-T'='t01.out'
C Data for the interpolation to the target 3-D grid:
C     The interpolation to the 3-D grid of points is performed if the
C     name of the output file MTTPTS is not specified (default).
C   Data specifying the parameters of the target 3-D grid:
C     O1=real, O2=real, O3=real... Coordinates of the origin of the
C             grid.
C             Defaults: O1=0., O2=0., O3=0.
C     D1=real... Grid interval along the X1 axis.
C             Default: D1=1.
C     D2=real... Grid interval along the X2 axis.
C             Default: D2=1.
C     D3=real... Grid interval along the X3 axis.
C             Default: D3=1.
C             Note that positive values of D1, D2, D3 are recommended.
C             Negative values of D1, D2, D3 are allowed, but
C             the target grid will be treated as if Di were positive,
C             and the value of corresponding Oi were Oi+(Ni-1)*Di.
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                                                  <A NAME="mttout"></A>
C   Names of output formatted files with interpolated quantities:
C     NUM='string'... Name of the output file with N1*N2*N3 array
C             of integer values, containing the number of arrivals at
C             each gridpoint of the target grid.
C             For NUM=' ' the file is not generated.
C             <A HREF="#NUM">Description of file NUM.</A>
C             Default:  NUM='mtt-num.out'
C     MTT='string'... Name of the output file with the array of
C             values, containing for each gridpoint the travel times
C             of all determined arrivals.
C             For MTT=' ' the file is not generated.
C             <A HREF="#M*">Description of output files M*.</A>
C             Default:  MTT='mtt-tt.out'
C     MTI='string'... Name of the output file with the array of
C             values, containing for each gridpoint the imaginary
C             travel times of all determined arrivals.
C             For MTI=' ' the file is not generated.
C             <A HREF="#M*">Description of output files M*.</A>
C             Default:  MTI=' ' (the file is not generated)
C     MHIST='string'... Name of the output file with the array of
C             the ray histories of all determined arrivals.
C             <A HREF="#M*">Description of output files M*.</A>
C             Default:  MHIST=' ' (the file is not generated)
C     MP1='string', MP2='string', MP3='string'... Names of the output
C             files with the array of the first, second and third
C             component of the slowness vector (i.e. with the
C             derivatives of travel time with respect to the coordinates
C             of the point).
C             <A HREF="#M*">Description of output files M*.</A>
C             Defaults:  MP1=' ', MP2=' ', MP3=' ' (no file generated)
C     MTT11='string', MTT12='string', MTT22='string', MTT13='string',
C     MTT23='string', MTT33='string'... Names of the output files
C             with the array of the second derivatives of travel time
C             with respect to the coordinates of the point.
C             <A HREF="#M*">Description of output files M*.</A>
C             Defaults:  MTT11=' ' to MTT33=' ' (no file generated)
C     MPQ11='string'... Name of the output file with the array of the
C             component 1,1 of the 4x4 ray propagator matrix.
C     MPQ21='string'... Name of the output file with the array of the
C             component 2,1 of the 4x4 ray propagator matrix.
C     MPQ31='string'... Name of the output file with the array of the
C             component 3,1 of the 4x4 ray propagator matrix.
C     MPQ41='string'... Name of the output file with the array of the
C             component 4,1 of the 4x4 ray propagator matrix.
C     MPQ12='string'... Name of the output file with the array of the
C             component 1,2 of the 4x4 ray propagator matrix.
C     MPQ22='string'... Name of the output file with the array of the
C             component 2,2 of the 4x4 ray propagator matrix.
C     MPQ32='string'... Name of the output file with the array of the
C             component 3,2 of the 4x4 ray propagator matrix.
C     MPQ42='string'... Name of the output file with the array of the
C             component 4,2 of the 4x4 ray propagator matrix.
C     MPQ13='string'... Name of the output file with the array of the
C             component 1,3 of the 4x4 ray propagator matrix.
C     MPQ23='string'... Name of the output file with the array of the
C             component 2,3 of the 4x4 ray propagator matrix.
C     MPQ33='string'... Name of the output file with the array of the
C             component 3,3 of the 4x4 ray propagator matrix.
C     MPQ43='string'... Name of the output file with the array of the
C             component 4,3 of the 4x4 ray propagator matrix.
C     MPQ14='string'... Name of the output file with the array of the
C             component 1,4 of the 4x4 ray propagator matrix.
C     MPQ24='string'... Name of the output file with the array of the
C             component 2,4 of the 4x4 ray propagator matrix.
C     MPQ34='string'... Name of the output file with the array of the
C             component 3,4 of the 4x4 ray propagator matrix.
C     MPQ44='string'... Name of the output file with the array of the
C             component 4,4 of the 4x4 ray propagator matrix.
C             <A HREF="#M*">Description of output files M*.</A>
C             Defaults:  MPQ*=' ' (no file generated)
C     GBW11='string'... Name of the output file containing the grid
C             values of the sum of squares of Gaussian beam widths
C             corresponding to GBY11.
C             The sum of squares of Gaussian beam widths is defined here
C             as the trace of the inverse imaginary part of the matrix
C             of second derivatives of the travel time of the Gaussian
C             beam.  The sum of squares of Gaussian beam widths depends
C             on parameters GBEij, GBR11, GBR12, GBR22, GBY11 and GBY22
C             described below.  It may be expressed as sum W11+W22,
C             where W11 is dependent on GBY11 but independent on GBY22,
C             and W22 is dependent on GBY22 but independent on GBY11.
C             Values of W11 are written to the file given by parameter
C             GBW11.
C             Note that positive GBY11 must be specified in order to
C             generate file GBW11.
C             Default:  GBW11=' ' (no file generated)
C     GBW1='string'... Name of the output file containing the grid
C             values of SQRT(W11).  See the description of GBW11.
C             Note that positive GBY11 must be specified in order to
C             generate file GBW1.
C             Default:  GBW1=' ' (no file generated)
C     GBW22='string'... Name of the output file containing the grid
C             values of the sum W22 of squares of Gaussian beam widths
C             corresponding to GBY22.  See the description of GBW11.
C             Note that positive GBY22 must be specified in order to
C             generate file GBW22.
C             Default:  GBW22=' ' (no file generated)
C     GBW2='string'... Name of the output file containing the grid
C             values of SQRT(W22).  See the description of GBW11.
C             Note that positive GBY22 must be specified in order to
C             generate file GBW2.
C             Default:  GBW2=' ' (no file generated)
C     AMP='string'... Name of the output file with the grid values of
C             the norm of the vectorial amplitude of the Green function.
C             Default:  AMP=' ' (no file generated)
C     AMPKI='string'... Name of the output file with the grid values of
C             the amplitude modified for use in the Kirchoff integral.
C             If you choose this option, do not forget to specify the
C             values of AMPKI1, AMPKI2 or AMPKI3.
C             Default:  AMPKI=' ' (no file generated)
C     AMPR11='string',AMPI11='string',AMPR21='string',AMPI21='string',
C     AMPR31='string',AMPI31='string',AMPR12='string',AMPI12='string',
C     AMPR22='string',AMPI22='string',AMPR32='string',AMPI32='string',
C     AMPR13='string',AMPI13='string',AMPR23='string',AMPI23='string',
C     AMPR33='string',AMPI33='string'... Names of the output files
C             with the grid values of the real or imaginary part of the
C             vectorial amplitude of the Green function.
C             Default: AMPRij=' ', AMPIij=' ' (no file generated)
C     MX4='string', MX5='string', MX6='string'... Names of the output
C             files with the X1, X2 and X3 coordinates of the initial
C             point of the ray corresponding to the arrival. (In case of
C             point source the coordinates of the source.)
C             Default:  MX4=' ', MX5=' ', MX6=' ' (no file generated)
C     MP4='string', MP5='string', MP6='string'... Names of the output
C             files with the derivatives of travel time with respect
C             to the coordinates of the source (i.e. three components of
C             the vector opposite to the slowness vector in the source).
C             Default:  MP4=' ', MP5=' ', MP6=' ' (no file generated)
C                                                   <A NAME="mttq1"></A>
C   Numerical parameters specifying the interpolated quantities:
C     MTTLIN=integer... Switch between bicubic and bilinear
C             interpolation of travel times:
C             MTTLIN=0 ... Bicubic interpolation
C             MTTLIN=1 ... Bilinear interpolation
C             Default: MTTLIN=0
C     TTDMAX=real... Maximum value of the second travel-time derivatives
C             MTT11 to MTT33. If the derivative is greater, it is
C             replaced by TTDMAX.  Note that TTDMAX is applied during
C             the calculation of the values of the derivatives in the
C             points along the rays, which are then used during the
C             interpolation.
C             Default:  TTDMAX=999999.
C     GBE11=real, GBE21=real, GBE31=real... Components of the first of
C             two vectors specifying the plane in which the initial
C             second derivatives of the complex-valued travel times of
C             Gaussian beams are given.  The vectors are basis vectors
C             of the linear coordinate system for the specification
C             of the second derivatives.
C             Defaults:  GBE11=0., GBE21=1., GBE31=0.
C     GBE12=real, GBE22=real, GBE32=real... Components of the second of
C             two vectors specifying the plane and coordinates for the
C             initial second derivatives of the complex-valued travel
C             times of Gaussian beams.
C             Defaults:  GBE12=1., GBE22=0., GBE32=0.
C     GBR11=real, GBR12=real, GBR22=real... Real part of the second
C             derivatives of the complex-valued travel times of Gaussian
C             beams in the directions of vectors GBEi1 and GBEi2.
C             Defaults:  GBR11=0., GBR12=0., GBR22=0.
C     GBY11=real, GBY22=real... Imaginary part of the second derivatives
C             of the complex-valued travel times of Gaussian beams in
C             the directions of vectors GBEi1 and GBEi2.
C             Vectors GBEi1 and GBEi2 are assumed to be specified in
C             such a way that mixed second derivatives GBY12=0.
C             Defaults:  GBY11=0., GBY22=0.
C     FGBE11='string',FGBE21='string',FGBE31='string',FGBE12='string',
C     FGBE22='string',FGBE32='string',FGBR11='string',FGBR12='string',
C     FGBR22='string',FGBY11='string',FGBY22='string'... Filenames
C             corresponding to the above quantities, if the quantities
C             depend on two-way travel time and ray parameters and
C             are specified on an optional ray-parameter grid of
C             NTIME*NPAR1*NPAR2*NWAVES*NCRT values, see the grid
C             parameters below.
C             Undefined grid values are allowed only at the gridpoints
C             not used during interpolation within ray cells.
C             If the filename is blank, a constant value given by the
C             corresponding real-valued parameter is used.
C             Defaults:  All blank.
C     FTIME='string'... Name of the file containing two-way travel time,
C             gridded in dependence on travel times (inner loop) and ray
C             parameters.  NTT*NPAR1*NPAR2*NWAVES*NCRT values.
C             Undefined grid values are allowed only at the gridpoints
C             not used during interpolation within ray cells.
C             If FTIME is blank, two-way travel time is deemed to
C             coincide with the travel time and parameters NTT, OTT, DTT
C             need not be specified.
C             Default:  FTIME=' '
C     AMPMAX=real... Maximum value of the amplitude AMP of the Green
C             function. If the amplitude is greater, it is replaced
C             by AMPMAX.  Note that AMPMAX is applied during the
C             calculation of the values of the Green function in the
C             points along the rays, which are then used during the
C             interpolation.
C             Similarly, AMPMAX and -AMPMAX are used as the limits for
C             the individual components AMPR11 to AMPI33 of the
C             vectorial amplitude.
C             Default:  AMPMAX=999999.
C     AMP2D1=real, AMP2D2=real, AMP2D3=real... Unit vector perpendicular
C             to a 2-D section in the 3-D model.
C             Writing the amplitudes of the 2-D Green function instead
C             of those of the 3-D Green function.
C             Default: AMP2D1=0., AMP2D2=0., AMP2D3=0.
C                      (amplitudes of the 3-D Green function)
C     AMPKI1=real, AMPKI2=real, AMPKI3=real... Unit vector perpendicular
C             to the surface of integration, multiplied by the surface
C             area or line length corresponding to one surface point.
C             Modification of amplitudes for Kirchhoff integral.
C             Default: AMPKI1=0., AMPKI2=0., AMPKI3=0.
C     QIPV=integer... Optional quasi-isotropic approximation of the
C             polarization vectors.
C             QIPV=0: Correct polarization vectors read from the input
C               file are used.
C             QIPV=1: Quasi-isotropic approximation of the polarization
C               vectors: The basis vectors of the ray-centred coordinate
C               system are used in place of the polarization vectors.
C               This option corresponds to versions 6.60 and older of
C               this program.
C             Default: QIPV=0
C                                                   <A NAME="mttq2"></A>
C   Numerical parameters specifying optional ray-parameter grid:
C             Number of gridpoints is NTT*NPAR1*NPAR2*NWAVES*NCRT or
C             NTIME*NPAR1*NPAR2*NWAVES*NCRT, inner loop corresponding to
C             NTT or NTIME, outer loop to NCRT.
C     NTT=positive integer... Number of travel time samples (inner loop)
C             in the file given by parameter FTIME.
C             Not used if FTIME=' '.
C             Default:  NTT=1
C     OTT=real... Travel time of the first sample in the file given by
C             parameter FTIME.
C             Not used if FTIME=' '.
C             Default:  OTT=0.
C     DTT=real... Travel-time increment in the file given by parameter
C             FTIME.
C             Not used if FTIME=' '.
C             Default:  DTT=1.
C     NTIME=positive integer... Number of two-way travel times (inner
C             loop) in the files given by parameters FGBE11, FGBE21,
C             FGBE31, FGBE12, FGBE22, FGBE32, FGBR11, FGBR12, FGBR22,
C             FGBY11 and FGBY22.  If all these filenames are blank,
C             parameters NTIME, OTIME, DTIME, NPAR1, OPAR1, DPAR1,
C             NPAR2, OPAR2, DPAR2, NWAVES, NCRT and ICRT are not used.
C             Default:  NTIME=1
C     OTIME=real... Two-way travel time of the first sample.
C             Default:  OTIME=0.
C     DTIME=real... Two-way travel-time increment.
C             Default:  DTIME=1.
C     NPAR1=positive integer... Number of gridpoints corresponding to
C             the first ray take-off parameter (inner but one loop) in
C             the files given by parameters FTIME, FGBE11, FGBE21,
C             FGBE31, FGBE12, FGBE22, FGBE32, FGBR11, FGBR12, FGBR22,
C             FGBY11 and FGBY22.
C             Default:  NPAR1=1
C     OPAR1=real... The first ray take-off parameter corresponding to
C             the first gridpoint.
C             Default:  OPAR1=0.
C     DPAR1=real... Increment of the first ray take-off parameter.
C             Default:  DPAR1=1.
C     NPAR2=positive integer... Number of gridpoints corresponding to
C             the second ray take-off parameter in the files given by
C             parameters FTIME, FGBE11, ..., FGBY22.
C             Default:  NPAR1=1
C     OPAR2=real... The second ray take-off parameter corresponding to
C             the first gridpoint.
C             Default:  OPAR2=0.
C     DPAR2=real... Increment of the second ray take-off parameter.
C             Default:  DPAR2=1.
C     NWAVES=positive integer... Maximum number of elementary waves
C             or sources per a single execution of program 'crt.for'.
C             The waves are indexed 1,2,...,NWAVES.
C             Default:  NWAVES=1
C     NCRT=positive integer... Total number of executions of program
C             'crt.for'.
C             Default:  NCRT=1
C     ICRT=positive integer... Sequential index of the execution of
C             program 'crt.for'.
C             Default:  ICRT=1
C                                                  <A NAME="points"></A>
C Data for alternative interpolation to the individual points:
C     The interpolation to the individual points is performed if the
C     name of the output file MTTPTS is specified.
C   Name of the input file with coordinates of the individual points:
C     PTS='string'... Name of the file with the points.  If MTTPTS
C             is specified, PTS must be given too.
C             <A HREF="#PTS">Description of file PTS</A>
C             Default: PTS=' '
C   Name of the output file with interpolated quantities:
C     MTTPTS='string'... Name of the output file with the interpolated
C             values.  If the name is left blank, the program performs
C             the interpolation to the gridpoints of the 3-D grid.
C             If MTTPTS is specified, PTS must be specified too,
C             and the program interpolates to the individual points
C             given in file PTS.
C             <A HREF="#MTTPTS">Description of file MTTPTS.</A>
C             Default: MTTPTS=' '  (interpolation to the 3-D grid)
C                                                  <A NAME="column"></A>
C   Parameters specifying the quantities to be written into the output
C   file MTTPTS.
C     COLUMN01='string' to COLUMN69='string'... Strings which specifie
C             the quantities to be written to the columns 1 to 69 of the
C             file MTTPTS.  First three columns usually contain
C             coordinates of the point.  Column zero is reserved for the
C             name of the point.
C             Following strings are allowed:
C             COLUMNii=' ' (a space)... Nothing is to be written to the
C               column ii and to all the following columns.
C             COLUMNii='X1'... First coordinate of the point.
C             COLUMNii='X2'... Second coordinate of the point.
C             COLUMNii='X3'... Third coordinate of the point.
C             COLUMNii='NAMEOUT'... The string specifiing the quantity
C               to be written to column ii may equal to any of
C               the names of SEP parameters used for the names
C               of output formatted files with interpolated
C               quantities when interpolating to the output 3-D
C               grid.
C               Here 'NAMEOUT' stays for any of 'NUM',
C               'MTT', 'MTI', 'MHIST', 'MP1', 'MP2', 'MP3',
C               'MTT11', 'MTT12', 'MTT22', 'MTT13', 'MTT23',
C               'MTT33',
C               'MPQ11', 'MPQ21', 'MPQ31', 'MPQ41', 'MPQ12',
C               'MPQ22', 'MPQ32', 'MPQ42', 'MPQ13', 'MPQ23',
C               'MPQ33', 'MPQ43', 'MPQ14', 'MPQ24', 'MPQ34',
C               'MPQ44', 'GBW11', 'GBW1', 'GBW22', 'GBW2',
C               'AMP', 'AMPKI', 'AMPR11' to 'AMPI33',
C               'MX4', 'MX5', 'MX6', 'MP4', 'MP5', 'MP6'.
C               <A HREF="#mttout">Description of NAMEOUT.</A>
C             All strings may be entered either in uppercase or in
C             lowercase letters.
C             Note that for COLUMNii='NUM', the sequential number of
C             the arrival is written to column ii.
C             Also note that all quantities, including number of arrival
C             or ray history, are written to MTTPTS as real values.
C             Defaults: COLUMN01='X1', COLUMN02='X2', COLUMN03='X3',
C               COLUMN04 to COLUMN69=' '.
C Projection vector for 2-D calculations:
C     PROJ1=real, PROJ2=real, PROJ3=real... Three components of the
C             projection vector which is used in 2-D computations to
C             project the coordinates of gridpoints or of the
C             individual points to the plane defined by rays.
C             If not specified (default), a vector in the
C             direction of the lowest dimension of the interpolation
C             grid is used as the projection vector in case of
C             interpolation to the grid.
C             For the case of 2-D ray field and interpolation to the
C             individual points, projection vector must be specified.
C             Default: PROJ1=0., PROJ2=0., PROJ3=0.
C                                                   <A NAME="mttq0"></A>
C Order of the multivalued interpolated quantities:
C     MTTSORT='string'... Quantity according which the multivalued
C             interpolated quantities are sorted.  The value of the
C             'string' should equal the name of one of the above SEP
C             parameters specifying the names of output formatted files
C             with interpolated quantities.
C             <A HREF="#mttout">Description of sorting parameters.</A>
C             Default: MTTSORT='MTT' (sorting according to travel times)
C     MTTORDER=real... Order of sorting:
C             MTTORDER=1 for sorting in the ascending order,
C             MTTORDER=-1 for sorting in the descending order.
C             Default: MTTORDER=1.
C Optional parameters specifying the form of the quantities
C written in the output formatted files:
C     MINDIG,MAXDIG=positive integers... See the description in file
C             <A HREF="../forms/forms.for#MAXDIG" TYPE="text/html">forms.for</A>.
C     NUMLIN=positive integer... Number of reals or integers in one
C             line of the output files NUM or M*. See the description in
C             file <A HREF="../forms/forms.for#NUMLIN" TYPE="text/html">forms.for</A>.
C
C                                                     <A NAME="NUM"></A>
C Output formatted file NUM:
C     N1*N2*N3 integers:  For each gridpoint, the number of travel
C     times determined at the gridpoint.  The innermost loop corresponds
C     to N1, the outermost loop corresponds to N3.
C     For general description of the files with gridded data refer to
C     file <A HREF="../forms/forms.htm#GRD">forms.htm</A>.
C
C                                                      <A NAME="M*"></A>
C Output formatted files M*:
C     N numbers, where N is the sum of integers in file NUM.
C     For each gridpoint, all values of a single interpolated quantity
C     determined at the gridpoint.  The values are stored in ascending
C     order according to the travel time. The loop over gridpoints
C     is the same as in file NUM.
C     For general description of the files with multivalued gridded data
C     refer to file <A HREF="../forms/forms.htm#MGRD">forms.htm</A>.
C
C                                                     <A NAME="PTS"></A>
C Input file PTS with the coordinates of points:
C (1) None to several strings terminated by / (a slash)
C (2) For each point data:
C (2.1) 'NAME',X1,X2,X3,V1,...,VN,/
C     'NAME'... Name of the point.
C     X1,X2,X3... Coordinates of the point
C     V1,...,VN... Optional values, not read by MTT.
C     /...    Values must be terminated by a slash.
C (3) / or end of file.
C
C                                                  <A NAME="MTTPTS"></A>
C Output file MTTPTS with the values interpolated in the points:
C (1) /... a slash.
C (2) For each point with at least one arrival data (2.1).  In case of
C     multivalued arrivals data (2.1) are repeated for each arrival.
C (2.1) 'NAME',R1,R2,... /
C     'NAME'... Name of the point.
C     R1,R2,... /... None to several real values terminated by a slash.
C             See parameters COLUMN01 to COLUMN69 above.
C (3) /...    A slash at the end of file.
C
C-----------------------------------------------------------------------
C
C Subroutines and external functions required:
      EXTERNAL CIEROR,CIGRID,CIREAD,CIERAS,CITUBE,CIINTP,CIWB,CIWI,
     *CIQD,CIQW,CIQRI,CIQRA,CIQI,LDWARF,CILSID,CIPPP,CILSIG,CIL2P,
     *CIDET3,CISUBD,CIQUAR,CICUBR,CIQUA,CICUB,CIAA,CIBB,
     *MTTQ,LOWER,FORM2,LENGTH,
     *ERROR,WARN,RSEP1,RSEP3T,RSEP3R,RSEP3I,WARRAY,WARRAI,INDEXI,AP00
      INTEGER LENGTH
      LOGICAL LDWARF
C     CIEROR,CIGRID,CIREAD,CIERAS,CITUBE,CIINTP,CIWB,CIWI,
C     CIQD,CIQW,CIQRI,CIQRA,CIQI,LDWARF,CILSID,CIPPP,CILSIG,CIL2P,
C     CIDET3,CISUBD,CIQUAR,CICUBR,CIQUA,CICUB,CIAA,CIBB... This file.
C     MTTQ... File <A HREF="../crt/mttq.for" TYPE="text/html">mttq.for</A>.
C     LOWER,LENGTH... File <A HREF="../forms/length.for" TYPE="text/html">length.for</A>.
C     ERROR,WARN... File <A HREF="../forms/error.for" TYPE="text/html">error.for</A>.
C     RSEP1,RSEP3I,RSEP3T,RSEP3R... File <A HREF="../forms/sep.for" TYPE="text/html">sep.for</A>.
C     WARRAI,WARRAI,FORM2... File <A HREF="../forms/forms.for" TYPE="text/html">forms.for</A>.
C     INDEXI... File <A HREF="../forms/indexi.for" TYPE="text/html">indexi.for</A>.
C     AP00... File <A HREF="../crt/ap.for" TYPE="text/html">ap.for</A>.
C
C Common block /MTTC/ to store the information about triangles and rays:
      INCLUDE 'mtt.inc'
C <A HREF="mtt.inc" TYPE="text/html">mtt.inc</A>.
C
C.......................................................................
C
C     Auxiliary storage locations:
      INTEGER IRAY1,IRAY2,IRAY3
      INTEGER I1,I2,I4,I6,INDX,INDX1,INDX2,IT1,IIT1,JWAVES
      INTEGER I
      INTEGER LU0,LU1,LU2,LU3,LU5
      PARAMETER (LU0=10,LU1=1,LU2=2,LU3=3,LU5=5)
C     LU4=4 used in CIPTS, LU=13 used in MTTQ
      REAL ORDER,AUX
      CHARACTER*80 FILSEP,FILCRT,FILE1,FILE2,FILE3,CH
      CHARACTER*52 TXTERR
      CHARACTER*6 SORT
      LOGICAL LENDT
C
C-----------------------------------------------------------------------
C
C     Reading a name of the file with the input data:
      FILSEP=' '
      WRITE(*,'(A)') '+MTT: Enter input filename: '
      READ(*,*) FILSEP
      IF (FILSEP.EQ.' ') THEN
C       <A NAME="error02"></A><FONT COLOR="RED">MTT-02</FONT>
        CALL ERROR('MTT-02: No input file specified')
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
      WRITE(*,'(A)') '+MTT: Reading input data.   '
C
C     Reading all the data from the SEP file into the memory:
      CALL RSEP1(LU1,FILSEP)
C
C     Reading filenames of the files with computed rays
C     and triangles:
      CALL RSEP3T('CRTOUT',FILCRT,' ')
      FILE1='r01.out'
      FILE2='r01i.out'
      FILE3='t01.out'
      IF (FILCRT.NE.' ') THEN
        OPEN (LU2,FILE=FILCRT,FORM='FORMATTED',STATUS='OLD')
        READ (LU2,*) FILE1,CH,FILE2,FILE3
        CLOSE (LU2)
      ENDIF
C
C     Opening the CRT output files:
      OPEN(LU1,FILE=FILE1,FORM='UNFORMATTED',STATUS='OLD')
      OPEN(LU2,FILE=FILE2,FORM='UNFORMATTED',STATUS='OLD')
      OPEN(LU3,FILE=FILE3,FORM='FORMATTED',STATUS='OLD')
C
C     Reading parameters of target grid or coordinates of target points,
C     reading filename(s) of the output file(s),
C     recording which quantities are to be written into the file(s):
      CALL CIQD
C
C     Computing parameter DWARF:
      DWARF=1.
   7  CONTINUE
        DWARF=DWARF*0.1
        AUX=1.+DWARF
      IF (LDWARF(AUX)) GOTO 7
      DWARF=DWARF*100.
C
C     Reading file with computed triangles,
C     sorting the rays in triangles:
      WRITE(*,'(A)') '+MTT: Reading the file with triangles.'
      JWAVES=0
      LENDT=.FALSE.
      READ(LU3,*,END=20) IRAY1,IRAY2,IRAY3
   8  CONTINUE
      NT=0
      NRAMP=0
      IRAYMI=999999
      IRAYMA=0
  10  CONTINUE
        IRAY1=0
        IRAY2=0
        IRAY3=0
        READ(LU3,*,END=20) IRAY1,IRAY2,IRAY3
        IF (IRAY1.EQ.0) GOTO 22
        IF ((IRAY1.LE.0).OR.(IRAY2.LE.0).OR.(IRAY3.LT.0)) THEN
C         <A NAME="error36"></A><FONT COLOR="RED">MTT-36</FONT>
          CALL ERROR('MTT-36: Disorder in file ''CRT-T''.')
C         The 'triangles' in the input file 'CRT-T' should be written
C         as three nonnegative integers (indices of rays), two of them
C         being positive (the third may equal zero in 2-D computations).
        ENDIF
        IF (IRAY1.GT.IRAYMA) IRAYMA=IRAY1
        IF (IRAY2.GT.IRAYMA) IRAYMA=IRAY2
        IF (IRAY3.GT.IRAYMA) IRAYMA=IRAY3
        IF (IRAY1.LT.IRAYMI)                    IRAYMI=IRAY1
        IF (IRAY2.LT.IRAYMI)                    IRAYMI=IRAY2
        IF ((IRAY3.NE.0).AND.(IRAY3.LT.IRAYMI)) IRAYMI=IRAY3
        IF (IRAY1.LT.IRAY2) THEN
          I=IRAY1
          IRAY1=IRAY2
          IRAY2=I
        ENDIF
        IF (IRAY2.LT.IRAY3) THEN
          I=IRAY2
          IRAY2=IRAY3
          IRAY3=I
        ENDIF
        IF (IRAY1.LT.IRAY2) THEN
          I=IRAY1
          IRAY1=IRAY2
          IRAY2=I
        ENDIF
        IF (NRAMP+3.GT.MRAMP) CALL CIEROR(1,TXTERR)
        NRAMP=NRAMP+1
        IRAM(NRAMP)=IRAY1
        NRAMP=NRAMP+1
        IRAM(NRAMP)=IRAY2
        NRAMP=NRAMP+1
        IRAM(NRAMP)=IRAY3
        NT=NT+1
      GOTO 10
  20  CONTINUE
      LENDT=.TRUE.
      CLOSE(LU3)
  22  CONTINUE
      JWAVES=JWAVES+1
      NR=IRAYMA-IRAYMI+1
C
C     Check for the 'triangles' in case of 2D computation:
      IF (IRAM(3).EQ.0) THEN
        DO 25, I1=6,3*NT,3
          IF (IRAM(I1).NE.0) THEN
C           <A NAME="error32"></A><FONT COLOR="RED">MTT-32</FONT>
            CALL ERROR('MTT-32: Disorder in triangles.')
C           The first 'triangle' is formed by two rays with zero
C           instead of the third ray. This identifies 2-D calculation
C           and all the 'triangles' should be formed by two rays and
C           zero instead of the third ray. This is not the case of the
C           current triangle. Either input file 'CRT-T'
C           is wrong, or there is a bug in the code. In the latter case,
C           please, <A HREF="#author">contact the author</A>.
          ENDIF
  25    CONTINUE
        IF ((PROJ1.EQ.0.).AND.(PROJ2.EQ.0.).AND.(PROJ3.EQ.0.)) THEN
          IF (LPTS) THEN
C           <A NAME="error06"></A><FONT COLOR="RED">MTT-06</FONT>
            CALL ERROR('MTT-06: Projection vector not specified.')
C           For the case of 2-D ray field and interpolation to the
C           individual points, the projection vector must be specified,
C           there is no default.
          ENDIF
          I1=MIN0(N1,N2,N3)
          I2=0
          IF (N1.EQ.I1) I2=I2+1
          IF (N2.EQ.I1) I2=I2+1
          IF (N3.EQ.I1) I2=I2+1
          IF (I2.GE.2) THEN
C           <A NAME="error33"></A><FONT COLOR="RED">MTT-33</FONT>
            CALL ERROR('MTT-33: No projection vector.')
C           The projection vector PROJ1(2,3), described in the
C           description of file <A HREF="#SEP">SEP</A>, was not
C           specified and the specification of the grid does not enable
C           the use of default projection vector.
          ENDIF
          IF (N1.EQ.I1) PROJ1=1.
          IF (N2.EQ.I1) PROJ2=1.
          IF (N3.EQ.I1) PROJ3=1.
        ENDIF
        L3D=.FALSE.
        L2D=.TRUE.
      ELSE
        L3D=.TRUE.
        L2D=.FALSE.
      ENDIF
C
C     Sorting the triangles:
      WRITE(*,'(A)') '+MTT: Sorting the triangles.          '
      IF (NRAMP+2*NT.GT.MRAMP) CALL CIEROR(1,TXTERR)
      DO 30, I1=NRAMP+1,NRAMP+NT
        IRAM(I1)=IRAM((I1-NRAMP-1)*3+1)
  30  CONTINUE
      CALL INDEXI(NT,IRAM(NRAMP+1),IRAM(NRAMP+NT+1))
      DO 40, I1=NRAMP+1,NRAMP+NT
        IRAM(I1)=IRAM(I1+NT)
  40  CONTINUE
      NRAMP=NRAMP+NT
C
C
C     Forming an auxiliary array with information about when can be rays
C     erased from the memory ("deleting array"):
      IF (NRAMP+NR.GT.MRAMP) CALL CIEROR(1,TXTERR)
      DO 50, I1=NRAMP+1,NRAMP+NR
        IRAM(I1)=0
  50  CONTINUE
      NRAMP=NRAMP+NR
      ORAYE=IRAYMI-1-4*NT
      DO 60, I2=3*NT+1,4*NT
        I1=(IRAM(I2)-1)*3+1
        IRAM(IRAM(I1  )-ORAYE)=IRAM(I1)
        IRAM(IRAM(I1+1)-ORAYE)=IRAM(I1)
        IF (IRAM(I1+2).NE.0) IRAM(IRAM(I1+2)-ORAYE)=IRAM(I1)
  60  CONTINUE
C
C
C     Forming an auxiliary array with information about addresses
C     of the ends of records for rays in array RAM ("addressing array"):
C     "Ray" IRAYMI-1:
      NRAMP=NRAMP+1
      IF (NRAMP.GT.MRAMP) CALL CIEROR(1,TXTERR)
      IRAM(NRAMP)=NRAMP+NR
C     All other rays:
      IF (NRAMP+NR.GT.MRAMP) CALL CIEROR(1,TXTERR)
      DO 70, I1=NRAMP+1,NRAMP+NR
        IRAM(I1)=0
  70  CONTINUE
      NRAMP=NRAMP+NR
      ORAYA=IRAYMI-1-4*NT-NR-1
C
C
C     Loop for all the triangles:
      IIT1=1
      I1=-1
  100 CONTINUE
        IT1=(IRAM(3*NT+IIT1)-1)*3+1
        I2=NINT((100.*IIT1)/(NT))
        IF (I2.NE.I1) THEN
          WRITE(*,'(''+'',79('' ''))')
          WRITE(*,'(A,1I2,A,1I4,A)')
     *    '+MTT: Interpolating wave ',JWAVES,'. ',
     *                                    I2,'% of ray tubes completed.'
          I1=I2
        ENDIF
C
C       If necessary, reading new rays:
        IF
     *  (((IRAM(IRAM(IT1)-ORAYA+1).EQ.0).AND.(IRAM(IT1).NE.IRAYMA)) .OR.
     *   ((IRAM(IRAM(IT1)-ORAYA  ).EQ.0).AND.(IRAM(IT1).EQ.IRAYMA)))
     *  CALL CIREAD(LU1,LU2,IT1)
C
C       Empting the array RAM to enable writing of possible interpolated
C       quantities:
        IF ((MRAMP-NRAMP).LT.(NINT(MAXRAM/10.))) CALL CIERAS
C
C       Interpolation along the rays of the triangle:
        CALL CITUBE(IT1)
C
      IIT1=IIT1+1
      IF (IIT1.LE.NT) GOTO 100
C     End of the loop for all the triangles.
C     End of the loop for all the triangles of the elementary wave.
      IF (.NOT.LENDT) GOTO 8
      CLOSE(LU1)
      CLOSE(LU2)
C
C
C     Sorting the results according to the travel times:
      CALL RSEP3T('MTTSORT',SORT,'mtt')
      CALL LOWER(SORT)
      CALL RSEP3R('MTTORDER',ORDER,1.)
      DO 500, I4=1,NOUT
        IF (CHOUT(I4).EQ.SORT) THEN
          IF (.NOT.LPTS) THEN
            I6=N1*N2*N3
          ELSE
            I6=NPTS
          ENDIF
          DO 310, I1=0,I6-1
  300       CONTINUE
            INDX=MAXOUT-I1
            INDX1=IRAM(INDX)
            IF (INDX1.EQ.0) GOTO 306
  302       CONTINUE
              INDX2=IRAM(INDX1)
              IF (INDX2.EQ.0) GOTO 306
              IF (ORDER*RAM(INDX2+I4).LT.ORDER*RAM(INDX1+I4)) THEN
                IRAM(INDX1)=IRAM(INDX2)
                IRAM(INDX2)=INDX1
                IRAM(INDX)=INDX2
                GOTO 300
              ENDIF
              INDX=INDX1
              INDX1=INDX2
            GOTO 302
  306       CONTINUE
  310     CONTINUE
        ENDIF
  500 CONTINUE
C
C     Writing the results of interpolation:
      CALL CIQW(LU5)
C
      WRITE(*,'(A)')
     *    '+MTT: Done.                                                 '
      STOP
      END
C
C
C=======================================================================
C
      SUBROUTINE CIREAD(LU1,LU2,IT1)
C
C----------------------------------------------------------------------
C Subroutine to read the unformatted output of program CRT and
C to write it into array (I)RAM used in program MTT.
C Reading the output files is completed by a simple invocation of
C subroutine AP00 of file 'ap.for'.
C
      INTEGER LU1,LU2,IT1
C Input:
C     LU1...  Number of logical unit corresponding to the file with
C             the quantities stored along rays.
C     LU2...  Number of logical unit corresponding to the file with
C             the quantities at the initial points of rays,
C             corresponding to file LU1.
C     IT1...  Position of the first ray of the actually processed
C             triangle in the array IRAM.
C No output.
C
C ...........................
C Common block /POINTC/ to store the results of complete ray tracing:
      INCLUDE 'pointc.inc'
C None of the storage locations of the common block are altered.
C ...........................
C Common block /MTTC/ to store the information about triangles and rays:
      INCLUDE 'mtt.inc'
C <A HREF="mtt.inc" TYPE="text/html">mtt.inc</A>.
C.......................................................................
C
C     Auxiliary storage locations:
      INTEGER IRAY0,IWAVE0,I1
      CHARACTER*52 TXTERR
C     IRAY0.. Index of the last ray read in into the array RAM.
C
C-----------------------------------------------------------------------
C     Loop for the points of rays:
   10 CONTINUE
        IF ((NRAMP+2*NQ).GT.MRAMP) THEN
C         Empting the memory:
          CALL CIERAS
          IF ((NRAMP+2*NQ).GT.MRAMP) CALL CIEROR(1,TXTERR)
        ENDIF
C       Reading the results of the complete ray tracing:
        IRAY0=IRAY
        IWAVE0=IWAVE
        IF ((IRAY0.EQ.0).AND.(IWAVE0.EQ.0)) THEN
C         Reading the first point on a ray of the first wave:
          CALL AP00(0,LU1,LU2)
          IF (IWAVE.LT.1) GOTO 20
        ELSEIF (IWAVE.EQ.IWAVE0) THEN
C         Reading the next point on a ray of the actual wave:
          CALL AP00(0,LU1,LU2)
          IF (IWAVE.NE.IWAVE0) GOTO 20
        ENDIF
        IF (IRAY.LT.IRAYMI) GOTO 10
        IF (IRAY.GT.IRAYMA) GOTO 10
        IF ((IRAY-IRAY0).GE.2) THEN
C         Some rays skipped by AP00:
          DO 15, I1=IRAY0+1,IRAY-1
            IF (I1.GE.IRAYMI) THEN
              IRAM(I1-ORAYA)=IRAM(IRAY0-ORAYA)
            ENDIF
  15      CONTINUE
        ENDIF
        IF (IRAM(IRAY-ORAYE).NE.0) THEN
C         Writing the results of the complete ray tracing - recording
C         new point on a ray:
          IF (IPT.LE.1) THEN
            IF ((ISHEET.EQ.0).AND.(IRAY.EQ.IRAYMI)) THEN
C             <A NAME="error18"></A><FONT COLOR="RED">MTT-18</FONT>
              CALL WARN
     *           ('MTT-18: a ray with history equal to 0 was observed.')
C             All the rays are probably of the same history 0. Only the
C             initial-value ray tracing was performed.  Width and shape
C             of ray tubes were not controlled.  The interpolation
C             in such a case makes sense only in smooth models.
C             Check the value of the parameter IPOINT in CRT input data
C             <A HREF="rpar.for#data4" TYPE="text/html">RPAR (4)</A>.
            ENDIF
C           New ray - recording the initial point:
C           Coordinates:
            RAM(NRAMP+1)=YI(3)
            RAM(NRAMP+2)=YI(4)
            RAM(NRAMP+3)=YI(5)
C           Index of surface:
            IRAM(NRAMP+4)=0
C           Sequential index of point:
            IRAM(NRAMP+5)=0
C           Quantities to be interpolated:
            CALL CIQRI
          ENDIF
C         Recording the new point:
C         Coordinates:
          RAM(NRAMP+1)=Y(3)
          RAM(NRAMP+2)=Y(4)
          RAM(NRAMP+3)=Y(5)
C         Index of surface:
          IRAM(NRAMP+4)=ISRF
C         Sequential index of point:
          IRAM(NRAMP+5)=IPT
C         Quantities to be interpolated:
          CALL CIQRA
        ENDIF
        IRAM(IRAY-ORAYA)=NRAMP
        IF ((IPT.LE.1).AND.(IRAY.GT.IRAM(IT1)).AND.(IRAY.NE.IRAYMA))
     *     RETURN
      GOTO 10
C
  20  CONTINUE
C     End of rays:
      IF (IRAY0.LT.IRAYMA) THEN
C       Some rays at the end of the CRT output file missing:
        DO 22, I1=IRAY0+1,IRAYMA
          IF (I1.GE.IRAYMI) THEN
            IRAM(I1-ORAYA)=NRAMP
          ENDIF
  22    CONTINUE
      ENDIF
      RETURN
      END
C
C
C=======================================================================
C
      SUBROUTINE CIERAS
C
C----------------------------------------------------------------------
C Subroutine for empting the array (I)RAM. All the parameters
C of all the rays, which will no more be used, are erased.
C
C No input.
C No output.
C
C ...........................
C Common block /POINTC/ to store the results of complete ray tracing:
      INCLUDE 'pointc.inc'
C     IRAY... Index of the ray being actually read in by CIREAD.
C             This procedure supposes, that any ray with higher
C             index than IRAY was not read in.
C None of the storage locations of the common block are altered.
C ...........................
C Common block /MTTC/ to store the information about triangles and rays:
      INCLUDE 'mtt.inc'
C <A HREF="mtt.inc" TYPE="text/html">mtt.inc</A>.
C.......................................................................
C     Auxiliary storage locations:
      INTEGER I1,I2,J1
      INTEGER IADDRP
C     I1...   Controls main loop over rays.
C     I2...   Controls the loop over parameters of ray I1.
C     J1...   address of the last used record of array RAM.
C
C-----------------------------------------------------------------------
      J1=IRAM(IRAYMI-1-ORAYA)
      IADDRP=J1
C     Loop for the rays:
      DO 20, I1=IRAYMI,IRAY
        IF (IRAM(I1-ORAYE).GE.(IRAY-1)) THEN
C         This ray is not to be erased:
          DO 10, I2=IADDRP+1,IRAM(I1-ORAYA)
            J1=J1+1
            IRAM(J1)=IRAM(I2)
   10     CONTINUE
        ELSE
C         This ray is to be erased:
          IRAM(I1-ORAYE)=0
        ENDIF
        IADDRP=IRAM(I1-ORAYA)
        IRAM(I1-ORAYA)=J1
   20 CONTINUE
      NRAMP=J1
      RETURN
      END
C=======================================================================
C
      SUBROUTINE CITUBE(IT1)
C
C----------------------------------------------------------------------
C Subroutine for interpolation within ray tube formed by the rays
C IRAM(IT1), IRAM(IT1+1), IRAM(IT1+2).
C
      INTEGER IT1
C Input:
C     IT1...  The address of the index of the first ray of the ray tube,
C             in which the interpolation is to be performed.
C No output.
C
C ...........................
      EXTERNAL CIL2P
      LOGICAL CIL2P
C ...........................
C Common block /MTTC/ to store the information about triangles and rays:
      INCLUDE 'mtt.inc'
C <A HREF="mtt.inc" TYPE="text/html">mtt.inc</A>.
C.......................................................................
      INTEGER I1B,I2B,I3B,I1C,I2C,I3C
      INTEGER I1MA,I2MA,I3MA,J1,J2
C     I1B,I2B,I3B,I1C,I2C,I3C... Integers controling main loop over
C             points on the rays (along ray tube). Numbers 1,2,3 denote
C             the first, second and third ray, character B denotes
C             bottom of the ray cell and C denotes top of the ray cell.
C             Each integer contains the address just before
C             the parameters of the corresponding point:
C             the first parameter of the first point: RAM(I1B+1)
C     J1...   Counts the number of identical points of the ray cell
C             (J1=0,1,2,3).
C     J2...   Displays maximum sequential index of a point allowed
C             for actual ray cell.
C
C-----------------------------------------------------------------------
      IF (         (IRAM(IRAM(IT1  )-ORAYA).EQ.0).OR.
     *             (IRAM(IRAM(IT1+1)-ORAYA).EQ.0).OR.
     *    (L3D.AND.(IRAM(IRAM(IT1+2)-ORAYA).EQ.0))) THEN
C       <A NAME="error03"></A><FONT COLOR="RED">MTT-03</FONT>
        CALL ERROR
     *     ('MTT-03: Parameters of a ray not found in memory in CITUBE')
C       This error may be caused by
C       <A HREF="writ.for#data" TYPE="text/html">K2P </A>
C       not equal to zero, then only two-point rays are stored in
C       output files of CRT. We recommend to run CRT with file
C       <A HREF="../crt/writall.dat" TYPE="text/html">writall.dat</A>.
      ENDIF
C
      I1MA=IRAM(IRAM(IT1  )-ORAYA)-NQ
      I2MA=IRAM(IRAM(IT1+1)-ORAYA)-NQ
      IF (L3D) I3MA=IRAM(IRAM(IT1+2)-ORAYA)-NQ
C     The first ray cell:
      I1B=IRAM(IRAM(IT1  )-ORAYA-1)
      I2B=IRAM(IRAM(IT1+1)-ORAYA-1)
      IF (L3D) I3B=IRAM(IRAM(IT1+2)-ORAYA-1)
      IF ((I1B.GT.I1MA).OR.(I2B.GT.I2MA).OR.(L3D.AND.(I3B.GT.I3MA)))
     *  RETURN
      I1C=I1B
      I2C=I2B
      IF (L3D) I3C=I3B
C     Loop for points on the rays (loop for ray cells):
C     J1 counts the number of points, which were not shifted.
C     J2 displays the sequential number of points, which is the
C        maximum allowed number for current cell.
  10  CONTINUE
        IF (L3D) THEN
          J1=3
          J2=MAX0(IRAM(I1B+5),IRAM(I2B+5),IRAM(I3B+5))
          IF ((IRAM(I1B+5).EQ.IRAM(I2B+5)).AND.
     *        (IRAM(I1B+5).EQ.IRAM(I3B+5)))  J2=J2+1
        ELSE
          J1=2
          J2=MAX0(IRAM(I1B+5),IRAM(I2B+5))
          IF (IRAM(I1B+5).EQ.IRAM(I2B+5))  J2=J2+1
        ENDIF
C       Forming standard ray cells: ----------------------------------
        IF ((IRAM(I1B+4).EQ.0).AND.(IRAM(I1B+5).LT.J2)) THEN
          I1C=I1B+NQ
          J1=J1-1
        ENDIF
        IF ((IRAM(I2B+4).EQ.0).AND.(IRAM(I2B+5).LT.J2)) THEN
          I2C=I2B+NQ
          J1=J1-1
        ENDIF
        IF (L3D) THEN
          IF ((IRAM(I3B+4).EQ.0).AND.(IRAM(I3B+5).LT.J2)) THEN
            I3C=I3B+NQ
            J1=J1-1
          ENDIF
        ENDIF
ccC       Forming degenerate ray cells (tetrahedrons): -----------------
cc        IF ((IRAM(I1B+4).EQ.0).AND.(IRAM(I1B+5).LT.J2)) THEN
cc          I1C=I1B+NQ
cc          J1=J1-1
cc        ELSE
cc          IF ((IRAM(I2B+4).EQ.0).AND.(IRAM(I2B+5).LT.J2)) THEN
cc            I2C=I2B+NQ
cc            J1=J1-1
cc          ELSE
cc            IF (L3D) THEN
cc              IF ((IRAM(I3B+4).EQ.0).AND.(IRAM(I3B+5).LT.J2)) THEN
cc                I3C=I3B+NQ
cc                J1=J1-1
cc              ENDIF
cc            ENDIF
cc          ENDIF
cc        ENDIF
C       ----------------------------------------------------------------
        IF ((L3D.AND.(J1.EQ.3)).OR.(L2D.AND.(J1.EQ.2))) THEN
          IF (L3D.AND.(IRAM(I1B+4).EQ.IRAM(I2B+4)).AND.
     *                (IRAM(I1B+4).EQ.IRAM(I3B+4))) THEN
C           Crossing the interface in 3D:
            I1B=I1B+NQ
            I2B=I2B+NQ
            I3B=I3B+NQ
            J1=0
            IF ((I1B.GT.I1MA).OR.(I2B.GT.I2MA).OR.(I3B.GT.I3MA))
     *        RETURN
            IRAM(I1B+4)=0
            IRAM(I2B+4)=0
            IRAM(I3B+4)=0
            I1C=I1B
            I2C=I2B
            I3C=I3B
            GOTO 10
          ELSEIF (L2D.AND.(IRAM(I1B+4).EQ.IRAM(I2B+4))) THEN
C           Crossing the interface in 2D:
            I1B=I1B+NQ
            I2B=I2B+NQ
            J1=0
            IF ((I1B.GT.I1MA).OR.(I2B.GT.I2MA))
     *        RETURN
            IRAM(I1B+4)=0
            IRAM(I2B+4)=0
            I1C=I1B
            I2C=I2B
            GOTO 10
          ELSE
C           Moving the points in a complex block:
C           Forming standard ray cells: ------------------------------
            IF (IRAM(I1B+4).EQ.0) THEN
              I1C=I1B+NQ
              J1=J1-1
            ENDIF
            IF (IRAM(I2B+4).EQ.0) THEN
              I2C=I2B+NQ
              J1=J1-1
            ENDIF
            IF (L3D) THEN
              IF (IRAM(I3B+4).EQ.0) THEN
                I3C=I3B+NQ
                J1=J1-1
              ENDIF
            ENDIF
ccC           Forming degenerate ray cells (tetrahedrons): -------------
cc            IF (IRAM(I1B+4).EQ.0) THEN
cc              I1C=I1B+NQ
cc              J1=J1-1
cc            ELSE
cc              IF (IRAM(I2B+4).EQ.0) THEN
cc                I2C=I2B+NQ
cc                J1=J1-1
cc              ELSE
cc                IF (L3D) THEN
cc                  IF (IRAM(I3B+4).EQ.0) THEN
cc                    I3C=I3B+NQ
cc                    J1=J1-1
cc                  ENDIF
cc                ENDIF
cc              ENDIF
cc            ENDIF
C             ----------------------------------------------------------
            IF ((L3D.AND.(J1.EQ.3)).OR.(L2D.AND.(J1.EQ.2))) THEN
              IF ((I1B.GE.I1MA).AND.(I2B.GE.I2MA).AND.(I3B.GE.I3MA).AND.
     *            L3D) RETURN
              IF ((I1B.GE.I1MA).AND.(I2B.GE.I2MA).AND.L2D) RETURN
C             <A NAME="error04"></A><FONT COLOR="RED">MTT-04</FONT>
              CALL ERROR
     *              ('MTT-04: The points reached different interfaces.')
C             This error should not appear.
C             Please <A HREF="#author">contact the author</A>.
            ENDIF
          ENDIF
        ENDIF
        IF ((I1C.GT.I1MA).OR.(I2C.GT.I2MA).OR.
     *      (L3D.AND.(I3C.GT.I3MA))) THEN
C         <A NAME="error05"></A><FONT COLOR="RED">MTT-05</FONT>
          CALL ERROR('MTT-05: point exceeded the ray.')
C         This error should not appear.
C         Please <A HREF="#author">contact the author</A>.
        ENDIF
C
C       The ray cell formed by points, whose parameters can be found
C       just behind the addresses I1B,I2B,(I3B,)I1C,I2C,(I3C,)
C       is prepared for interpolation:
        IF (L3D) THEN
C         3-D case:
          IF(
     *     ((CIL2P(I1B,I2B).AND.CIL2P(I2B,I3B).AND.CIL2P(I1B,I3B)).AND.
     *      (CIL2P(I1C,I2C).AND.CIL2P(I2C,I3C).AND.CIL2P(I1C,I3C))).AND.
     *      (CIL2P(I1B,I1C).OR.CIL2P(I2B,I2C).OR.CIL2P(I3B,I3C))   )THEN
C           Ray cell formed by 4, 5 or 6 points. The
C           bottom and the top of the ray cell are triangles
C           (i.e. they are formed by different points), the three sides
C           of the ray cell are formed by lines, triangles or tetragons.
            CALL CIINTP(I1B,I2B,I3B,I1C,I2C,I3C)
          ENDIF
        ELSE
C         2-D case:
C         To prevent from calling undefined values:
                                                   I3B=I2B
                                                   I3C=I2C
          IF ((CIL2P(I1B,I2B).AND.CIL2P(I1C,I2C)).AND.
     *        (CIL2P(I1B,I1C).OR.CIL2P(I2B,I2C))) THEN
C           Ray cell formed by 3 or 4 points.
            CALL CIINTP(I1B,I2B,I3B,I1C,I2C,I3C)
          ENDIF
        ENDIF
        I1B=I1C
        I2B=I2C
        IF (L3D) I3B=I3C
      GOTO 10
C     End of the loop along the ray tube.
      END
C=======================================================================
C
      SUBROUTINE CIWI(I1B,I2B,I3B,I1C,I2C,I3C,X1,X2,X3,WB,WC,
     *                W1,W2,W3)
C
C----------------------------------------------------------------------
C Subroutine for the computation of the local coordinates w1,w2,w3.
      INTEGER I1B,I2B,I3B,I1C,I2C,I3C
      REAL X1,X2,X3,WB,WC,W1,W2,W3
C Input:
C     I1B,I2B,I3B,I1C,I2C,I3C... Integers specifying the six
C             points on the rays, which define the ray cell.
C             Numbers 1,2,3 denote the first, second and third ray,
C             character B denotes the bottom of the ray cell and C
C             denotes the top of the ray cell.
C             Each integer contains the address just before
C             the parameters of the corresponding point:
C             the first parameter of the first point: RAM(I1B+1)
C             In 2-D computations I3B and I3C need not be specified.
C     X1,X2,X3... Coordinates of the examined point.
C     WB,WC... Already computed local coordinates.
C Output:
C     W1,W2,W3... Computed values of the local coordinates W1,W2,W3.
C             In 2-D computations W3 is not computed.
C
C ...........................
C Common block /MTTC/ to store the information about triangles and rays:
      INCLUDE 'mtt.inc'
C <A HREF="mtt.inc" TYPE="text/html">mtt.inc</A>.
C.......................................................................
      REAL A11,A21,A31,A12,A22,A32,A13,A23,A33,B11,B21,B31,B12,B22,B32
      REAL A1,A2,UU11,UU21,UU12,UU22,VV1,VV2,DETUU,AUX
      REAL XA1,XA2,XA3,AA1,AA2,AA3,E1,E2,E3,EE
      EQUIVALENCE (E1,PROJ1),(E2,PROJ2),(E3,PROJ3)
C-----------------------------------------------------------------------
      W1=0.
      W2=0.
      W3=0.
      A11=WB*RAM(I1B+1) + WC*RAM(I1C+1)
      A21=WB*RAM(I1B+2) + WC*RAM(I1C+2)
      A31=WB*RAM(I1B+3) + WC*RAM(I1C+3)
      A12=WB*RAM(I2B+1) + WC*RAM(I2C+1)
      A22=WB*RAM(I2B+2) + WC*RAM(I2C+2)
      A32=WB*RAM(I2B+3) + WC*RAM(I2C+3)
      IF (L2D) THEN
C       2-D case:
        XA1=X1-A12
        XA2=X2-A22
        XA3=X3-A32
        AA1=WB*(RAM(I1B+1)-RAM(I2B+1)) + WC*(RAM(I1C+1)-RAM(I2C+1))
        AA2=WB*(RAM(I1B+2)-RAM(I2B+2)) + WC*(RAM(I1C+2)-RAM(I2C+2))
        AA3=WB*(RAM(I1B+3)-RAM(I2B+3)) + WC*(RAM(I1C+3)-RAM(I2C+3))
        EE=E1*E1+E2*E2+E3*E3
        AUX=(AA1*AA1+AA2*AA2+AA3*AA3)*EE-(AA1*E1+AA2*E2+AA3*E3)**2
        IF (AUX.NE.0.) THEN
          W1=(XA1*AA1+XA2*AA2+XA3*AA3)*EE -
     *       (XA1*E1+XA2*E2+XA3*E3)*(AA1*E1+AA2*E2+AA3*E3)
          W1=W1/AUX
          W2=1. - W1
          IF (ABS(W1-1.).LT.DWARF) THEN
            XA1=X1-A11
            XA2=X2-A21
            XA3=X3-A31
            AA1=-AA1
            AA2=-AA2
            AA3=-AA3
            AUX=(AA1*AA1+AA2*AA2+AA3*AA3)*EE-(AA1*E1+AA2*E2+AA3*E3)**2
            IF (AUX.NE.0.) THEN
              W2=(XA1*AA1+XA2*AA2+XA3*AA3)*EE -
     *           (XA1*E1+XA2*E2+XA3*E3)*(AA1*E1+AA2*E2+AA3*E3)
              W2=W2/AUX
              W1=1. - W2
            ENDIF
          ENDIF
        ENDIF
      ELSE
C       3-D case:
        A13=WB*RAM(I3B+1) + WC*RAM(I3C+1)
        A23=WB*RAM(I3B+2) + WC*RAM(I3C+2)
        A33=WB*RAM(I3B+3) + WC*RAM(I3C+3)
        A11=WB*(RAM(I1B+1)-RAM(I3B+1)) + WC*(RAM(I1C+1)-RAM(I3C+1))
        A21=WB*(RAM(I1B+2)-RAM(I3B+2)) + WC*(RAM(I1C+2)-RAM(I3C+2))
        A31=WB*(RAM(I1B+3)-RAM(I3B+3)) + WC*(RAM(I1C+3)-RAM(I3C+3))
        A12=WB*(RAM(I2B+1)-RAM(I3B+1)) + WC*(RAM(I2C+1)-RAM(I3C+1))
        A22=WB*(RAM(I2B+2)-RAM(I3B+2)) + WC*(RAM(I2C+2)-RAM(I3C+2))
        A32=WB*(RAM(I2B+3)-RAM(I3B+3)) + WC*(RAM(I2C+3)-RAM(I3C+3))
        A13=X1-A13
        A23=X2-A23
        A33=X3-A33
        A1=SQRT(A11*A11+A21*A21+A31*A31)
        A2=SQRT(A12*A12+A22*A22+A32*A32)
        B11=A11*A2+A12*A1
        B21=A21*A2+A22*A1
        B31=A31*A2+A32*A1
        B12=A11*A2-A12*A1
        B22=A21*A2-A22*A1
        B32=A31*A2-A32*A1
        UU11=B11*A11+B21*A21+B31*A31
        UU21=B12*A11+B22*A21+B32*A31
        UU12=B11*A12+B21*A22+B31*A32
        UU22=B12*A12+B22*A22+B32*A32
        VV1 =B11*A13+B21*A23+B31*A33
        VV2 =B12*A13+B22*A23+B32*A33
        DETUU=UU11*UU22-UU12*UU21
C       Determinant eq zero in case of infinitely thin ray cell,
C       in such a case gridpoint cannot lie inside the cell.
        IF (DETUU.NE.0.) THEN
          AUX=(UU22*VV1-UU12*VV2)/DETUU
          W1=AUX
          AUX=(UU11*VV2-UU21*VV1)/DETUU
          W2=AUX
          W3=1.-W1-W2
        ENDIF
      ENDIF
      RETURN
      END
C=======================================================================
C
      SUBROUTINE CIINTP(I1B,I2B,I3B,I1C,I2C,I3C)
C
C----------------------------------------------------------------------
C Subroutine for interpolation within standard ray cell formed by the
C points I1B,I2B,I3B,I1C,I2C,I3C in 3-D or by points I1B,I2B,I1C,I2C
C in 2-D.
C
      INTEGER I1B,I2B,I3B,I1C,I2C,I3C
C Input:
C     I1B,I2B,I3B,I1C,I2C,I3C... Integers specifying the six
C             points on the rays, which define the ray cell.
C             Numbers 1,2,3 denote the first, second and third ray,
C             character B denotes the bottom of the ray cell and C
C             denotes the top of the ray cell.
C             Each integer contains the address just before
C             the parameters of the corresponding point:
C             the first parameter of the first point: RAM(I1B+1)
C No output.
C
C Subroutines and external functions required:
      EXTERNAL CIPPP,CILSIG
      REAL CIPPP
      LOGICAL CILSIG
C
C ...........................
C Common block /MTTC/ to store the information about triangles and rays:
      INCLUDE 'mtt.inc'
C <A HREF="mtt.inc" TYPE="text/html">mtt.inc</A>.
C.......................................................................
      INTEGER K1MI,K1MA,K2MI,K2MA,K3MI,K3MA
      REAL AUX
      INTEGER I1,I2,I3
      REAL DWB,DWI,HEIG,WID
      PARAMETER (DWB=0.001)
      REAL X1,X2,X3
      INTEGER INDX
      REAL ERRMAX
C     DWB...  The points with local coordinates wb,wc from
C             range [0-DWB,1+DWB] are taken into account.
C             The points with local coordinates wb,wc from range
C             [0+DWB,1-DWB] are considered to lie within the ray cell.
C             For the other points further check is done.
C     DWI...  Range [0-DWI,1+DWI] is used for local coordinates
C             w1,w2,w3.
C     HEIG,WID... Average height and average width of the ray cell.
C             Averaged heights of the triangles forming the top
C             and the bottom of the ray cell are considered as the
C             average cell's width.
C-----------------------------------------------------------------------
      IF (.NOT.LPTS) THEN
C       Interpolation to the grid:
C       Choosing gridpoints, which may be contained in the ray cell:
        IF (L2D) THEN
          I1=0
          IF (PROJ1.EQ.0.) I1=I1+1
          IF (PROJ2.EQ.0.) I1=I1+1
          IF (PROJ3.EQ.0.) I1=I1+1
          IF (I1.EQ.3) THEN
C           In this case all the gridpoints may be inside the cell:
            K1MI=0
            K1MA=N1-1
            K2MI=0
            K2MA=N2-1
            K3MI=0
            K3MA=N3-1
            GOTO 10
          ENDIF
        ENDIF
        AUX=(AMIN1(RAM(I1B+1),RAM(I2B+1),RAM(I3B+1),
     *             RAM(I1C+1),RAM(I2C+1),RAM(I3C+1)) - O1 ) / D1
        IF (AUX.GT. GIANT) AUX= GIANT
        IF (AUX.LT.-GIANT) AUX=-GIANT
        K1MI=MAX0(0,NINT(AUX))
        IF (L2D.AND.(PROJ1.NE.0.)) K1MI=0
        AUX=(AMAX1(RAM(I1B+1),RAM(I2B+1),RAM(I3B+1),
     *             RAM(I1C+1),RAM(I2C+1),RAM(I3C+1)) - O1 ) / D1
        IF (AUX.GT. GIANT) AUX= GIANT
        IF (AUX.LT.-GIANT) AUX=-GIANT
        K1MA=MIN0(N1-1,NINT(AUX))
        IF (L2D.AND.(PROJ1.NE.0.)) K1MA=N1-1
        IF (K1MA.LT.K1MI) RETURN
        AUX=(AMIN1(RAM(I1B+2),RAM(I2B+2),RAM(I3B+2),
     *             RAM(I1C+2),RAM(I2C+2),RAM(I3C+2)) - O2 ) / D2
        IF (AUX.GT. GIANT) AUX= GIANT
        IF (AUX.LT.-GIANT) AUX=-GIANT
        K2MI=MAX0(0,NINT(AUX))
        IF (L2D.AND.(PROJ2.NE.0.)) K2MI=0
        AUX=(AMAX1(RAM(I1B+2),RAM(I2B+2),RAM(I3B+2),
     *             RAM(I1C+2),RAM(I2C+2),RAM(I3C+2)) - O2 ) / D2
        IF (AUX.GT. GIANT) AUX= GIANT
        IF (AUX.LT.-GIANT) AUX=-GIANT
        K2MA=MIN0(N2-1,NINT(AUX))
        IF (L2D.AND.(PROJ2.NE.0.)) K2MA=N2-1
        IF (K2MA.LT.K2MI) RETURN
        AUX=(AMIN1(RAM(I1B+3),RAM(I2B+3),RAM(I3B+3),
     *             RAM(I1C+3),RAM(I2C+3),RAM(I3C+3)) - O3 ) / D3
        IF (AUX.GT. GIANT) AUX= GIANT
        IF (AUX.LT.-GIANT) AUX=-GIANT
        K3MI=MAX0(0,NINT(AUX))
        IF (L2D.AND.(PROJ3.NE.0.)) K3MI=0
        AUX=(AMAX1(RAM(I1B+3),RAM(I2B+3),RAM(I3B+3),
     *             RAM(I1C+3),RAM(I2C+3),RAM(I3C+3)) - O3 ) / D3
        IF (AUX.GT. GIANT) AUX= GIANT
        IF (AUX.LT.-GIANT) AUX=-GIANT
        K3MA=MIN0(N3-1,NINT(AUX))
        IF (L2D.AND.(PROJ3.NE.0.)) K3MA=N3-1
        IF (K3MA.LT.K3MI) RETURN
      ENDIF
C
  10  CONTINUE
C
C     Checking whether all the rays of the top (bottom) of the ray cell
C     are on the same side of the bottom (top) of the ray cell:
      IF (L3D.AND.I1B.NE.I1C.AND.I2B.NE.I2C.AND.I3B.NE.I3C) THEN
        IF (.NOT.CILSIG(
     *    CIPPP(I1B,I2B,I1B,I3B,I1B,RAM(I1C+1),RAM(I1C+2),RAM(I1C+3)),
     *    CIPPP(I1B,I2B,I1B,I3B,I1B,RAM(I2C+1),RAM(I2C+2),RAM(I2C+3)),
     *    CIPPP(I1B,I2B,I1B,I3B,I1B,RAM(I3C+1),RAM(I3C+2),RAM(I3C+3)),
     *          0.)) RETURN
        IF (.NOT.CILSIG(
     *    CIPPP(I1C,I2C,I1C,I3C,I1C,RAM(I1B+1),RAM(I1B+2),RAM(I1B+3)),
     *    CIPPP(I1C,I2C,I1C,I3C,I1C,RAM(I2B+1),RAM(I2B+2),RAM(I2B+3)),
     *    CIPPP(I1C,I2C,I1C,I3C,I1C,RAM(I3B+1),RAM(I3B+2),RAM(I3B+3)),
     *          0.)) RETURN
      ENDIF
C
      AUX=4.
      ERRMAX=RAM(I1B+1)**2+RAM(I2B+1)**2+RAM(I3B+1)**2
     *      +RAM(I1C+1)**2+RAM(I2C+1)**2+RAM(I3C+1)**2
     *      +RAM(I1B+2)**2+RAM(I2B+2)**2+RAM(I3B+2)**2
     *      +RAM(I1C+2)**2+RAM(I2C+2)**2+RAM(I3C+2)**2
      IF (L3D) THEN
        ERRMAX=ERRMAX
     *      +RAM(I1B+3)**2+RAM(I2B+3)**2+RAM(I3B+3)**2
     *      +RAM(I1C+3)**2+RAM(I2C+3)**2+RAM(I3C+3)**2
        AUX=6.
      ENDIF
      ERRMAX=ERRMAX/AUX*DWARF**2
C
      AUX=2.
      HEIG=      (RAM(I1C+1)-RAM(I1B+1))**2+(RAM(I1C+2)-RAM(I1B+2))**2+
     *           (RAM(I1C+3)-RAM(I1B+3))**2+
     *           (RAM(I2C+1)-RAM(I2B+1))**2+(RAM(I2C+2)-RAM(I2B+2))**2+
     *           (RAM(I2C+3)-RAM(I2B+3))**2
      IF (L3D)THEN
        HEIG=HEIG+(RAM(I3C+1)-RAM(I3B+1))**2+(RAM(I3C+2)-RAM(I3B+2))**2
     *           +(RAM(I3C+3)-RAM(I3B+3))**2
        AUX=3.
      ENDIF
      HEIG=SQRT(HEIG/AUX)
C
      AUX=2.
      WID=      (RAM(I1B+1)-RAM(I2B+1))**2+(RAM(I1B+2)-RAM(I2B+2))**2+
     *          (RAM(I1B+3)-RAM(I2B+3))**2+
     *          (RAM(I1C+1)-RAM(I2C+1))**2+(RAM(I1C+2)-RAM(I2C+2))**2+
     *          (RAM(I1C+3)-RAM(I2C+3))**2
      IF (L3D) THEN
        WID=WID+(RAM(I2B+1)-RAM(I3B+1))**2+(RAM(I2B+2)-RAM(I3B+2))**2+
     *          (RAM(I2B+3)-RAM(I3B+3))**2+
     *          (RAM(I2C+1)-RAM(I3C+1))**2+(RAM(I2C+2)-RAM(I3C+2))**2+
     *          (RAM(I2C+3)-RAM(I3C+3))**2+
     *          (RAM(I3B+1)-RAM(I1B+1))**2+(RAM(I3B+2)-RAM(I1B+2))**2+
     *          (RAM(I3B+3)-RAM(I1B+3))**2+
     *          (RAM(I3C+1)-RAM(I1C+1))**2+(RAM(I3C+2)-RAM(I1C+2))**2+
     *          (RAM(I3C+3)-RAM(I1C+3))**2
        AUX=6./(SQRT(3.)/2.)
      ENDIF
      WID=SQRT(WID/AUX)
C
      DWI=DWB*HEIG/WID
C
      IF (.NOT.LPTS) THEN
C       Interpolation to the grid:
C       Loop for all the selected gridpoints:
        DO 19, I1=K1MI,K1MA
        DO  18, I2=K2MI,K2MA
        DO  17, I3=K3MI,K3MA
          X1=O1+D1*FLOAT(I1)
          X2=O2+D2*FLOAT(I2)
          X3=O3+D3*FLOAT(I3)
          INDX=I3*N1*N2+I2*N1+I1+1
          INDX=MAXOUT-INDX+1
          CALL CIINT2(I1B,I2B,I3B,I1C,I2C,I3C,X1,X2,X3,INDX,ERRMAX,DWI)
  17    CONTINUE
  18    CONTINUE
  19    CONTINUE
      ELSE
C       Interpolation to the individual points:
        DO 25, I1=1,NPTS
          I2=MAXRAM-(3*I1)
          X1=RAM(I2+1)
          X2=RAM(I2+2)
          X3=RAM(I2+3)
          INDX=MAXOUT-I1+1
          IF (.NOT.(L2D.AND.(PROJ1.NE.0.))) THEN
            IF ((X1.LT.AMIN1(RAM(I1B+1),RAM(I2B+1),RAM(I3B+1),
     *                       RAM(I1C+1),RAM(I2C+1),RAM(I3C+1))).OR.
     *          (X1.GT.AMAX1(RAM(I1B+1),RAM(I2B+1),RAM(I3B+1),
     *                       RAM(I1C+1),RAM(I2C+1),RAM(I3C+1)))) GOTO 25
          ENDIF
          IF (.NOT.(L2D.AND.(PROJ2.NE.0.))) THEN
            IF ((X2.LT.AMIN1(RAM(I1B+2),RAM(I2B+2),RAM(I3B+2),
     *                       RAM(I1C+2),RAM(I2C+2),RAM(I3C+2))).OR.
     *          (X2.GT.AMAX1(RAM(I1B+2),RAM(I2B+2),RAM(I3B+2),
     *                       RAM(I1C+2),RAM(I2C+2),RAM(I3C+2)))) GOTO 25
          ENDIF
          IF (.NOT.(L2D.AND.(PROJ3.NE.0.))) THEN
            IF ((X3.LT.AMIN1(RAM(I1B+3),RAM(I2B+3),RAM(I3B+3),
     *                       RAM(I1C+3),RAM(I2C+3),RAM(I3C+3))).OR.
     *          (X3.GT.AMAX1(RAM(I1B+3),RAM(I2B+3),RAM(I3B+3),
     *                       RAM(I1C+3),RAM(I2C+3),RAM(I3C+3)))) GOTO 25
          ENDIF
          CALL CIINT2(I1B,I2B,I3B,I1C,I2C,I3C,X1,X2,X3,INDX,ERRMAX,DWI)
  25    CONTINUE
      ENDIF
      RETURN
      END
C
C=======================================================================
C
      SUBROUTINE
     *  CIINT2(I1B,I2B,I3B,I1C,I2C,I3C,X1,X2,X3,INDX,ERRMAX,DWI)
C
C----------------------------------------------------------------------
C Subroutine designed to interpolate to the given point.
C
      INTEGER I1B,I2B,I3B,I1C,I2C,I3C,INDX
      REAL X1,X2,X3,ERRMAX,DWI
C
C Input:
C     I1B,I2B,I3B,I1C,I2C,I3C... Integers specifying the six
C             points on the rays, which define the ray cell.
C             Numbers 1,2,3 denote the first, second and third ray,
C             character B denotes the bottom of the ray cell and C
C             denotes the top of the ray cell.
C             Each integer contains the address just before
C             the parameters of the corresponding point:
C             the first parameter of the first point: RAM(I1B+1)
C     X1,X2,X3... Coordinates of the point for interpolation.
C     INDX... Index in IRAM of the address of the point for writing
C             the interpolated values.
C     ERRMAX... Upper error bound.
C     DWI...  Range [0-DWI,1+DWI] is used for local coordinates
C             w1,w2,w3.
C No output.
C Subroutines and external functions required:
      EXTERNAL CIPPP,CILSIG
      REAL CIPPP
      LOGICAL CILSIG
C
C ...........................
C Common block /MTTC/ to store the information about triangles and rays:
      INCLUDE 'mtt.inc'
C <A HREF="mtt.inc" TYPE="text/html">mtt.inc</A>.
C.......................................................................
      INTEGER I4
      REAL DWB
      PARAMETER (DWB=0.001)
      REAL Y1,Y2,Y3
      INTEGER IR
      REAL ROOT(3)
      REAL WB,WC,W1,W2,W3
      INTEGER I1BA,I2BA,I1CB,I2CB,ISID
      REAL SID
      CHARACTER*52 TXTERR
C     DWB... The points with local coordinates wb,wc from
C            range [0-DWB,1+DWB] are taken into account.
C            The points with local coordinates wb,wc from ran-
C            ge [0+DWB,1-DWB] are considered to lie within the ray cell.
C            For the other points further check is done.
C-----------------------------------------------------------------------
        IF (L3D) THEN
C         Checking the position of the gridpoint with respect to
C         the planes bounding the ray cell:
C
          Y1=(RAM(I1B+1)+RAM(I2B+1)+RAM(I3B+1))/3.
          Y2=(RAM(I1B+2)+RAM(I2B+2)+RAM(I3B+2))/3.
          Y3=(RAM(I1B+3)+RAM(I2B+3)+RAM(I3B+3))/3.
          IF (.NOT.CILSIG(
     *      CIPPP(I1C,I2C,I1C,I3C,I1C,Y1,Y2,Y3),
     *      CIPPP(I1C,I2C,I1C,I3C,I1C,X1,X2,X3) , 0. , 0.             ))
     *      GOTO 71
C
          Y1=(RAM(I1C+1)+RAM(I2C+1)+RAM(I3C+1))/3.
          Y2=(RAM(I1C+2)+RAM(I2C+2)+RAM(I3C+2))/3.
          Y3=(RAM(I1C+3)+RAM(I2C+3)+RAM(I3C+3))/3.
          IF (.NOT.CILSIG(
     *      CIPPP(I1B,I2B,I1B,I3B,I1B,Y1,Y2,Y3),
     *      CIPPP(I1B,I2B,I1B,I3B,I1B,X1,X2,X3) , 0. , 0.             ))
     *      GOTO 71
C
          IF (I1B.NE.I1C.AND.I2B.NE.I2C.AND.I3B.NE.I3C) THEN
            IF (CILSIG(
     *      CIPPP(I1B,I2C,I2B,I1C,I1B,RAM(I2B+1),RAM(I2B+2),RAM(I2B+3)),
     *      CIPPP(I1B,I2C,I2B,I1C,I1B,RAM(I3B+1),RAM(I3B+2),RAM(I3B+3)),
     *      CIPPP(I1B,I2C,I2B,I1C,I1B,RAM(I3C+1),RAM(I3C+2),RAM(I3C+3)),
     *            0.)) THEN
              IF (.NOT.CILSIG(
     *      CIPPP(I1B,I2C,I2B,I1C,I1B,RAM(I2B+1),RAM(I2B+2),RAM(I2B+3)),
     *      CIPPP(I1B,I2C,I2B,I1C,I1B,X1,X2,X3),0.,0.))          GOTO 71
            ELSEIF (CILSIG(
     *      CIPPP(I1B,I2C,I2B,I1C,I2B,RAM(I1B+1),RAM(I1B+2),RAM(I1B+3)),
     *      CIPPP(I1B,I2C,I2B,I1C,I2B,RAM(I3B+1),RAM(I3B+2),RAM(I3B+3)),
     *      CIPPP(I1B,I2C,I2B,I1C,I2B,RAM(I3C+1),RAM(I3C+2),RAM(I3C+3)),
     *            0.)) THEN
              IF (.NOT.CILSIG(
     *      CIPPP(I1B,I2C,I2B,I1C,I2B,RAM(I1B+1),RAM(I1B+2),RAM(I1B+3)),
     *      CIPPP(I1B,I2C,I2B,I1C,I2B,X1,X2,X3),0.,0.))          GOTO 71
            ENDIF
C
            IF (CILSIG(
     *      CIPPP(I2B,I3C,I3B,I2C,I2B,RAM(I3B+1),RAM(I3B+2),RAM(I3B+3)),
     *      CIPPP(I2B,I3C,I3B,I2C,I2B,RAM(I1B+1),RAM(I1B+2),RAM(I1B+3)),
     *      CIPPP(I2B,I3C,I3B,I2C,I2B,RAM(I1C+1),RAM(I1C+2),RAM(I1C+3)),
     *            0.)) THEN
              IF (.NOT.CILSIG(
     *      CIPPP(I2B,I3C,I3B,I2C,I2B,RAM(I3B+1),RAM(I3B+2),RAM(I3B+3)),
     *      CIPPP(I2B,I3C,I3B,I2C,I2B,X1,X2,X3),0.,0.))          GOTO 71
            ELSEIF (CILSIG(
     *      CIPPP(I2B,I3C,I3B,I2C,I3B,RAM(I2B+1),RAM(I2B+2),RAM(I2B+3)),
     *      CIPPP(I2B,I3C,I3B,I2C,I3B,RAM(I1B+1),RAM(I1B+2),RAM(I1B+3)),
     *      CIPPP(I2B,I3C,I3B,I2C,I3B,RAM(I1C+1),RAM(I1C+2),RAM(I1C+3)),
     *            0.)) THEN
              IF (.NOT.CILSIG(
     *      CIPPP(I2B,I3C,I3B,I2C,I3B,RAM(I2B+1),RAM(I2B+2),RAM(I2B+3)),
     *      CIPPP(I2B,I3C,I3B,I2C,I3B,X1,X2,X3),0.,0.))          GOTO 71
            ENDIF
C
            IF (CILSIG(
     *      CIPPP(I3B,I1C,I1B,I3C,I1B,RAM(I3B+1),RAM(I3B+2),RAM(I3B+3)),
     *      CIPPP(I3B,I1C,I1B,I3C,I1B,RAM(I2B+1),RAM(I2B+2),RAM(I2B+3)),
     *      CIPPP(I3B,I1C,I1B,I3C,I1B,RAM(I2C+1),RAM(I2C+2),RAM(I2C+3)),
     *            0.)) THEN
              IF (.NOT.CILSIG(
     *      CIPPP(I3B,I1C,I1B,I3C,I1B,RAM(I3B+1),RAM(I3B+2),RAM(I3B+3)),
     *      CIPPP(I3B,I1C,I1B,I3C,I1B,X1,X2,X3),0.,0.))          GOTO 71
            ELSEIF (CILSIG(
     *      CIPPP(I3B,I1C,I1B,I3C,I3B,RAM(I1B+1),RAM(I1B+2),RAM(I1B+3)),
     *      CIPPP(I3B,I1C,I1B,I3C,I3B,RAM(I2B+1),RAM(I2B+2),RAM(I2B+3)),
     *      CIPPP(I3B,I1C,I1B,I3C,I3B,RAM(I2C+1),RAM(I2C+2),RAM(I2C+3)),
     *            0.)) THEN
              IF (.NOT.CILSIG(
     *      CIPPP(I3B,I1C,I1B,I3C,I3B,RAM(I1B+1),RAM(I1B+2),RAM(I1B+3)),
     *      CIPPP(I3B,I1C,I1B,I3C,I3B,X1,X2,X3),0.,0.))          GOTO 71
            ENDIF
          ENDIF
        ENDIF
C
C       Computation of the local coordinate wb:
        CALL CIWB(I1B,I2B,I3B,I1C,I2C,I3C,X1,X2,X3,DWB,IR,ROOT)
C
        DO 70, I4=1,IR
          WB=ROOT(I4)
          IF (WB.EQ.1.) GOTO 71
          WC=1.-WB
          IF ((WB.LT.0.-DWB).OR.(WB.GT.1.+DWB)) THEN
C           <A NAME="error13"></A><FONT COLOR="RED">MTT-13</FONT>
            CALL ERROR('MTT-13: Root outside the cell')
C           This error should not appear.
C           Please <A HREF="#author">contact the author</A>.
          ENDIF
          CALL CIWI(I1B,I2B,I3B,I1C,I2C,I3C,X1,X2,X3,WB,WC,W1,W2,W3)
          IF ((W1.EQ.0.).AND.(W2.EQ.0.).AND.(W3.EQ.0.))
C           For the considered WB the gridpoint is outside the ray cell.
C           Continuing with the next WB:
     *      GOTO 69
          IF ((W1.LT.0.-DWI).OR.(W1.GT.1.+DWI).OR.
     *        (W2.LT.0.-DWI).OR.(W2.GT.1.+DWI).OR.
     *        (L3D.AND.((W3.LT.0.-DWI).OR.(W3.GT.1.+DWI))))
C           For the considered WB the gridpoint is outside the ray cell.
C           Continuing with the next WB:
     *      GOTO 69
          IF (L3D) THEN
C           Tests for the points close to the sides of the cell:
            IF ((W1.GE.0.-DWI).AND.(W1.LE.0.+DWI).AND.
     *          ((I2B.NE.I2C).OR.(I3B.NE.I3C))) THEN
C             The gridpoint is very close the side of the ray cell,
C             checking, whether it is inside or outside the cell:
              I1BA=MIN0(I2B,I3B)
              I2BA=MAX0(I2B,I3B)
              I1CB=MIN0(I2C,I3C)
              I2CB=MAX0(I2C,I3C)
              CALL CILSID
     *             (I1BA,I2BA,I1CB,I2CB,X1,X2,X3,DWB,WB,Y1,Y2,Y3,ISID)
              SID=Y1*(WB*RAM(I1B+1)+WC*RAM(I1C+1)-X1)
     *           +Y2*(WB*RAM(I1B+2)+WC*RAM(I1C+2)-X2)
     *           +Y3*(WB*RAM(I1B+3)+WC*RAM(I1C+3)-X3)
              IF (SID*FLOAT(ISID).LE.0.) THEN
C               For this WB the gridpoint is outside the ray cell:
                GOTO 69
              ENDIF
            ENDIF
            IF ((W2.GE.0.-DWI).AND.(W2.LE.0.+DWI).AND.
     *          ((I1B.NE.I1C).OR.(I3B.NE.I3C))) THEN
C             The gridpoint is very close the side of the ray cell,
C             checking, whether it is inside or outside the cell:
              I1BA=MIN0(I1B,I3B)
              I2BA=MAX0(I1B,I3B)
              I1CB=MIN0(I1C,I3C)
              I2CB=MAX0(I1C,I3C)
              CALL CILSID
     *             (I1BA,I2BA,I1CB,I2CB,X1,X2,X3,DWB,WB,Y1,Y2,Y3,ISID)
              SID=Y1*(WB*RAM(I2B+1)+WC*RAM(I2C+1)-X1)
     *           +Y2*(WB*RAM(I2B+2)+WC*RAM(I2C+2)-X2)
     *           +Y3*(WB*RAM(I2B+3)+WC*RAM(I2C+3)-X3)
              IF (SID*FLOAT(ISID).LE.0.) THEN
C               For this WB the gridpoint is outside the ray cell:
                GOTO 69
              ENDIF
            ENDIF
            IF ((W3.GE.0.-DWI).AND.(W3.LE.0.+DWI).AND.
     *          ((I1B.NE.I1C).OR.(I2B.NE.I2C))) THEN
C             The gridpoint is very close the side of the ray cell,
C             checking, whether it is inside or outside the cell:
              I1BA=MIN0(I2B,I1B)
              I2BA=MAX0(I2B,I1B)
              I1CB=MIN0(I2C,I1C)
              I2CB=MAX0(I2C,I1C)
              CALL CILSID
     *             (I1BA,I2BA,I1CB,I2CB,X1,X2,X3,DWB,WB,Y1,Y2,Y3,ISID)
              SID=Y1*(WB*RAM(I3B+1)+WC*RAM(I3C+1)-X1)
     *           +Y2*(WB*RAM(I3B+2)+WC*RAM(I3C+2)-X2)
     *           +Y3*(WB*RAM(I3B+3)+WC*RAM(I3C+3)-X3)
              IF (SID*FLOAT(ISID).LE.0.) THEN
C               For this WB the gridpoint is outside the ray cell:
                GOTO 69
              ENDIF
            ENDIF
          ENDIF
          IF (L2D) THEN
C           ------------------------------------------------------------
ccC           No tests for the points close to the sides of the cell:
cc            IF ((W1.LT.0.).OR.(W1.GE.1.).OR.
cc     *          (W2.LE.0.).OR.(W2.GT.1.).OR.
cc     *          (WB.LT.0.).OR.(WB.GE.1.))
ccC               The gridpoint is situated outside the ray cell.
cc     *          GOTO 69
C           ------------------------------------------------------------
C           Tests for the points close to the sides of the cell:
            IF ((WB.LT.0.).OR.(WB.GE.1.))
C               The gridpoint is situated outside the ray cell.
     *          GOTO 69
            IF (ABS(W1-1.).LT.DWI) THEN
C             The gridpoint is very close the side of the ray cell,
C             checking, whether it is inside or outside the cell:
              I1BA=I1B
              I1CB=I1C
              CALL CILSID
     *             (I1BA,I2BA,I1CB,I2CB,X1,X2,X3,DWB,WB,Y1,Y2,Y3,ISID)
              SID=Y1*(WB*RAM(I2B+1)+WC*RAM(I2C+1)-X1)
     *           +Y2*(WB*RAM(I2B+2)+WC*RAM(I2C+2)-X2)
     *           +Y3*(WB*RAM(I2B+3)+WC*RAM(I2C+3)-X3)
              IF (SID*FLOAT(ISID).LE.0.) THEN
C               For this WB the gridpoint is outside the ray cell:
                GOTO 69
              ENDIF
            ENDIF
            IF (ABS(W2-1.).LT.DWI) THEN
C             The gridpoint is very close the side of the ray cell,
C             checking, whether it is inside or outside the cell:
              I1BA=I2B
              I1CB=I2C
              CALL CILSID
     *             (I1BA,I2BA,I1CB,I2CB,X1,X2,X3,DWB,WB,Y1,Y2,Y3,ISID)
              SID=Y1*(WB*RAM(I1B+1)+WC*RAM(I1C+1)-X1)
     *           +Y2*(WB*RAM(I1B+2)+WC*RAM(I1C+2)-X2)
     *           +Y3*(WB*RAM(I1B+3)+WC*RAM(I1C+3)-X3)
              IF (SID*FLOAT(ISID).LE.0.) THEN
C               For this WB the gridpoint is outside the ray cell:
                GOTO 69
              ENDIF
            ENDIF
C           ------------------------------------------------------------
          ENDIF
C
C         The gridpoint is situated inside the ray cell:
C
          IF (L3D) THEN
C           Checking accuracy of interpolation coefficients:
            Y1=WB*(W1*RAM(I1B+1)+W2*RAM(I2B+1)+W3*RAM(I3B+1))+
     *         WC*(W1*RAM(I1C+1)+W2*RAM(I2C+1)+W3*RAM(I3C+1))
            Y2=WB*(W1*RAM(I1B+2)+W2*RAM(I2B+2)+W3*RAM(I3B+2))+
     *         WC*(W1*RAM(I1C+2)+W2*RAM(I2C+2)+W3*RAM(I3C+2))
            Y3=WB*(W1*RAM(I1B+3)+W2*RAM(I2B+3)+W3*RAM(I3B+3))+
     *         WC*(W1*RAM(I1C+3)+W2*RAM(I2C+3)+W3*RAM(I3C+3))
            IF (((Y1-X1)**2 + (Y2-X2)**2 + (Y3-X3)**2).GT.ERRMAX) THEN
C             <A NAME="error23"></A><FONT COLOR="RED">MTT-23</FONT>
              CALL WARN
     *           ('MTT-23: Inexact interpolation coefficients.        ')
C             Interpolation coefficients are not exact enough to
C             provide exact coordinates of gridpoints. Thus the error
C             of the same order will appear in interpolation of
C             travel times and other quantities.
C             In principle this error should not appear, check, that
C             you are computing with all possible accuracy.
            ENDIF
          ENDIF
C
C         Interpolation of output quantities:
  40      CONTINUE
          IF (IRAM(INDX).NE.0) THEN
            INDX=IRAM(INDX)
            GOTO 40
          ENDIF
          NRAMT=NRAMT-(NOUT+1)
          IF (NRAMT.LE.NRAMP) CALL CIEROR(1,TXTERR)
          IRAM(INDX)=NRAMT
          IRAM(NRAMT)=0
          MRAMP=NRAMT-1
          CALL CIQI(WB,WC,W1,W2,W3,I1B,I2B,I3B,I1C,I2C,I3C,X1,X2,X3)
  69      CONTINUE
  70    CONTINUE
  71    CONTINUE
      RETURN
      END
C=======================================================================
C
      SUBROUTINE CILSID(I1B,I2B,I1C,I2C,X1,X2,X3,DWB,WB,Y1,Y2,Y3,ISID)
C
C----------------------------------------------------------------------
C Subroutine for the decision on which side of the side of the ray
C cell defined by points I1B,I2B,I1C,I2C is located point X.
C The side of the ray cell defined by points I1B,I2B,I1C,I2C is
C completed with points I3B,I3C (for details see the code bellow) to
C create virtual ray cell. Local coordinates are then computed for
C point X. If (0.-DWB)<WB<(1.+DWB) and W3>0. hold, point X is
C considered to be located at positive side of the side of the ray cell.
C Finaly vector Y with origin in X and direction towards the virtual
C cell is computed.
      INTEGER I1B,I2B,I1C,I2C
      REAL X1,X2,X3,DWB,WB,Y1,Y2,Y3
      INTEGER ISID
C Input:
C     I1B,I2B,I1C,I2C... Integers specifying the four
C             points on the rays, which define the side of the ray cell.
C             Numbers 1,2 denote the first and second ray,
C             character B denotes the bottom of the ray cell and C
C             denotes the top of the ray cell.
C             Each integer contains the address just before
C             the parameters of the corresponding point:
C             the first parameter of the first point: RAM(I1B+1)
C     X1,X2,X3...Coordinates of the examined point.
C     DWB...  The points with local coordinate WBB from
C             range [0-DWB,1+DWB] are taken into account.
C     WB...   The point with the value of local coordinate WBB nearest
C             to input value WB is considered. (WB is the local
C             coordinate of point X in the real cell, WBB is the local
C             coordinate of X in the virtual ray cell.)
C Output:
C     Y1,Y2,Y3... Three components of the vector Y from point X
C             towards (pointing inside) the virtual cell.
C     ISID... +1 if point X is on the positive side,
C              0 if the position with respect to the side
C                was not found,
C             -1 otherwise.
C
C ...........................
C Common block /MTTC/ to store the information about triangles and rays:
      INCLUDE 'mtt.inc'
C <A HREF="mtt.inc" TYPE="text/html">mtt.inc</A>.
C.......................................................................
      INTEGER I3B,I3C
      REAL A1,A2,A3,B1,B2,B3
      REAL U1,U2,U3,V1,V2,V3,W1,W2,W3,WBB,WCC,A,WW,UU,VV
      INTEGER IR,I,J
      REAL ROOT(3)
      REAL Y11,Y12,Y13,Y21,Y22,Y23
      CHARACTER*52 TXTERR
C     I3B,I3C... Addresses of the two points completing the ray cell.
C     A1,A2,A3,B1,B2,B3... Coordinates of two points in the middles of
C             the edges of the ray cell.
C     U1,U2,U3,V1,V2,V3,W1,W2,W3,UU,VV... Coordinates of the vectors
C             at the side of the ray cell, U and V are the edges
C             at the bottom and at the top of the ray cell, W is
C             connecting points in the middles of the edges, UU and VV
C             are lengths of the vectors U and V.
C             W1,W2,W3 are later used as local coordinates.
C             Optionally vectors U and V are later used for edges
C             at the sides of the ray cell.
C     Y11,Y12,Y13... Three components of the vector U x W.
C     Y21,Y22,Y23... Three components of the vector V x W.
C-----------------------------------------------------------------------
      IF (NRAMP+6.GT.MRAMP) CALL CIEROR(1,TXTERR)
      IF (L3D) THEN
C       Computation of the points I3B, I3C:
        A1=(RAM(I1B+1)+RAM(I2B+1))/2.
        A2=(RAM(I1B+2)+RAM(I2B+2))/2.
        A3=(RAM(I1B+3)+RAM(I2B+3))/2.
        B1=(RAM(I1C+1)+RAM(I2C+1))/2.
        B2=(RAM(I1C+2)+RAM(I2C+2))/2.
        B3=(RAM(I1C+3)+RAM(I2C+3))/2.
        U1=RAM(I1B+1)-RAM(I2B+1)
        U2=RAM(I1B+2)-RAM(I2B+2)
        U3=RAM(I1B+3)-RAM(I2B+3)
        V1=RAM(I1C+1)-RAM(I2C+1)
        V2=RAM(I1C+2)-RAM(I2C+2)
        V3=RAM(I1C+3)-RAM(I2C+3)
        W1=B1-A1
        W2=B2-A2
        W3=B3-A3
        WW=SQRT(W1*W1+W2*W2+W3*W3)
        WW=(SQRT(3.)/2.)/WW
        W1=W1*WW
        W2=W2*WW
        W3=W3*WW
        Y11=U2*W3-W2*U3
        Y12=U3*W1-W3*U1
        Y13=U1*W2-W1*U2
        Y21=V2*W3-W2*V3
        Y22=V3*W1-W3*V1
        Y23=V1*W2-W1*V2
        I3B=NRAMP
        RAM(I3B+1)=A1+Y11
        RAM(I3B+2)=A2+Y12
        RAM(I3B+3)=A3+Y13
        I3C=NRAMP+3
        RAM(I3C+1)=B1+Y21
        RAM(I3C+2)=B2+Y22
        RAM(I3C+3)=B3+Y23
      ENDIF
      IF (L2D) THEN
C       Computation of the points I2B, I2C:
        W1=RAM(I1C+1)-RAM(I1B+1)
        W2=RAM(I1C+2)-RAM(I1B+2)
        W3=RAM(I1C+3)-RAM(I1B+3)
        WW=SQRT(PROJ1*PROJ1+PROJ2*PROJ2+PROJ3*PROJ3)
        Y11=(PROJ2/WW)*W3-W2*(PROJ3/WW)
        Y12=(PROJ3/WW)*W1-W3*(PROJ1/WW)
        Y13=(PROJ1/WW)*W2-W1*(PROJ2/WW)
        Y21=Y11
        Y22=Y12
        Y23=Y13
        I2B=NRAMP
        I3B=I2B
        RAM(I2B+1)=RAM(I1B+1)+Y11
        RAM(I2B+2)=RAM(I1B+2)+Y12
        RAM(I2B+3)=RAM(I1B+3)+Y13
        I2C=NRAMP+3
        I3C=I2C
        RAM(I2C+1)=RAM(I1C+1)+Y21
        RAM(I2C+2)=RAM(I1C+2)+Y22
        RAM(I2C+3)=RAM(I1C+3)+Y23
      ENDIF
C
C     Computation of the local coordinate wb:
      CALL CIWB(I1B,I2B,I3B,I1C,I2C,I3C,X1,X2,X3,DWB,IR,ROOT)
C
      IF (IR.LE.0) THEN
C       No WB found in the virtual cell:
        ISID=0
        RETURN
      ENDIF
      J=1
      A=ABS(ROOT(1)-WB)
      DO 10 I=2,IR
        IF(ABS(ROOT(I)-WB).LT.A) THEN
          J=I
          A=ABS(ROOT(I)-WB)
        END IF
   10 CONTINUE
C
      WBB=ROOT(J)
      WCC=1.-WBB
      IF ((WBB.LT.0.-DWB).OR.(WBB.GT.1.+DWB)) THEN
C       <A NAME="error28"></A><FONT COLOR="RED">MTT-28</FONT>
        CALL ERROR('MTT-28: Root outside the cell')
C       This error should not appear.
C       Please <A HREF="#author">contact the author</A>.
      ENDIF
      CALL CIWI(I1B,I2B,I3B,I1C,I2C,I3C,X1,X2,X3,WBB,WCC,W1,W2,W3)
      IF (A.GT.0.01) THEN
        U1=RAM(I1C+1)-RAM(I1B+1)
        U2=RAM(I1C+2)-RAM(I1B+2)
        U3=RAM(I1C+3)-RAM(I1B+3)
        V1=RAM(I2C+1)-RAM(I2B+1)
        V2=RAM(I2C+2)-RAM(I2B+2)
        V3=RAM(I2C+3)-RAM(I2B+3)
        UU=U1*U1+U2*U2+U3*U3
        IF (UU.GT.DWARF) UU=SQRT(UU)
        VV=V1*V1+V2*V2+V3*V3
        IF (VV.GT.DWARF) VV=SQRT(VV)
        A=A*ABS((UU*W1+VV*W2)/AMAX1(UU,VV))
        IF (A.GT.0.01) THEN
C         <A NAME="error30"></A><FONT COLOR="RED">MTT-30</FONT>
          CALL WARN
     *    ('MTT-30: WB in virtual and real cells too different.')
C         WB was computed for the point X in the real cell. Now we are
C         looking for WBB in the virtual cell, which corresponds to the
C         above mentioned WB in the real cell. Thus WB and WBB should
C         not be too different. It is possible, that the value 0.01
C         should be enlarged.
C         This warning should not appear, or at least not too often.
        ENDIF
      ENDIF
      IF ((W1.EQ.0.).AND.(W2.EQ.0.).AND.(W3.EQ.0.)) THEN
        ISID=0
      ELSEIF ((L3D.AND.W3.GE.0.).OR.(L2D.AND.W2.GE.0.)) THEN
        ISID=+1
      ELSE
        ISID=-1
      ENDIF
C
      Y1=WBB*Y11+WCC*Y21
      Y2=WBB*Y12+WCC*Y22
      Y3=WBB*Y13+WCC*Y23
      RETURN
      END
C
C=======================================================================
C
      REAL FUNCTION CIPPP(IU1,IU2,IV1,IV2,IA,X1,X2,X3)
C
C----------------------------------------------------------------------
      INTEGER IU1,IU2,IV1,IV2,IA
      REAL X1,X2,X3
C     Subroutine designed to indicate the position of
C     a point X: (X1,X2,X3) with respect to
C     a plane defined by two vectors u: IU1 --> IU2, v: IV1 --> IV2,
C     and by a point IA.
C     The subroutine computes the scalar product a.w of vector
C     a: IA --> X with vector w: w = u x v being normal to the plane.
C     The sign of this product then indicates, on which side of the
C     plane is the point X located.
C     All the computation is performed in 3-D Cartesian coordinates.
C
C Input:
C     IU1,IU2... Two points defining vector u.
C     IV1,IV2... Two points defining vector v.
C     IA...   Point of the plane.
C             Each integer contains the address just before
C             the parameters of the corresponding point:
C             the first parameter of the point IA: RAM(IA+1)
C     X1,X2,X3... Coordinates of the examined point.
C Output:
C     CIPPP... The value of the scalar product.
C
C ...........................
C Common block /MTTC/ to store the information about triangles and rays:
      INCLUDE 'mtt.inc'
C <A HREF="mtt.inc" TYPE="text/html">mtt.inc</A>.
C
C......................................................................
      REAL U1,U2,U3,V1,V2,V3,W1,W2,W3,A1,A2,A3
C-----------------------------------------------------------------------
      U1=RAM(IU2+1)-RAM(IU1+1)
      U2=RAM(IU2+2)-RAM(IU1+2)
      U3=RAM(IU2+3)-RAM(IU1+3)
      V1=RAM(IV2+1)-RAM(IV1+1)
      V2=RAM(IV2+2)-RAM(IV1+2)
      V3=RAM(IV2+3)-RAM(IV1+3)
      W1=U2*V3-U3*V2
      W2=U3*V1-U1*V3
      W3=U1*V2-U2*V1
      A1=X1-RAM(IA+1)
      A2=X2-RAM(IA+2)
      A3=X3-RAM(IA+3)
      CIPPP=W1*A1+W2*A2+W3*A3
      RETURN
      END
C
C=======================================================================
C
      REAL FUNCTION CICUB(AAA,BBB,CCC,DDD,XX)
C
C----------------------------------------------------------------------
      REAL AAA,BBB,CCC,DDD,XX
C     Subroutine designed to calculate the value of cubic function
C     given by coefficients AAA,BBB,CCC,DDD in point XX.
C......................................................................
      CICUB=AAA*XX*XX*XX+BBB*XX*XX+CCC*XX+DDD
      RETURN
      END
C
C=======================================================================
C
      REAL FUNCTION CIAA(W)
C
C----------------------------------------------------------------------
C Subroutine to calculate the value of the cubic function A used for
C interpolation of travel time during bicubic travel time interpolation.
      REAL W
C......................................................................
      CIAA=(3-2*W)*W*W
      RETURN
      END
C
C=======================================================================
C
      REAL FUNCTION CIBB(W,IB,IC,IP)
C
C----------------------------------------------------------------------
C Subroutine to calculate the value of the cubic function B used for
C interpolation of slowness during bicubic travel time interpolation.
      INTEGER IB,IC,IP
      REAL W
C ...........................
C Common block /MTTC/ to store the information about triangles and rays:
      INCLUDE 'mtt.inc'
C <A HREF="mtt.inc" TYPE="text/html">mtt.inc</A>.
C ...........................
      REAL B1,B2,B3,C1,C2,C3,P1,P2,P3,A1W,A2W,A3W
C......................................................................
      B1=RAM(IB+1)
      B2=RAM(IB+2)
      B3=RAM(IB+3)
      C1=RAM(IC+1)
      C2=RAM(IC+2)
      C3=RAM(IC+3)
      P1=RAM(IP+1)
      P2=RAM(IP+2)
      P3=RAM(IP+3)
      A1W=W*B1+(1-W)*C1
      A2W=W*B2+(1-W)*C2
      A3W=W*B3+(1-W)*C3
      CIBB=W*W*(P1*(A1W-B1)+P2*(A2W-B2)+P3*(A3W-B3))
      RETURN
      END
C
C=======================================================================
C
      REAL FUNCTION CIQUA(AAA,BBB,CCC,XX)
C
C----------------------------------------------------------------------
      REAL AAA,BBB,CCC,XX
C     Subroutine designed to calculate the value of quadratic function
C     given by coefficients AAA,BBB,CCC in point XX.
C......................................................................
      CIQUA=AAA*XX*XX+BBB*XX+CCC
      RETURN
      END
C
C=======================================================================
C
      REAL FUNCTION CIDET3(A)
C
C----------------------------------------------------------------------
      REAL A(3,3)
C     Subroutine designed to calculate the determinant of 3x3 matrix AA.
C Input:
C     A...    3x3 real matrix.
C Output:
C     CIDET3... Determinant.
C
C......................................................................
      CIDET3=A(1,1)*(A(2,2)*A(3,3)-A(3,2)*A(2,3))+
     *       A(2,1)*(A(3,2)*A(1,3)-A(1,2)*A(3,3))+
     *       A(3,1)*(A(1,2)*A(2,3)-A(2,2)*A(1,3))
      RETURN
      END
C
C=======================================================================
C
      REAL FUNCTION CISUBD(A,B)
C
C----------------------------------------------------------------------
      REAL A(3,3),B(3,3)
C     Subroutine designed to calculate the sum
C
C             SUM  (  e  *  A * B * B   )
C             ijk      ijk   1i  2j  3k
C
C     where i,j,k=1..3 and e    is a Levi-Civita symbol.
C                           ijk
C Input:
C     A...    3x3 real matrix.
C     B...    3x3 real matrix.
C Output:
C     CISUBD... Value of the sum mentioned above.
C
C......................................................................
      CISUBD=A(1,1)*(B(2,2)*B(3,3)-B(3,2)*B(2,3))+
     *       A(2,1)*(B(3,2)*B(1,3)-B(1,2)*B(3,3))+
     *       A(3,1)*(B(1,2)*B(2,3)-B(2,2)*B(1,3))+
     *       A(1,2)*(B(2,3)*B(3,1)-B(3,3)*B(2,1))+
     *       A(2,2)*(B(3,3)*B(1,1)-B(1,3)*B(3,1))+
     *       A(3,2)*(B(1,3)*B(2,1)-B(2,3)*B(1,1))+
     *       A(1,3)*(B(2,1)*B(3,2)-B(3,1)*B(2,2))+
     *       A(2,3)*(B(3,1)*B(1,2)-B(1,1)*B(3,2))+
     *       A(3,3)*(B(1,1)*B(2,2)-B(2,1)*B(1,2))
      END
C
C
C=======================================================================
C
      SUBROUTINE CICUBR(AA0,BB0,CC0,DD0,RR,IR,ROOT)
C
C----------------------------------------------------------------------
C Subroutine for numerical solution of the cubic equation
C on the interval <RR(1),RR(NRR)>.
      INTEGER IR
      REAL AA0,BB0,CC0,DD0,RR(4),ROOT(3)
C Input:
C     AA0,BB0,CC0,DD0... Coefficients of the equation.
C     IR...   Expected number of real roots from the interval.
C     RR...   Array of points, which divide the interval <RR(1),RR(NRR)>
C             into subintervals, each subinterval containing just one
C             root of the cubic equation. It is expected, that
C             functional values of cubic equation have different signes
C             in RR(i) and RR(i+1).
C             RR(1)... Lower bound of the interval.
C             RR(NRR)... Upper bound of the interval.
C             for IR=1 NRR=2
C             for IR=2 NRR=3, RR(2) is a point in which
C               the cubic equation has zero derivative
C             for IR=3 NRR=4, RR(2) and RR(3) are points in which
C               the cubic equation has zero derivative.
C Output:
C     ROOT... Real roots of the equation from the interval or undefined.
C
C Subroutines and external functions required:
      EXTERNAL CICUB,CIQUA
      REAL CICUB,CIQUA
C.......................................................................
C Common block /MTTC/ to store the information about triangles and rays:
      INCLUDE 'mtt.inc'
C <A HREF="mtt.inc" TYPE="text/html">mtt.inc</A>.
C.......................................................................
      REAL TRIAA0,DVEBB0,POM1,POM2,POM3,DER,RA,RB,DA,DB
      INTEGER I1,I2
C-----------------------------------------------------------------------
      TRIAA0=3.*AA0
      DVEBB0=2.*BB0
      DO 20, I2=1,IR
        RA=RR(I2)
        RB=RR(I2+1)
        POM1=CICUB(AA0,BB0,CC0,DD0,RB)
        POM2=CICUB(AA0,BB0,CC0,DD0,RA)
        IF (POM1.EQ.0.) THEN
          ROOT(I2)=RB
          GOTO 19
        ENDIF
        IF (POM2.EQ.0.) THEN
          ROOT(I2)=RA
          GOTO 19
        ENDIF
        I1=0
  10    CONTINUE
          I1=I1+1
          IF (I1.GT.100) THEN
C           <A NAME="error08"></A><FONT COLOR="RED">MTT-08</FONT>
            CALL ERROR('MTT-08: infinite loop in CICUBR')
C           The root was not find even after 100 iterations.
C           This error should not appear.
C           Please <A HREF="#author">contact the author</A>.
          ENDIF
C
          POM1=CICUB(AA0,BB0,CC0,DD0,RB)
          POM2=CICUB(AA0,BB0,CC0,DD0,RA)
          IF (((POM1.LE.0.).AND.(POM2.LE.0.)).OR.
     *        ((POM1.GE.0.).AND.(POM2.GE.0.))) THEN
C          <A NAME="error24"></A><FONT COLOR="RED">MTT-24</FONT>
            CALL ERROR('MTT-24: values in RA and RB have the same sign')
C           This error should not appear.
C           Please <A HREF="#author">contact the author</A>.
          ENDIF
          DER=CIQUA(TRIAA0,DVEBB0,CC0,RA)
          IF (DER.NE.0.) THEN
            ROOT(I2)=RA-POM2/DER
            IF((ROOT(I2).LE.RA).OR.(ROOT(I2).GE.RB))ROOT(I2)=(RA+RB)/2.
          ELSE
            ROOT(I2)=(RA+RB)/2.
          ENDIF
          POM3=CICUB(AA0,BB0,CC0,DD0,ROOT(I2))
          IF (POM3.EQ.0.) GOTO 19
          IF (((POM1.LT.0.).AND.(POM3.GT.0.)).OR.
     *        ((POM1.GT.0.).AND.(POM3.LT.0.))) THEN
            RA=ROOT(I2)
            POM2=POM3
          ELSE
            RB=ROOT(I2)
            POM1=POM3
          ENDIF
C
          IF (((POM1.LE.0.).AND.(POM2.LE.0.)).OR.
     *        ((POM1.GE.0.).AND.(POM2.GE.0.))) THEN
C          <A NAME="error25"></A><FONT COLOR="RED">MTT-25</FONT>
            CALL ERROR('MTT-25: values in RA and RB have the same sign')
C           This error should not appear.
C           Please <A HREF="#author">contact the author</A>.
          ENDIF
          POM3=POM1-POM2
          IF (POM3.EQ.0.) THEN
C           <A NAME="error09"></A><FONT COLOR="RED">MTT-09</FONT>
            CALL ERROR('MTT-09: division by zero in CICUBR.')
C           This error should not appear.
C           Please <A HREF="#author">contact the author</A>.
          ENDIF
          ROOT(I2)=RA-(RB-RA)*POM2/POM3
          IF((ROOT(I2).LE.RA).OR.(ROOT(I2).GE.RB)) ROOT(I2)=(RA+RB)/2.
          POM3=CICUB(AA0,BB0,CC0,DD0,ROOT(I2))
          IF (POM3.EQ.0.) GOTO 19
          IF (((POM1.LT.0.).AND.(POM3.GT.0.)).OR.
     *        ((POM1.GT.0.).AND.(POM3.LT.0.))) THEN
            RA=ROOT(I2)
            POM2=POM3
          ELSE
            RB=ROOT(I2)
            POM1=POM3
          ENDIF
        IF (ABS((RA-RB)/(ABS(RA+RB)+DWARF)).GT.DWARF) GOTO 10
        IF (RA.NE.RB) THEN
          IF (POM1.EQ.0.) THEN
            ROOT(I2)=RB
          ELSEIF (POM2.EQ.0.) THEN
            ROOT(I2)=RA
          ELSEIF (POM1-POM2.NE.0.) THEN
C           Linear interpolation of the root:
            DA=RA-ROOT(I2)
            DB=RB-ROOT(I2)
            POM3=(DA*POM1-DB*POM2)/(POM1-POM2)
            ROOT(I2)=ROOT(I2)+POM3
            IF((ROOT(I2).LE.RA).OR.(ROOT(I2).GE.RB)) ROOT(I2)=(RA+RB)/2.
          ELSE
C           <A NAME="error22"></A><FONT COLOR="RED">MTT-22</FONT>
            CALL ERROR('MTT-22: Equal functional values in CICUBR.')
C           This error should not appear.
C           Please <A HREF="#author">contact the author</A>.
          END IF
        END IF
  19    CONTINUE
  20  CONTINUE
C
      END
C
C=======================================================================
C
      LOGICAL FUNCTION LDWARF(AUX)
C
C----------------------------------------------------------------------
      REAL AUX
C     Subroutine to force the computer to take the value of DWARF from
C     the memory.
      IF (AUX.NE.1.) THEN
        LDWARF=.TRUE.
      ELSE
        LDWARF=.FALSE.
      ENDIF
      END
C
C=======================================================================
C
      LOGICAL FUNCTION CILSIG(R1,R2,R3,R4)
C
C----------------------------------------------------------------------
      REAL R1,R2,R3,R4
C     Subroutine to compare signs of real quantities.
C
C Input:
C     R1,R2,R3,R4... Real quantities.
C Output:
C     CILSIG... .TRUE. for all the quantities nonnegative or
C                      all the quantities nonpositive.
C               .FALSE. in other cases.
C-----------------------------------------------------------------------
      IF (((R1.LE.0.).AND.(R2.LE.0.).AND.(R3.LE.0.).AND.(R4.LE.0.)).OR.
     *    ((R1.GE.0.).AND.(R2.GE.0.).AND.(R3.GE.0.).AND.(R4.GE.0.)))
     *  THEN
        CILSIG=.TRUE.
      ELSE
        CILSIG=.FALSE.
      ENDIF
      RETURN
      END
C
C=======================================================================
C
      LOGICAL FUNCTION CIL2P(I1,I2)
C
C----------------------------------------------------------------------
      INTEGER I1,I2
C     Subroutine to compare coordinates of two points from array RAM.
C
C Input:
C     I1,I2... Addresses of the two points in array RAM.
C Output:
C     CIL2P... .TRUE. if the coordinates of the points are different
C              .FALSE. if they are the same.
C ...........................
C Common block /MTTC/ to store the information about triangles and rays:
      INCLUDE 'mtt.inc'
C <A HREF="mtt.inc" TYPE="text/html">mtt.inc</A>.
C-----------------------------------------------------------------------
      IF ((RAM(I1+1).NE.RAM(I2+1)).OR.(RAM(I1+2).NE.RAM(I2+2))
     *       .OR.(RAM(I1+3).NE.RAM(I2+3))) THEN
        CIL2P=.TRUE.
      ELSE
        CIL2P=.FALSE.
      ENDIF
      RETURN
      END
C
C
C=======================================================================
C
      SUBROUTINE CIGRID
C
C----------------------------------------------------------------------
C Subroutine to read in the file with parameters of an interpolation
C grid. The read quantities are then written into common block MTTC.
C No input:
C No output.
C
C ...........................
C Common block /MTTC/ to store the information about triangles and rays:
      INCLUDE 'mtt.inc'
C <A HREF="mtt.inc" TYPE="text/html">mtt.inc</A>.
C.......................................................................
      INTEGER I1
      CHARACTER*52 TXTERR
C-----------------------------------------------------------------------
C
C     Recalling the data specifying grid dimensions
C     (arguments: Name of value in input data, Variable, Default):
      CALL RSEP3R('O1',O1,0.)
      CALL RSEP3R('O2',O2,0.)
      CALL RSEP3R('O3',O3,0.)
      CALL RSEP3R('D1',D1,1.)
      CALL RSEP3R('D2',D2,1.)
      CALL RSEP3R('D3',D3,1.)
      CALL RSEP3I('N1',N1,1)
      CALL RSEP3I('N2',N2,1)
      CALL RSEP3I('N3',N3,1)
C     Recalling the data specifying projection vector, which is used
C     in 2-D calculations for projection of the gridpoint coordinates
C     to the plane defined by rays.
      CALL RSEP3R('PROJ1',PROJ1,0.)
      CALL RSEP3R('PROJ2',PROJ2,0.)
      CALL RSEP3R('PROJ3',PROJ3,0.)
C
      IF (D1.LT.0.) THEN
        O1=O1+(N1-1)*D1
        D1=-D1
      ENDIF
      IF (D2.LT.0.) THEN
        O2=O2+(N2-1)*D2
        D2=-D2
      ENDIF
      IF (D3.LT.0.) THEN
        O3=O3+(N3-1)*D3
        D3=-D3
      ENDIF
      IF ((N1.LE.0).OR.(N2.LE.0).OR.(N3.LE.0)) GOTO 10
      IF (D1.EQ.0.) THEN
        IF (N1.EQ.1) THEN
          D1=1.
        ELSE
          GOTO 10
        ENDIF
      ENDIF
      IF (D2.EQ.0.) THEN
        IF (N2.EQ.1) THEN
          D2=1.
        ELSE
          GOTO 10
        ENDIF
      ENDIF
      IF (D3.EQ.0.) THEN
        IF (N3.EQ.1) THEN
          D3=1.
        ELSE
          GOTO 10
        ENDIF
      ENDIF
      MAXOUT=MAXRAM
      MRAMP=MAXOUT-N1*N2*N3
      IF (MRAMP.LE.1) CALL CIEROR(1,TXTERR)
      NRAMT=MRAMP+1
      DO 5, I1=NRAMT,MAXOUT
        IRAM(I1)=0
   5  CONTINUE
      RETURN
C
  10  CONTINUE
C     <A NAME="error10"></A><FONT COLOR="RED">MTT-10</FONT>
      CALL ERROR('MTT-10: This specification of the interpolation grid
     *may cause problems. Please, specify D1,D2,D3 and N1,N2,N3 greater
     * than 0. Di may equal 0 in case that corresponding Ni equals 1.')
C
      END
C
C
C=======================================================================
C
      SUBROUTINE CIPTS
C
C----------------------------------------------------------------------
C Subroutine to read in the file with coordinates of individual points
C for interpolation. The read quantities are then written into common
C block MTTC.
C No input:
C No output.
C
C ...........................
C Common block /MTTC/ to store the information about triangles and rays:
      INCLUDE 'mtt.inc'
C <A HREF="mtt.inc" TYPE="text/html">mtt.inc</A>.
C.......................................................................
      INTEGER LU4,I1
      PARAMETER (LU4=4)
      CHARACTER*52 TXTERR
C-----------------------------------------------------------------------
C
C     Reading the names and the coordinates of points:
      OPEN(LU4,FILE=FILPTS,STATUS='OLD')
      READ(LU4,*) (TXTPTS(I1),I1=1,20)
      NPTS=0
      MAXOUT=MAXRAM
   20 CONTINUE
        IF (MAXOUT-2.LT.1) CALL CIEROR(1,TXTERR)
        IF (NPTS+1.GT.MPTS) THEN
C         <A NAME="error07"></A><FONT COLOR="RED">MTT-07</FONT>
          CALL ERROR('MTT-07: Too small array TXTPTS')
        ENDIF
        TXTPTS(NPTS+1)='$'
        RAM(MAXOUT-2)=0.
        RAM(MAXOUT-1)=0.
        RAM(MAXOUT  )=0.
        READ(LU4,*,END=29) TXTPTS(NPTS+1),(RAM(I1),I1=MAXOUT-2,MAXOUT)
        IF (TXTPTS(NPTS+1).EQ.'$') THEN
          GOTO 29
        ENDIF
        MAXOUT=MAXOUT-3
        NPTS=NPTS+1
      GOTO 20
   29 CONTINUE
      CLOSE(LU4)
C     Recalling the data specifying projection vector, which is used
C     in 2-D calculations for projection of the gridpoint coordinates
C     to the plane defined by rays.
      CALL RSEP3R('PROJ1',PROJ1,0.)
      CALL RSEP3R('PROJ2',PROJ2,0.)
      CALL RSEP3R('PROJ3',PROJ3,0.)
      MRAMP=MAXOUT-NPTS
      IF (MRAMP.LE.1) CALL CIEROR(1,TXTERR)
      NRAMT=MRAMP+1
      DO 30, I1=NRAMT,MAXOUT
        IRAM(I1)=0
  30  CONTINUE
      RETURN
      END
C
C=======================================================================
C
      SUBROUTINE CIWB(I1B,I2B,I3B,I1C,I2C,I3C,X1,X2,X3,DWB,IR,ROOT)
C
C----------------------------------------------------------------------
C Subroutine for the computation of the local coordinate WB.
      INTEGER I1B,I2B,I3B,I1C,I2C,I3C,IR
      REAL X1,X2,X3,ROOT(3),DWB
C Input:
C     I1B,I2B,I3B,I1C,I2C,I3C... Integers specifying the six
C             points on the rays, which define the ray cell.
C             Numbers 1,2,3 denote the first, second and third ray,
C             character B denotes the bottom of the ray cell and C
C             denotes the top of the ray cell.
C             Each integer contains the address just before
C             the parameters of the corresponding point:
C             the first parameter of the first point: RAM(I1B+1)
C             In 2-D computations I3B and I3C need not be specified.
C     X1,X2,X3... Coordinates of the examined point.
C     DWB...  The points with local coordinate WB from
C             range [0-DWB,1+DWB] are taken into account.
C Output:
C     IR...   Number of computed values of WB from range [0-DWB,1+DWB].
C     ROOT... Computed values of wb from range [0-DWB,1+DWB].
C
C Subroutines and external functions required:
      EXTERNAL CICUB,CICUBR,CIQUAR,CIDET3,CISUBD
      REAL CICUB,CIDET3,CISUBD
C
C ...........................
C Common block /MTTC/ to store the information about triangles and rays:
      INCLUDE 'mtt.inc'
C <A HREF="mtt.inc" TYPE="text/html">mtt.inc</A>.
C.......................................................................
      INTEGER I4,I5
      REAL YY(3,3),ZZ(3,3)
      REAL AAA,BBB,CCC,DDD,EEE,FFF
      INTEGER NRR
      REAL RR(4),CRR(4)
      REAL R1,R2
C-----------------------------------------------------------------------
C     Computation of the coefficients AAA,BBB,CCC,DDD
C     of the cubic equation:
C
      YY(1,1)=RAM(I1B+1)-RAM(I1C+1)
      YY(2,1)=RAM(I1B+2)-RAM(I1C+2)
      YY(3,1)=RAM(I1B+3)-RAM(I1C+3)
      YY(1,2)=RAM(I2B+1)-RAM(I2C+1)
      YY(2,2)=RAM(I2B+2)-RAM(I2C+2)
      YY(3,2)=RAM(I2B+3)-RAM(I2C+3)
      IF (L3D) THEN
        YY(1,3)=RAM(I3B+1)-RAM(I3C+1)
        YY(2,3)=RAM(I3B+2)-RAM(I3C+2)
        YY(3,3)=RAM(I3B+3)-RAM(I3C+3)
      ELSE
        YY(1,3)=0.
        YY(2,3)=0.
        YY(3,3)=0.
      ENDIF
C
      ZZ(1,1)=RAM(I1C+1)-X1
      ZZ(2,1)=RAM(I1C+2)-X2
      ZZ(3,1)=RAM(I1C+3)-X3
      ZZ(1,2)=RAM(I2C+1)-X1
      ZZ(2,2)=RAM(I2C+2)-X2
      ZZ(3,2)=RAM(I2C+3)-X3
      IF (L3D) THEN
        ZZ(1,3)=RAM(I3C+1)-X1
        ZZ(2,3)=RAM(I3C+2)-X2
        ZZ(3,3)=RAM(I3C+3)-X3
      ELSE
        ZZ(1,3)=PROJ1
        ZZ(2,3)=PROJ2
        ZZ(3,3)=PROJ3
      ENDIF
C
      AAA=CIDET3(YY)
      IF (L2D.AND.AAA.NE.0.) THEN
C       <A NAME="error35"></A><FONT COLOR="RED">MTT-35</FONT>
        CALL ERROR('MTT-35: Cubic equation in 2-D.')
C       This error should not appear.
C       Please <A HREF="#author">contact the author</A>.
      ENDIF
      BBB=CISUBD(ZZ,YY)
      CCC=CISUBD(YY,ZZ)
      DDD=CIDET3(ZZ)
C
C
      IF (DDD.EQ.0.) THEN
        IF(((ZZ(1,1).EQ.0.).AND.(ZZ(2,1).EQ.0.).AND.(ZZ(3,1).EQ.0.)).OR.
     *     ((ZZ(1,2).EQ.0.).AND.(ZZ(2,2).EQ.0.).AND.(ZZ(3,2).EQ.0.)).OR.
     *     ((ZZ(1,3).EQ.0.).AND.(ZZ(2,3).EQ.0.).AND.(ZZ(3,3).EQ.0.)))
     *     THEN
C         Special case, point X coincides with one of the points forming
C         the top of the ray cell:
          IR=1
          ROOT(1)=1.
          RETURN
        ENDIF
      ENDIF
C
C     Solving the equation according to their coefficients:
      IF (AAA.EQ.0.) THEN
        IF((YY(1,1).EQ.0.).AND.(YY(2,1).EQ.0.).AND.(YY(3,1).EQ.0.).AND.
     *     (YY(1,2).EQ.0.).AND.(YY(2,2).EQ.0.).AND.(YY(3,2).EQ.0.).AND.
     *     (YY(1,3).EQ.0.).AND.(YY(2,3).EQ.0.).AND.(YY(3,3).EQ.0.))
     *     THEN
C         The top of the ray cell coincides with the bottom of the
C         ray cell, point X cannot lie inside the cell:
          IR=0
          RETURN
        ENDIF
        IF (BBB.EQ.0.) THEN
C         Linear equation:
          IF (CCC.EQ.0.) THEN
C           The equation has no roots:
            IR=0
            RETURN
          ENDIF
          R1=-DDD/CCC
          IF (R1.GE.0.-DWB.AND.R1.LE.1.+DWB) THEN
            IR=1
            ROOT(1)=R1
          ELSE
            IR=0
          ENDIF
        ELSE
C         Quadratic equation:
          CALL CIQUAR(BBB,CCC,DDD,DWB,IR,R1,R2)
          IF (IR.GE.1) THEN
            IF ((R1.LT.0.-DWB).OR.(R1.GT.1.+DWB)) THEN
C             <A NAME="error11"></A><FONT COLOR="RED">MTT-11</FONT>
              CALL ERROR('MTT-11: First root of quadratic eq. wrong')
C             This error should not appear.
C             Please <A HREF="#author">contact the author</A>.
            ENDIF
            ROOT(1)=R1
          ENDIF
          IF (IR.GE.2) THEN
            IF ((R2.LT.0.-DWB).OR.(R2.GT.1.+DWB)) THEN
C             <A NAME="error12"></A><FONT COLOR="RED">MTT-12</FONT>
              CALL ERROR('MTT-12: Second root of quadratic eq. wrong')
C             This error should not appear.
C             Please <A HREF="#author">contact the author</A>.
            ENDIF
            ROOT(2)=R2
          ENDIF
        ENDIF
      ELSE
C       Cubic equation:
C       Computation of the coefficients EEE,FFF,CCC of the derivative
C       of the cubic equation:
        EEE=3.*AAA
        FFF=2.*BBB
C
C       Solving the equation for the derivative:
        CALL CIQUAR(EEE,FFF,CCC,DWB,IR,R1,R2)
C       Deciding, whether the cubic equation is to be solved:
        RR(1)=0.-DWB
        IF (IR.GE.1) THEN
          RR(2)=R1
          NRR=3
        ELSE
          NRR=2
        ENDIF
        IF (IR.GE.2) THEN
          RR(NRR)=R2
          NRR=NRR+1
        ENDIF
        RR(NRR)=1.+DWB
        DO 10, I4=1,NRR
          CRR(I4)=CICUB(AAA,BBB,CCC,DDD,RR(I4))
  10    CONTINUE
        IR=0
        I4=1
  20    CONTINUE
          IF ((CRR(I4)*CRR(I4+1)).LE.0.) THEN
            IR=IR+1
            I4=I4+1
          ELSE
            DO 30, I5=I4,NRR-1
              CRR(I5)=CRR(I5+1)
              RR(I5)=RR(I5+1)
  30        CONTINUE
            NRR=NRR-1
          ENDIF
        IF (I4.LT.NRR) GOTO 20
        IF (IR.GT.0) THEN
C         Solving the cubic equation:
          CALL CICUBR(AAA,BBB,CCC,DDD,RR,IR,ROOT)
        ENDIF
      ENDIF
      RETURN
      END
C
C
C=======================================================================
C
      SUBROUTINE CIQUAR(AAA,BBB,CCC,DWB,IR,R1,R2)
C
C----------------------------------------------------------------------
C Subroutine to solve the quadratic equation on the interval
C <0-DWB,1+DWB>.
      INTEGER IR
      REAL AAA,BBB,CCC,DWB,R1,R2
C Input:
C     AAA,BBB,CCC... Coefficients of the equation.
C     DWB... The roots from range [0-DWB,1+DWB] are taken into account.
C Output:
C     IR... Number of real roots of the equation from the interval.
C     R1,R2. Real roots of the equation, R1<R2, or undefined.
C
C.......................................................................
      REAL QQ
C----------------------------------------------------------------------
C
C     Solution of quadratic equation following the algorithm
C     from Numerical Recipes:
C
      QQ=BBB*BBB-4.*AAA*CCC
      IF (QQ.LT.0.) THEN
C       Determinant negative, no real roots:
        IR=0
        RETURN
      ENDIF
      QQ=-0.5*(BBB+SIGN(1.,BBB)*SQRT(QQ))
      R1=QQ/AAA
      IF (QQ.EQ.0.) THEN
        R2=R1
        IR=1
      ELSE
        R2=CCC/QQ
        IR=2
        IF (R1.GT.R2) THEN
          QQ=R2
          R2=R1
          R1=QQ
        ENDIF
      ENDIF
      IF ((R1.LT.0.-DWB).OR.(R1.GT.1.+DWB)) THEN
        IR=IR-1
        R1=R2
      ENDIF
      IF ((R2.LT.0.-DWB).OR.(R2.GT.1.+DWB)) THEN
        IF (IR.GE.1) IR=IR-1
      ENDIF
      RETURN
      END
C
C=======================================================================
C
      SUBROUTINE CIQD
C
C.......................................................................
C
C Subroutine designed to read the input data describing the names
C of the output files with the interpolated quantities, to read the
C quantities computed by CRT, to interpolate and to write the output
C files with the interpolated quantities.
C
C.......................................................................
C Subroutines and external functions required:
      EXTERNAL CIAA,CIBB,LOWER
      REAL CIAA,CIBB
C
C Common block /MTTC/ to store the information about triangles and rays:
      INCLUDE 'mtt.inc'
C For the description of the parameters stored in the common block
C MTTC refer to the file <A HREF="mtt.inc" TYPE="text/html">mtt.inc</A>.
C ...........................
C Common block /POINTC/ to store the results of complete ray tracing:
      INCLUDE 'pointc.inc'
C <A HREF="pointc.inc" TYPE="text/html">pointc.inc</A>.
C None of the storage locations of the common block are altered.
C.......................................................................
C Subroutines and external functions required:
      EXTERNAL LENGTH
      INTEGER LENGTH
C.......................................................................
C     Auxiliary storage locations for all the entries:
      INTEGER LU5
      INTEGER I1B,I2B,I3B,I1C,I2C,I3C
      REAL WB,WC,W1,W2,W3,X1,X2,X3
      INTEGER I1,I2,I3,I4,I5,I6,I7,I8,INDX
      REAL AWB,AWC,TA1,TA2,TA3,PA(3,3),AA(3,3),KSI
      REAL OUTMIN(MOUT),OUTMAX(MOUT)
      CHARACTER*(4+8*MOUT) FORMAT
      CHARACTER*20 FORMA1,TEXT
      CHARACTER*52 TXTERR
C.......................................................................
C
C     Reading filename of the output file with points:
      CALL RSEP3T('MTTPTS',FILOUT,' ')
      IF (FILOUT.NE.' ') THEN
        LPTS=.TRUE.
      ELSE
        LPTS=.FALSE.
      ENDIF
      CALL RSEP3I('MTTLIN',MTTLIN,0)
C
      IF (.NOT.LPTS) THEN
C       Interpolation to the 3-D grid:
C       Reading filenames of the output files, recording
C       which quantities are to be written into the files:
        CALL RSEP3T('NUM',FOUT(0),'mtt-num.out')
        CALL RSEP3T('MTT',FOUT(1),'mtt-tt.out')
        IF (FOUT(1).NE.' ') THEN
          CHOUT(1)='mtt'
          CHOUT(2)=' '
          CHOUT(3)=' '
          CHOUT(4)=' '
          NOUT=4
          CALL RSEP3T('MP1',FOUT(2),' ')
          IF (FOUT(2).NE.' ') CHOUT(2)='mp1'
          CALL RSEP3T('MP2',FOUT(3),' ')
          IF (FOUT(3).NE.' ') CHOUT(3)='mp2'
          CALL RSEP3T('MP3',FOUT(4),' ')
          IF (FOUT(4).NE.' ') CHOUT(4)='mp3'
        ELSE
          NOUT=0
          CALL RSEP3T('MP1',FOUT(NOUT+1),' ')
          IF (FOUT(NOUT+1).NE.' ') THEN
            CHOUT(NOUT+1)='mp1'
            NOUT=NOUT+1
          ENDIF
          CALL RSEP3T('MP2',FOUT(NOUT+1),' ')
          IF (FOUT(NOUT+1).NE.' ') THEN
            CHOUT(NOUT+1)='mp2'
            NOUT=NOUT+1
          ENDIF
          CALL RSEP3T('MP3',FOUT(NOUT+1),' ')
          IF (FOUT(NOUT+1).NE.' ') THEN
            CHOUT(NOUT+1)='mp3'
            NOUT=NOUT+1
          ENDIF
        ENDIF
        CALL RSEP3T('MHIST',FOUT(NOUT+1),' ')
        IF (FOUT(NOUT+1).NE.' ') THEN
          CHOUT(NOUT+1)=  'mhist'
          NOUT=NOUT+1
        ENDIF
C
C       Reading the list QNAMES of the possible interpolated quantities:
        CALL MTTQ
C       Recording the quantities to be interpolated:
        DO 5, I1=1,MOUT
          IF (QNAMES(I1).EQ.' ') GOTO 6
          CALL RSEP3T(QNAMES(I1),FOUT(NOUT+1),' ')
          IF (FOUT(NOUT+1).NE.' ') THEN
            NOUT=NOUT+1
            IF (NOUT.GT.MOUT) CALL CIEROR(27,TXTERR)
            CHOUT(NOUT)=QNAMES(I1)
C           Reading the input data for the interpolated quantity:
            CALL MTTQD(QNAMES(I1))
          ENDIF
  5     CONTINUE
  6     CONTINUE
C
        NQ=5+NOUT
        CALL CIGRID
      ELSE
C       Interpolation to the individual points:
        NOUT=0
C       Reading the list QNAMES of the possible interpolated quantities:
        CALL MTTQ
C       Reading the input filename:
        CALL RSEP3T('PTS',FILPTS,' ')
        IF (FILPTS.EQ.' ') THEN
C         <A NAME="error19"></A><FONT COLOR="RED">MTT-19</FONT>
          CALL ERROR('MTT-19: File PTS not specified.')
C         If MTTPTS is given, PTS must be specified too.
C         See <A HREF="#points">description of input data.</A>
        ENDIF
C       Reading the data specifying the quantities to be written into
C       the individual columns of the output file:
        FORMA1='COLUMN00'
        I1=0
   7    CONTINUE
          I1=I1+1
          FORMA1(8:8)=CHAR(ICHAR('0')+MOD(I1,10))
          FORMA1(7:7)=CHAR(ICHAR('0')+I1/10)
          IF     (I1.EQ.1) THEN
            CALL RSEP3T(FORMA1,TEXT,'x1')
          ELSEIF (I1.EQ.2) THEN
            CALL RSEP3T(FORMA1,TEXT,'x2')
          ELSEIF (I1.EQ.3) THEN
            CALL RSEP3T(FORMA1,TEXT,'x3')
          ELSE
            CALL RSEP3T(FORMA1,TEXT,' ')
          ENDIF
          IF (TEXT.NE.' ') THEN
            CALL LOWER(TEXT)
            IF (TEXT.EQ.'x1'   ) GOTO 9
            IF (TEXT.EQ.'x2'   ) GOTO 9
            IF (TEXT.EQ.'x3'   ) GOTO 9
            IF (TEXT.EQ.'num'  ) GOTO 9
            IF (TEXT.EQ.'mtt'  ) GOTO 9
            IF (TEXT.EQ.'mhist') GOTO 9
            IF (TEXT.EQ.'mp1'  ) GOTO 9
            IF (TEXT.EQ.'mp2'  ) GOTO 9
            IF (TEXT.EQ.'mp3'  ) GOTO 9
            DO 8, I2=1,MOUT
              IF (TEXT.EQ.QNAMES(I2)) GOTO 9
  8         CONTINUE
C           <A NAME="error20"></A><FONT COLOR="RED">MTT-20</FONT>
            CALL ERROR('MTT-20: Wrong value of COLUMN.')
C           See allowed values of COLUMNii in the
C           <A HREF="#column">description of file SEP.</A>
  9         CONTINUE
            IF (I1.EQ.69) THEN
              CALL RSEP3T('COLUMN70',TEXT,' ')
              IF (TEXT.NE.' ') THEN
C               <A NAME="error21"></A><FONT COLOR="RED">MTT-21</FONT>
                CALL ERROR('MTT-21: More than 69 COLUMNs.')
C               Currently up to 69 values of COLUMNii may be specified.
C               See allowed values of COLUMNii in the
C               <A HREF="#column">description of file SEP.</A>
              ENDIF
            ENDIF
C
            NOUT=NOUT+1
            IF (NOUT.GT.MOUT) CALL CIEROR(27,TXTERR)
            CHOUT(NOUT)=TEXT
            FOUT(NOUT)=' '
C           Reading the input data for the interpolated quantity:
            CALL MTTQD(TEXT)
            IF (TEXT.EQ.'mtt') THEN
              IF (NOUT+3.GT.MOUT) CALL CIEROR(27,TXTERR)
              NOUT=NOUT+1
              CHOUT(NOUT)=' '
              FOUT(NOUT)=' '
              NOUT=NOUT+1
              CHOUT(NOUT)=' '
              FOUT(NOUT)=' '
              NOUT=NOUT+1
              CHOUT(NOUT)=' '
              FOUT(NOUT)=' '
            ENDIF
            GOTO 7
          ENDIF
C       End of the loop over future columns of the output file.
        NQ=5+NOUT
        CALL CIPTS
      ENDIF
      RETURN
C
C=======================================================================
C
      ENTRY CIQRI
C
C.......................................................................
C
C Entry designed to read the output of the CRT at an initial point of
C a ray.
C
      DO 10, I1=1,NOUT
        IF (CHOUT(I1).EQ.'mtt') tHEN
C         Travel time:
          RAM(NRAMP+(5+I1))=YI(1)
C         Three components of the slowness vector:
          RAM(NRAMP+(5+I1+1))=YI(6)
          RAM(NRAMP+(5+I1+2))=YI(7)
          RAM(NRAMP+(5+I1+3))=YI(8)
        ELSEIF (CHOUT(I1).EQ.'mp1') THEN
C         First component of the slowness vector:
          RAM(NRAMP+(5+I1))=YI(6)
        ELSEIF (CHOUT(I1).EQ.'mp2') ThEN
C         Second component of the slowness vector:
          RAM(NRAMP+(5+I1))=YI(7)
        ELSEIF (CHOUT(I1).EQ.'mp3') THEN
C         Third component of the slowness vector:
          RAM(NRAMP+(5+I1))=YI(8)
        ELSEIF (CHOUT(I1).EQ.'mhist') THEN
C         Ray history:
          IRAM(NRAMP+(5+I1))=ISHEET
        ELSEIF ((CHOUT(I1).EQ.' ') .OR.(CHOUT(I1).EQ.'x1').OR.
     *          (CHOUT(I1).EQ.'x2').OR.(CHOUT(I1).EQ.'x3')) THEN
C         Nothing to do:
          CONTINUE
        ELSE
C         User-defined quantity:
          RAM(NRAMP+(5+I1))=0.
          CALL MTTQRI(CHOUT(I1),RAM(NRAMP+(5+I1)))
        ENDIF
  10  CONTINUE
      NRAMP=NRAMP+NQ
      RETURN
C=======================================================================
C
      ENTRY CIQRA
C
C.......................................................................
C
C Entry designed to read the output of the CRT at other than initial
C point of a ray.
C
      DO 20, I1=1,NOUT
        IF (CHOUT(I1).EQ.'mtt') THEN
C         Travel time:
          RAM(NRAMP+(5+I1))=Y(1)
C         Three components of the slowness vector:
          RAM(NRAMP+(5+I1+1))=Y(6)
          RAM(NRAMP+(5+I1+2))=Y(7)
          RAM(NRAMP+(5+I1+3))=Y(8)
        ELSEIF (CHOUT(I1).EQ.'mhist') THEN
C         Ray history:
          IRAM(NRAMP+(5+I1))=ISHEET
        ELSEIF (CHOUT(I1).EQ.'mp1') THEN
C         First component of the slowness vector:
          RAM(NRAMP+(5+I1))=Y(6)
        ELSEIF (CHOUT(I1).EQ.'mp2') THEN
C         Second component of the slowness vector:
          RAM(NRAMP+(5+I1))=Y(7)
        ELSEIF (CHOUT(I1).EQ.'mp3') THEN
C         Third component of the slowness vector:
          RAM(NRAMP+(5+I1))=Y(8)
        ELSEIF ((CHOUT(I1).EQ.' ') .OR.(CHOUT(I1).EQ.'x1').OR.
     *          (CHOUT(I1).EQ.'x2').OR.(CHOUT(I1).EQ.'x3')) THEN
C         Nothing to do:
          CONTINUE
        ELSE
C         User-defined quantity:
          RAM(NRAMP+(5+I1))=0.
          CALL MTTQRA(CHOUT(I1),RAM(NRAMP+(5+I1)))
        ENDIF
  20  CONTINUE
      NRAMP=NRAMP+NQ
      RETURN
C
C=======================================================================
C
      ENTRY CIQI(WB,WC,W1,W2,W3,I1B,I2B,I3B,I1C,I2C,I3C,X1,X2,X3)
C
C.......................................................................
C
C Entry designed to perform the interpolation.
      DO 30, I5=1,NOUT
        IF (CHOUT(I5).EQ.'mtt') THEN
          IF (MTTLIN.EQ.1) THEN
C           ............................................................
C           Travel time - bilinear interpolation:
            RAM(NRAMT+I5)=
     *         WB*W1*RAM(I1B+(5+I5))+WB*W2*RAM(I2B+(5+I5))+
     *         WC*W1*RAM(I1C+(5+I5))+WC*W2*RAM(I2C+(5+I5))
            IF (L3D) THEN
              RAM(NRAMT+I5)=RAM(NRAMT+I5)+
     *           WB*W3*RAM(I3B+(5+I5))+
     *           WC*W3*RAM(I3C+(5+I5))
            ENDIF
C           ............................................................
          ELSE
C           Travel time - bicubic interpolation:
C For the interpolation scheme used below refer to:
C Bulant, P. & Klimes, L.: Interpolation of ray-theory travel times
C within ray cells, Seismic Waves in Complex 3-D Structures, Report 7
C Department of Geophysics, Charles University, Prague, 1998.
            AWB=CIAA(WB)
            AWC=CIAA(WC)
            TA1=AWB*RAM(I1B+(5+I5))+AWC*RAM(I1C+(5+I5))+
     *          CIBB(WB,I1B,I1C,I1B+5+I5)+CIBB(WC,I1C,I1B,I1C+5+I5)
            TA2=AWB*RAM(I2B+(5+I5))+AWC*RAM(I2C+(5+I5))+
     *          CIBB(WB,I2B,I2C,I2B+5+I5)+CIBB(WC,I2C,I2B,I2C+5+I5)
            PA(1,1)=AWB*RAM(I1B+(5+I5+1))+AWC*RAM(I1C+(5+I5+1))
            PA(2,1)=AWB*RAM(I1B+(5+I5+2))+AWC*RAM(I1C+(5+I5+2))
            PA(3,1)=AWB*RAM(I1B+(5+I5+3))+AWC*RAM(I1C+(5+I5+3))
            PA(1,2)=AWB*RAM(I2B+(5+I5+1))+AWC*RAM(I2C+(5+I5+1))
            PA(2,2)=AWB*RAM(I2B+(5+I5+2))+AWC*RAM(I2C+(5+I5+2))
            PA(3,2)=AWB*RAM(I2B+(5+I5+3))+AWC*RAM(I2C+(5+I5+3))
            AA(1,1)=WB*RAM(I1B+1)+WC*RAM(I1C+1)
            AA(2,1)=WB*RAM(I1B+2)+WC*RAM(I1C+2)
            AA(3,1)=WB*RAM(I1B+3)+WC*RAM(I1C+3)
            AA(1,2)=WB*RAM(I2B+1)+WC*RAM(I2C+1)
            AA(2,2)=WB*RAM(I2B+2)+WC*RAM(I2C+2)
            AA(3,2)=WB*RAM(I2B+3)+WC*RAM(I2C+3)
            RAM(NRAMT+I5)=
     *        CIAA(W1)*TA1+CIAA(W2)*TA2 +
     *        W1**2*(PA(1,1)*(X1-AA(1,1))+PA(2,1)*(X2-AA(2,1))+
     *               PA(3,1)*(X3-AA(3,1))) +
     *        W2**2*(PA(1,2)*(X1-AA(1,2))+PA(2,2)*(X2-AA(2,2))+
     *               PA(3,2)*(X3-AA(3,2)))
            IF (L3D) THEN
              TA3=AWB*RAM(I3B+(5+I5))+AWC*RAM(I3C+(5+I5))+
     *          CIBB(WB,I3B,I3C,I3B+5+I5)+CIBB(WC,I3C,I3B,I3C+5+I5)
              PA(1,3)=AWB*RAM(I3B+(5+I5+1))+AWC*RAM(I3C+(5+I5+1))
              PA(2,3)=AWB*RAM(I3B+(5+I5+2))+AWC*RAM(I3C+(5+I5+2))
              PA(3,3)=AWB*RAM(I3B+(5+I5+3))+AWC*RAM(I3C+(5+I5+3))
              AA(1,3)=WB*RAM(I3B+1)+WC*RAM(I3C+1)
              AA(2,3)=WB*RAM(I3B+2)+WC*RAM(I3C+2)
              AA(3,3)=WB*RAM(I3B+3)+WC*RAM(I3C+3)
              KSI=0
              DO 24, I6=1,3
                DO 23, I7=1,3
                  DO 22, I8=1,3
                    KSI=KSI+PA(I8,I7)*(AA(I8,I6)-AA(I8,I7))
  22              CONTINUE
  23            CONTINUE
  24          CONTINUE
              KSI=KSI*0.5 + 2*(TA1+TA2+TA3)
              RAM(NRAMT+I5)=RAM(NRAMT+I5) + CIAA(W3)*TA3 +
     *          W3**2*(PA(1,3)*(X1-AA(1,3))+PA(2,3)*(X2-AA(2,3))+
     *                 PA(3,3)*(X3-AA(3,3))) +
     *          W1*W2*W3*KSI
            ENDIF
          ENDIF
C         ..............................................................
        ELSEIF (CHOUT(I5).EQ.'mhist') THEN
C         Ray history - no interpolation:
          IRAM(NRAMT+I5)=IRAM(I1B+(5+I5))
        ELSEIF ((CHOUT(I5).EQ.' ') .OR.(CHOUT(I5).EQ.'x1').OR.
     *          (CHOUT(I5).EQ.'x2').OR.(CHOUT(I5).EQ.'x3')) THEN
C         Nothing to do:
          CONTINUE
        ELSE
C         Slowness vector, ray propagator matrix or other real quantity
C         - bilinear interpolation:
          RAM(NRAMT+I5)=
     *       WB*W1*RAM(I1B+(5+I5))+WB*W2*RAM(I2B+(5+I5))+
     *       WC*W1*RAM(I1C+(5+I5))+WC*W2*RAM(I2C+(5+I5))
          IF (L3D) RAM(NRAMT+I5)=RAM(NRAMT+I5)+
     *       WB*W3*RAM(I3B+(5+I5))+
     *       WC*W3*RAM(I3C+(5+I5))
        ENDIF
  29    CONTINUE
  30  CONTINUE
      RETURN
C
C=======================================================================
C
      ENTRY CIQW(LU5)
C
C.......................................................................
C
C Entry designed to write the output files.
C
C     Writing numbers of computed arrivals:
      IF (.NOT.LPTS) THEN
        I6=N1*N2*N3
      ELSE
        I6=NPTS
      ENDIF
      IF (I6.GT.MRAMP) THEN
        I1=MRAMP-I6
        WRITE(TXTERR,'(A,I9,A)')
     *  'MTT-31: Array RAM too small,',I1,' units missing.'
        CALL CIEROR(31,TXTERR)
      ENDIF
      NRAMP=0
      I5=0
      DO 110, I1=0,I6-1
        NRAMP=NRAMP+1
        I4=0
        INDX=MAXOUT-I1
  105   CONTINUE
C         Check for the consistentcy of the results
          IF (INDX.LE.MRAMP.OR.INDX.GT.MAXOUT) THEN
C           <A NAME="error14"></A><FONT COLOR="RED">MTT-14</FONT>
            CALL ERROR('MTT-14: Disorder in array RAM')
C           This error should not appear.
C           Please <A HREF="#author">contact the author</A>.
          ENDIF
          INDX=IRAM(INDX)
          IF (INDX.EQ.0) THEN
            IF (.NOT.LPTS) IRAM(NRAMP)=I4
            I5=I5+I4
            GOTO 110
          ENDIF
          I4=I4+1
        GOTO 105
  110 CONTINUE
      IF (NRAMP.NE.I6) THEN
C       <A NAME="error15"></A><FONT COLOR="RED">MTT-15</FONT>
        CALL ERROR('MTT-15: Disorder in array RAM')
C       This error should not appear.
C       Please <A HREF="#author">contact the author</A>.
      ENDIF
      IF ((.NOT.LPTS).AND.(FOUT(0).NE.' ')) THEN
        CALL WARRAI(LU5,FOUT(0),'FORMATTED',.FALSE.,0,.FALSE.,0,
     *                                                    N1*N2*N3,IRAM)
      ENDIF
C
C
C     Writing interpolated quantities:
      IF ((NOUT.GE.1).AND.(.NOT.LPTS)) THEN
C       Interpolation to the grid:
        IF (I5.GT.MRAMP) THEN
          I1=MRAMP-I5
          WRITE(TXTERR,'(A,I9,A)')
     *    'MTT-31: Array RAM too small,',I1,' units missing.'
          CALL CIEROR(31,TXTERR)
        ENDIF
        DO 140, I4=1,NOUT
          IF (FOUT(I4).EQ.' ') GOTO 139
          NRAMP=0
          DO 37, I3=0,N3-1
          DO 36, I2=0,N2-1
          DO 35, I1=0,N1-1
            INDX=I3*N1*N2+I2*N1+I1
            INDX=MAXOUT-INDX
            IF (IRAM(INDX).EQ.0) GOTO 33
            INDX=IRAM(INDX)
  32        CONTINUE
C             Check for the consistentcy of the results
              IF (INDX.LE.MRAMP.OR.INDX.GT.MAXOUT) THEN
C               <A NAME="error16"></A><FONT COLOR="RED">MTT-16</FONT>
                CALL ERROR('MTT-16: Disorder in array RAM')
C               This error should not appear.
C               Please <A HREF="#author">contact the author</A>.
              ENDIF
              NRAMP=NRAMP+1
              IF (CHOUT(I4).EQ.'mhist') THEN
C               Ray history:
                IRAM(NRAMP)=IRAM(INDX+I4)
              ELSEIF (CHOUT(I4).NE.' ') THEN
C               Travel time or other real quantity:
                RAM(NRAMP)=RAM(INDX+I4)
              ENDIF
              INDX=IRAM(INDX)
            IF (INDX.NE.0) GOTO 32
  33        CONTINUE
  35      CONTINUE
  36      CONTINUE
  37      CONTINUE
          IF (NRAMP.NE.I5) THEN
C           <A NAME="error17"></A><FONT COLOR="RED">MTT-17</FONT>
            CALL ERROR('MTT-17: Disorder in array RAM')
C           This error should not appear.
C           Please <A HREF="#author">contact the author</A>.
          ENDIF
          IF (CHOUT(I4).EQ.'mhist') THEN
C           Ray history:
            CALL WARRAI(LU5,FOUT(I4),'FORMATTED',.FALSE.,0,.FALSE.,0,
     *                                                   I5,IRAM)
          ELSEIF (CHOUT(I4).NE.' ') THEN
C           Travel time or other real quantity:
            CALL WARRAY(LU5,FOUT(I4),'FORMATTED',.FALSE.,0.,.FALSE.,0.,
     *                                                   I5,RAM)
          ENDIF
  139     CONTINUE
  140   CONTINUE
      ELSEIF ((NOUT.GE.1).AND.(LPTS).AND.(FILOUT.NE.' ')) THEN
C       Interpolation to individual points:
        IF (NOUT.GT.MRAMP) THEN
          I1=MRAMP-NOUT
          WRITE(TXTERR,'(A,I9,A)')
     *    'MTT-31: Array RAM too small,',I1,' units missing.'
          CALL CIEROR(31,TXTERR)
        ENDIF
        OPEN(LU5,FILE=FILOUT)
        WRITE(LU5,'(A)') '/'
C       Setting output format:
        FORMAT(1:4)='(4A,'
        DO 149, I1=1,NOUT
          OUTMIN(I1)=GIANT
          OUTMAX(I1)=DWARF
  149   CONTINUE
C       Loop over points:
        DO 170, I1=1,NPTS
C         I1 counts the points
          INDX=MAXOUT-I1+1
          I2=0
          I3=0
C         Loop over multivalued arrivals:
  150     CONTINUE
C           I2 counts the arrivals
            INDX=IRAM(INDX)
            IF (INDX.NE.0) THEN
              I3=0
C             I3 counts the output values to be written to MTTPTS
              I2=I2+1
C             Looking for the minimum and maximum values:
              DO 160, I4=1,NOUT
                IF (CHOUT(I4).EQ.'num') THEN
                  I3=I3+1
                  OUTMIN(I3)=AMIN1(OUTMIN(I3),FLOAT(I2))
                  OUTMAX(I3)=AMAX1(OUTMAX(I3),FLOAT(I2))
                ELSEIF (CHOUT(I4).EQ.'mhist') THEN
                  I3=I3+1
                  OUTMIN(I3)=AMIN1(OUTMIN(I3),FLOAT(IRAM(INDX+I4)))
                  OUTMAX(I3)=AMAX1(OUTMAX(I3),FLOAT(IRAM(INDX+I4)))
                ELSEIF (CHOUT(I4).EQ.'x1') THEN
                  I3=I3+1
                  OUTMIN(I3)=AMIN1(OUTMIN(I3),RAM(MAXRAM-3*I1+1))
                  OUTMAX(I3)=AMAX1(OUTMAX(I3),RAM(MAXRAM-3*I1+1))
                ELSEIF (CHOUT(I4).EQ.'x2') THEN
                  I3=I3+1
                  OUTMIN(I3)=AMIN1(OUTMIN(I3),RAM(MAXRAM-3*I1+2))
                  OUTMAX(I3)=AMAX1(OUTMAX(I3),RAM(MAXRAM-3*I1+2))
                ELSEIF (CHOUT(I4).EQ.'x3') THEN
                  I3=I3+1
                  OUTMIN(I3)=AMIN1(OUTMIN(I3),RAM(MAXRAM-3*I1+3))
                  OUTMAX(I3)=AMAX1(OUTMAX(I3),RAM(MAXRAM-3*I1+3))
                ELSEIF (CHOUT(I4).NE.' ') THEN
                  I3=I3+1
                  OUTMIN(I3)=AMIN1(OUTMIN(I3),RAM(INDX+I4))
                  OUTMAX(I3)=AMAX1(OUTMAX(I3),RAM(INDX+I4))
                ENDIF
  160         CONTINUE
              GOTO 150
            ENDIF
C         End of the loop over multivalued arrivals.
          IF (I3.NE.0) THEN
            CALL FORM2(I3,OUTMIN,OUTMAX,FORMAT(5:4+8*I3))
          ENDIF
  170   CONTINUE
C
C       Writing the values at the points:
C       Loop over points:
        DO 200, I1=1,NPTS
C         I1 counts the points
          INDX=MAXOUT-I1+1
          I2=0
C         Loop over multivalued arrivals:
  180     CONTINUE
C           I2 counts the arrivals
            INDX=IRAM(INDX)
            IF (INDX.NE.0) THEN
              I2=I2+1
C             Preparing the output values for the point and the arrival:
              I3=0
C             I3 counts the output values to be written to MTTPTS
              DO 190, I4=1,NOUT
                IF (CHOUT(I4).EQ.'num') THEN
                  I3=I3+1
                  RAM(I3)=FLOAT(I2)
                ELSEIF (CHOUT(I4).EQ.'mhist') THEN
                  I3=I3+1
                  RAM(I3)=FLOAT(IRAM(INDX+I4))
                ELSEIF (CHOUT(I4).EQ.'x1') THEN
                  I3=I3+1
                  RAM(I3)=RAM(MAXRAM-3*I1+1)
                ELSEIF (CHOUT(I4).EQ.'x2') THEN
                  I3=I3+1
                  RAM(I3)=RAM(MAXRAM-3*I1+2)
                ELSEIF (CHOUT(I4).EQ.'x3') THEN
                  I3=I3+1
                  RAM(I3)=RAM(MAXRAM-3*I1+3)
                ELSEIF (CHOUT(I4).NE.' ') THEN
                  I3=I3+1
                  RAM(I3)=RAM(INDX+I4)
                ENDIF
  190         CONTINUE
              WRITE(LU5,FORMAT(1:4+8*I3))
     *          '''',TXTPTS(I1)(1:LENGTH(TXTPTS(I1))),'''',
     *          (' ',RAM(I4),I4=1,I3),' /'
              GOTO 180
            ENDIF
C         End of the loop over multivalued arrivals.
  200   CONTINUE
        WRITE(LU5,'(A)') '/'
        CLOSE(LU5)
      ENDIF
C
      RETURN
      END
C
C=======================================================================
C
      SUBROUTINE CIEROR(IERR,TXTERR)
C
C-----------------------------------------------------------------------
      INTEGER IERR
      CHARACTER*52 TXTERR
C
C Subroutine designed to print error messages of different
C subroutines of the program MTT using subroutine ERROR.
C
C Input:
C     IERR... Index of the error.
C     TXTERR... Description of the error.
C No output.
C-----------------------------------------------------------------------
C
      IF     (IERR.EQ.01) THEN
C       <A NAME="error01"></A><FONT COLOR="RED">MTT-01</FONT>
        CALL ERROR('MTT-01: Array (I)RAM too small.')
C       This error may be caused by too small dimension of array
C       RAM. Try to enlarge dimension MRAM in include file
C       <A HREF="../forms/ram.inc" TYPE="text/html">ram.inc</A>.
      ELSEIF (IERR.EQ.27) THEN
C       <A NAME="error27"></A><FONT COLOR="RED">MTT-27</FONT>
        CALL ERROR('MTT-27: Small array FOUT or CHOUT.')
C       This error may be caused by wrongly prescribed
C       <A HREF="#data">input data,</A> or by
C       small parameter MOUT defined in the file
C       <A HREF="mtt.inc" TYPE="text/html">mtt.inc</A>.
      ELSEIF (IERR.EQ.31) THEN
C       <A NAME="error31"></A><FONT COLOR="RED">MTT-31</FONT>
        CALL ERROR(TXTERR)
C       This error may be caused by too small dimension of array
C       RAM. Try to enlarge dimension MRAM in include file
C       <A HREF="../forms/ram.inc" TYPE="text/html">ram.inc</A>.
C       Number of needed aditional units should have been written on
C       standard output by subroutine ERROR.
      ENDIF
      END
C
C=======================================================================
C
      INCLUDE 'mttq.for'
C     <A HREF="mttq.for" TYPE="text/html">mttq.for</A>
      INCLUDE 'error.for'
C     <A HREF="../forms/error.for" TYPE="text/html">error.for</A>
      INCLUDE 'ap.for'
C     <A HREF="ap.for" TYPE="text/html">ap.for</A>
      INCLUDE 'forms.for'
C     <A HREF="../forms/forms.for" TYPE="text/html">forms.for</A>
      INCLUDE 'length.for'
C     <A HREF="../forms/length.for" TYPE="text/html">length.for</A>
      INCLUDE 'sep.for'
C     <A HREF="../forms/sep.for" TYPE="text/html">sep.for</A>
      INCLUDE 'indexi.for'
C     <A HREF="../forms/indexi.for" TYPE="text/html">indexi.for</A>.
C
C=======================================================================
C                                                                 </PRE>
