
C LAST UPDATE:
C++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
C
C************************
C**      LRL_OVALL     **
C************************
C
CD-Routine: Find All Spatial Overlaps - LRL_OVALL
C This routine is used to find all the spots (up to a requested limit) which 
C overlap with a given spatially overlapped spot. A number of ways of 
C specifying the overlap criterion are available (as in LRL_OVLP). The
C Laue Reflection List (LRL) must be sorted on 'xfd' or 'yfd' before this
C routine is called. 
CD-end
CD-Fortran:
      SUBROUTINE  LRL_OVALL (IOVTYP, N, NSPOT, SPOT_L, SPOT_W, 
     +                       SPOTFAC, SPOT_B, SPOT_D, RMAX, CTOF, 
     +                       MM_RAST_X, MM_RAST_Y, MAX_OVLPS, 
     +                       NUM_OV, X_OV, Y_OV, IERR, ERRSTR)
CD-end
      INCLUDE 'implicit_none.finc'
C
C Purpose:  to find list of overlapping spots
C
C          (Used as a service routine for LFN_SAINT but may be
C           called directly if desired)
C
C Author:  Q. Hao. Based on LRL_OVLP from J.W.Campbell et al.
C
C Arguments:
C
      INTEGER IOVTYP
      INTEGER N
      INTEGER NSPOT
      REAL SPOT_L
      REAL SPOT_W
      REAL SPOTFAC
      REAL SPOT_B
      REAL SPOT_D
      REAL RMAX
      REAL CTOF
      REAL MM_RAST_X
      REAL MM_RAST_Y
      INTEGER MAX_OVLPS
      INTEGER NUM_OV
      REAL X_OV(MAX_OVLPS)
      REAL Y_OV(MAX_OVLPS)
      INTEGER IERR
      CHARACTER*(*) ERRSTR
CD-Parameters:
C IOVTYP    i (R)   Flag for calculation of spatial overlaps
C                        = 1, analytical calculation (spot + unused
C                             pixel + border) v spot
C                        = 2, analytical calculation (spot + border) v spot
C                        = 3, analytical calculation spot v spot
C                        = 4, mask method (spot + unused pixel + border) 
C                             v spot
C                        = 5, mask method (spot + border) v spot
C                        = 6, mask method spot v spot
C N         i (R)    Spot number in sorted LRL
C NSPOT     i (R)    Number of spots in the LRL
C SPOT_L    r (R)    Spot length (mm)
C SPOT_W    r (R)    Spot width (mm)
C SPOTFAC   r (R)    Spot expansion factor (See LDM parameter defns.)
C SPOT_B    r (R)    Spot border width (pixels)
C SPOT_D    r (R)    Spot delta (mm)
C RMAX      r (R)    Maximum radius (mm)
C CTOF      r (R)    Crystal to image diastance
C MM_RAST_X r (R)    Conversion factor mm to x-rasters
C MM_RAST_Y r (R)    Conversion factor mm to y-rasters
C MAX_OVLPS i (R)    Maximum number of overlaps to return
C NUM_OV    i (W)    Number of overlapping spots found
C X_OV()    r (W)    'x' coordinates of the NUM_OV overlapping spots (rasters)
C Y_OV()    r (W)    'y' coordinates of the NUM_OV overlapping spots (rasters)
C IERR      i (W)     Error flag = 0, OK
C                                = 1, Spot list not sorted on 'xfd' 
C                                     or 'yfd'
C                                = 2, Spot was not found to be overlapped
C                                  
C ERRSTR    c (W)  Error message string (max 80 characters)
CD-end
C====== Parameter statements:
C
      INCLUDE 'lrl_maxss.finc'
C
C====== GLOBALS:
C
      INCLUDE 'lrl_nodmax.finc'
      INCLUDE 'lrl_data.finc'
C
C====== FUNCTION TYPES:
C 
      LOGICAL LRL_OVQ
      LOGICAL LRL_OVM
      EXTERNAL LRL_BDAT
C
C====== LOCALS:
C 
      LOGICAL    RAD_MASK
      LOGICAL    OVLP
      INTEGER    I
      INTEGER    J
      INTEGER    JJ
      INTEGER    ISPOT1
      INTEGER    ISPOT2
      REAL       X1
      REAL       Y1
      REAL       X2
      REAL       Y2
      REAL       XD
      REAL       YD
      REAL       RASTOMM
      REAL       DELTAM
      REAL       DELTA2
      REAL       D2
      REAL       X_DIFF
      REAL       Y_DIFF
C
C------------------------------------------------------------------------------
C
C====== Get sort order in LRL
C
      IF (ISORT.NE.3.AND.ISORT.NE.4) THEN
         IERR = 1
         ERRSTR = 'Reflections not sorted on xfd or yfd'
         RETURN
      END IF
C
C====== Get delta value or ellipse max. dimension if radial masking
C
      RASTOMM = 1.0/MM_RAST_X
      RAD_MASK = .FALSE.
      IF (SPOT_W.GT.0.0) RAD_MASK = .TRUE.
      IF (RAD_MASK) THEN
         DELTAM = SPOT_L
         IF (SPOTFAC.GT.0.0) THEN
            DELTAM = DELTAM*(1.0+SPOTFAC*RMAX/CTOF)       
         END IF
         IF (SPOT_W.GT.DELTAM) DELTAM = SPOT_W
         DELTAM = DELTAM + (1.0+SPOT_B)*RASTOMM
      ELSE
         DELTAM = SPOT_D
      END IF
C
C====== Adjust delta to a minimum of 10 micron
C
      DELTAM = MAX(DELTAM,0.01)
      DELTA2 = DELTAM**2
C
C====== Other initialisations
C
      NUM_OV = 0
      ISPOT1 = INDX(N)
      IF (DISTOR_CORR) THEN
        X1 = XF_D(ISPOT1)
        Y1 = YF_D(ISPOT1)
      ELSE
        CALL LDM_CORR (IPK, IPL, GCOS_WC, GSIN_WC, GCTOF, 
     +                 XF_D(ISPOT1), YF_D(ISPOT1), X1, Y1) 
      END IF
C
C====== Treat depending on sort order
C
C
C====== Sorted on 'xfd' - search back then forward
C
      IF (ISORT.EQ.3) THEN
         DO 60 JJ = -1, 1, 2
            DO 50 J = 1, NSPOT
               I = N + JJ*J
               IF (I.LT.1.OR.I.GT.NSPOT) GOTO 60   
               ISPOT2 = INDX(I)
               IF (DISTOR_CORR) THEN
                  X2 = XF_D(ISPOT2)
                  Y2 = YF_D(ISPOT2)
               ELSE
                  CALL LDM_CORR (IPK, IPL, GCOS_WC, GSIN_WC, GCTOF, 
     +                           XF_D(ISPOT2), YF_D(ISPOT2), X2, Y2) 
               END IF
C
C====== If X difference exceeds delta then finish this loop
C
               X_DIFF = ABS(X1-X2)
               IF (X_DIFF.GT.DELTAM) GO TO 60
C
C====== If X difference is possible then check Y difference.
C
               Y_DIFF = ABS(Y1-Y2)
               IF (Y_DIFF.LE.DELTAM) THEN
                  D2 = X_DIFF**2 + Y_DIFF**2
                  IF (D2.LE.DELTA2) THEN
C
C====== Radial masking code makes approximation that overlapping
C====== Spots have the same size of ellipse and are in the same
C====== orientation
C
                     OVLP = .TRUE.
                     IF (RAD_MASK) THEN
                        IF (IOVTYP.LE.3) THEN
                           OVLP = LRL_OVQ (SPOT_L, SPOT_W,
     +                            SPOTFAC, SPOT_B, CTOF,
     +                            RASTOMM, X1, Y1, X2, Y2,
     +                            IOVTYP)
                        ELSE
                           OVLP = LRL_OVM (SPOT_L, SPOT_W,
     +                            SPOTFAC, SPOT_B, CTOF,
     +                            MM_RAST_X, MM_RAST_Y, 
     +                            X1, Y1, X2, Y2, IOVTYP-3)
                        END IF
                     END IF
                     IF (OVLP) THEN
                        NUM_OV = NUM_OV + 1
                        IF (NUM_OV.LE.MAX_OVLPS) THEN
                           XD = GXCEN + X2*GMM_RAST_X
                           YD = GYCEN + Y2*GMM_RAST_Y
                           X_OV(NUM_OV) = XD
                           Y_OV(NUM_OV) = YD
                        END IF
                     END IF
                  END IF
               END IF
 50         CONTINUE
 60      CONTINUE
C
C====== Sorted on 'yfd' - search back then forward
C
      ELSE IF (ISORT.EQ.4) THEN
         DO 80 JJ = -1, 1, 2
            DO 70 J = 1, NSPOT
               I = N + JJ*J
               IF (I.LT.1.OR.I.GT.NSPOT) GOTO 80   
               ISPOT2 = INDX(I)
               IF (DISTOR_CORR) THEN
                  X2 = XF_D(ISPOT2)
                  Y2 = YF_D(ISPOT2)
               ELSE
                  CALL LDM_CORR (IPK, IPL, GCOS_WC, GSIN_WC, GCTOF, 
     +                           XF_D(ISPOT2), YF_D(ISPOT2), X2, Y2) 
               END IF
C
C====== If Y difference exceeds delta then finish this loop
C
               Y_DIFF = ABS(Y1-Y2)
               IF (Y_DIFF.GT.DELTAM) GO TO 80
C
C====== If Y difference is possible then check X difference.
C
               X_DIFF = ABS(X1-X2)
               IF (X_DIFF.LE.DELTAM) THEN
                  D2 = X_DIFF**2 + Y_DIFF**2
                  IF (D2.LE.DELTA2) THEN
C
C====== Radial masking code makes approximation that overlapping
C====== Spots have the same size of ellipse and are in the same
C====== orientation
C
                     OVLP = .TRUE.
                     IF (RAD_MASK) THEN
                        IF (IOVTYP.LE.3) THEN
                           OVLP = LRL_OVQ (SPOT_L, SPOT_W,
     +                            SPOTFAC, SPOT_B, CTOF,
     +                            RASTOMM, X1, Y1, X2, Y2,
     +                            IOVTYP)
                        ELSE
                           OVLP = LRL_OVM (SPOT_L, SPOT_W,
     +                            SPOTFAC, SPOT_B, CTOF,
     +                            MM_RAST_X, MM_RAST_Y, 
     +                            X1, Y1, X2, Y2, IOVTYP-3)
                        END IF
                     END IF
                     IF (OVLP) THEN
                        NUM_OV = NUM_OV + 1
                        IF (NUM_OV.LE.MAX_OVLPS) THEN
                           XD = GXCEN + X2*GMM_RAST_X
                           YD = GYCEN + Y2*GMM_RAST_Y
                           X_OV(NUM_OV) = XD
                           Y_OV(NUM_OV) = YD
                        END IF
                     END IF
                  END IF
               END IF
 70         CONTINUE
 80      CONTINUE
      END IF
C
C====== Check that overlap(s) found
C
      IF (NUM_OV.EQ.0) THEN
         IERR = 2
         ERRSTR = 'Inconsistent overlapping criteria'
         RETURN
      END IF
      IF (NUM_OV.GT.MAX_OVLPS) NUM_OV = MAX_OVLPS
      RETURN
      END
