
CD-Section: Laue Unique Data Analysis
C A number of routines are available for generating lists of unique reflections,
C making counts of measured or predicted Laue reflections and generating
C tables of statistics showing the amount of unique data measured or predicted.
CD-end
C LAST UPDATE: 
C+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
C
C**************************
C**     LFN_UNQ_GEN      **
C**************************
C
CD-Routine: Generate Unique Reflections List - LFN_UNQ_GEN
C This routine will generate a list of the unique relections for a given
C resolution range based on the current LDM parameter values for the
C cell and symmetry which must be defined. The unique reflections list
C is stored internally. This routine could equally well be used to aid
C the analysis of monochromatic data.
CD-end
CD-Fortran:
      SUBROUTINE LFN_UNQ_GEN (RESMIN, RESMAX, NUNIQUE, IERR)
CD-end
      INCLUDE 'implicit_none.finc'
C
C Purpose: Generate list of unique reflections
C
C Author:  John W. Campbell, September 1993
C
C Arguments:
C
      REAL RESMIN
      REAL RESMAX
      INTEGER NUNIQUE
      INTEGER IERR
      
CD-Parameters:
C  RESMIN   r (R)   Minimum resolution limit in Angstroms 
C  RESMAX   r (R)   Maximum resolution limit in Angstroms 
C  NUNIQUE  i (W)   No. of unique reflections generated
C  IERR     i (W)   Error flag =0 OK, 
C                              =1 No symmetry defined,
C                              =2 too may reflections to store
C        
C                   Resolution limits may be in either order
CD-end
C
C====== Parameter statements
C 

C
C====== GLOBALS:
C
      EXTERNAL LFN_UNQ_BDAT
      INCLUDE 'lfn_unq.finc'
C
C====== FUNCTION TYPES:
C
      INTEGER INASU
      REAL STHLSQ
C
C====== LOCALS:
C
      LOGICAL ABSENT
      INTEGER IH
      INTEGER IK
      INTEGER IL
      INTEGER IHKL(3)
      INTEGER MLAUE
      INTEGER IHMIN
      INTEGER IHMAX
      INTEGER IKMIN
      INTEGER IKMAX
      INTEGER ILMIN
      INTEGER ILMAX
      INTEGER NTWO10
      INTEGER NTWO20
      INTEGER IFLAG
      INTEGER ND
      INTEGER NSYM
      REAL RSMIN
      REAL RSMAX
      REAL SMIN
      REAL SMAX
      REAL TEMP
      REAL STHLMIN
      REAL STHLMAX
      REAL STHL
      REAL CELL(6)

C     LOGICAL ABSENT          !Systematic absence flag
C     INTEGER IH              !'h' index loop counter
C     INTEGER IK              !'k' index loop counter
C     INTEGER IL              !'l' index loop counter
C     INTEGER IHKL(3)         !Reflection indices
C     INTEGER MLAUE           !Laue group number
C     INTEGER IHMIN           !Minimum 'h' limit
C     INTEGER IHMAX           !Maximum 'h' limit
C     INTEGER IKMIN           !Minimum 'k' limit
C     INTEGER IKMAX           !Maximum 'k' limit
C     INTEGER ILMIN           !Minimum 'l' limit
C     INTEGER ILMAX           !Maximum 'l' limit
C     INTEGER NTWO10          !2**10
C     INTEGER NTWO20          !2**20
C     INTEGER IFLAG           !LDM parameter status flag
C     INTEGER ND              !No. of decimal places flag
C     INTEGER NSYM            !No. of symmetry operators
C     REAL RSMIN              !Minimum (low) resolution limit in Angstroms
C     REAL RSMAX              !Maximum (low) resolution limit in Angstroms
C     REAL SMIN               !Minimum 4sin**2theta/lambda**2 value
C     REAL SMAX               !Maximum 4sin**2theta/lambda**2 value
C     REAL TEMP               !Temporary variable
C     REAL STHLMIN            !Minimum sin**2theta/lambda**2 value
C     REAL STHLMAX            !Maximum sin**2theta/lambda**2 value
C     REAL STHL               !sin**2theta/lambda**2 value
C     REAL CELL(6)            !Cell parameters

      DATA NTWO20/1048576/, NTWO10/1024/
C
C-------------------------------------------------------------------------------
C
C====== Initialisations
C
      IERR = 0
      NUNIQUE = 0
      CALL LDM_GET_NSYM (NSYM, IFLAG)
      IF (NSYM.EQ.0) THEN
         IERR = 1
         RETURN
      END IF
      NUM_UNQ = 0
      CALL LDM_ASUSET (MLAUE)
      RSMIN = RESMIN
      RSMAX = RESMAX
      IF (RSMIN.LE.RSMAX) THEN
         TEMP = RSMAX
         RSMAX = RSMIN
         RSMIN = TEMP
      END IF
      SMIN = 1.0/RSMIN**2
      SMAX = 1.0/RSMAX**2
      STHLMIN = SMIN/4.0
      STHLMAX = SMAX/4.0
      RES_MIN = RSMIN
      RES_MAX = RSMAX
      S_MIN = SMIN
      S_MAX = SMAX
C
C====== Get Laue group and h, k, l limits
C
      CALL LFN_UNQ_LIMS (MLAUE, RSMAX, IHMIN, IHMAX, 
     +                   IKMIN, IKMAX, ILMIN, ILMAX, IERR)
C
C====== Prepare for resolution calculations
C
      CALL LDM_GET_A (CELL(1),IFLAG,ND)
      CALL LDM_GET_B (CELL(2),IFLAG,ND)
      CALL LDM_GET_C (CELL(3),IFLAG,ND)
      CALL LDM_GET_ALPHA (CELL(4),IFLAG,ND)
      CALL LDM_GET_BETA (CELL(5),IFLAG,ND)
      CALL LDM_GET_GAMMA (CELL(6),IFLAG,ND)
      CALL SETRSL (CELL(1),CELL(2),CELL(3),CELL(4),CELL(5),CELL(6))
C
C====== Generate reflection list
C
      DO 200 IH = IHMIN, IHMAX
         DO 150 IK = IKMIN, IKMAX
            DO 100 IL = ILMIN, ILMAX
               IF (IH.EQ.0.AND.IK.EQ.0.AND.IL.EQ.0) GO TO 100
               IHKL(1) = IH
               IHKL(2) = IK
               IHKL(3) = IL
               IF (INASU(IHKL, MLAUE).LE.0) GO TO 100
               CALL LDM_SYSABS (IH, IK, IL, ABSENT)
               IF (ABSENT) GO TO 100
               IF (NUM_UNQ.GE.MAX_UNQ) THEN
                  IERR = 2
                  GO TO 400
               END IF
               STHL = STHLSQ (IH, IK, IL)
               IF (STHL.LT.STHLMIN.OR.STHL.GT.STHLMAX) GO TO 100
               NUM_UNQ = NUM_UNQ + 1
               HKL_UNQ(NUM_UNQ) = NTWO20*(IH+512)
     +                            + NTWO10*(IK+512)
     +                            + IL + 512
               COUNTS(NUM_UNQ) = 0
               MULT_CNT(NUM_UNQ) = 0
               SIGN_CNT(NUM_UNQ) = 0
100         CONTINUE
150      CONTINUE
200   CONTINUE
C
C====== Sort data on h,k,l
C
400   NUNIQUE = NUM_UNQ
      IF (NUM_UNQ.LE.1) RETURN
      CALL INDXIV (HKL_UNQ, NUM_UNQ, INDX_UNQ)
      RETURN
      END
