******************************************************************
*
*       TITLE:  DATA FILTER ROUTINE
*
*       FILE NAME:  CLEAN1.FOR
*
*       PURPOSE:   TO REMOVE NOISE SPIKES FROM DATA BY EMPLOYING
*	           GAUSSIAN STATISTICS.
*
*	AUTHOR            DATE            CHANGE
*	--------          ----            -------
*       A. ROBERTS       12/17/92         ORIGINAL CODE IDL ROUTINE
*       S. B. KRAMER     12/17/92         ADAPTED FOR EDR PROCESSING
*
******************************************************************
      SUBROUTINE CLEAN1(DATA1,NPTS,NTOTB,NTOTG,SIGMUL,BAD,AVE,PASS)
C
C PROGRAM TO AUTOMATICALLY FLAG AND ASSIGN NULL VALUE TO BAD POINTS
C IN A DATASET BASED ON STATISTICAL LOCAL CRITERION (E.G. THE
C DATA POINT IS MORE THAN K SIGMA AWAY FROM THE MEAN OF ITS NEAR
C NEIGHBORS).  EACH POINT IS ANALYZED USING A NUMBER OF LOCAL 
C AVERAGES WITH EACH AVERAGE BEING THE SUM OF 100 POINTS; THE SUM
C MOVES PAST THE POINT.  FLAGGED POINTS ARE REMOVED FROM THE SERIES 
C AND NOT USED FOR SUBSEQUENT TESTS OF POINTS; THIS CLEANS "RATTY" 
C SERIES MUCH BETTER.
C
      INTEGER*4 I100PT(100), IUP(100), IDN(100), PASS
      REAL*4 DATA1(NPTS)
      REAL*8 SUM,SUMSQ,SIG,SUMDIFF
C
C MULTI-PASS LOOP
C
      NBD = 0
      DO IPASS = 1,PASS
C
C LEAVE ROUTINE IF STARTING WITH INSUFFICIENT NUMBER OF POINTS (100)
C
      IF (NPTS.LT.100) GOTO 300   
C
C INITIALIZATION OF SUMS AND I100PT (INDEX LIST)
C ALSO OF IUP,IDN,I100PT,NTOTG,NTOTB
C
      DO IZERO=1, 100
        IUP(IZERO)=0
        IDN(IZERO)=0
        I100PT(IZERO)=0
      ENDDO
C
C REMOVE FILL DATA FROM DATA ARRAY
C
      NTOTG=0
      NTOTB = 0       ! NTOTB = TOTAL NUMBER OF POINTS DELETED BY PROGRAM
      SUM = 0.0D0     ! SUM OF THE 100 DATA POINTS
      SUMSQ = 0.0D0   ! SUM OF THE SQUARES OF THE 100 POINTS
      AVE = BAD
      IPT = 1
      DO NPT1 = 1, 100
   25    IF (ABS(DATA1(IPT)-BAD).LT.0.01) THEN
            IPT = IPT + 1
            IF (IPT.GT.NPTS) GOTO 300   ! INSUFFICIENT NUMBER OF NON-FILL POINTS
            GOTO 25
         ENDIF
         SUM = SUM + DATA1(IPT)
         SUMSQ = SUMSQ + DATA1(IPT)**2
         NTOTG = NTOTG + 1
         I100PT(NPT1) = IPT
         IPT = IPT + 1
         IF (IPT.GT.NPTS) GOTO 300      ! INSUFFICIENT NUMBER OF NON-FILL POINTS
      ENDDO
      AVE = SUM/100.0
      SUMDIFF = SUMSQ - SUM**2/100.0
      IF (SUMDIFF.GE.0.0) THEN
       SIG = DSQRT(SUMDIFF/100.0)  ! DBLE PREC
      ELSE
       SIG = 0.0D0
      END IF
C
C TEST THE POINTS
C
   50 NLOCB = 0    ! NLOCB = THE NUMBER OF BAD POINTS THIS LOOP
      DO J = 1, 100
         I = I100PT(J)
         IF (ABS(DATA1(I)-AVE).GT.SIGMUL*SIG) THEN
            SUM = SUM - DATA1(I)
            SUMSQ = SUMSQ - DATA1(I)**2
            IDN(NLOCB+1) = I
            DATA1(I) = BAD
            NLOCB = NLOCB + 1
            NTOTB = NTOTB + 1
         ENDIF
      ENDDO
      IF (IPT.GT.NPTS) GOTO 200
C
C  UPDATE THE 100 POINT SET SUMS AND I100PT
C
      IPT = I100PT(100) + 1
      IF (IPT.GT.NPTS) GOTO 250
      IINC = 1
      IF (I100PT(1).NE.IDN(1)) THEN
         SUM = SUM - DATA1(I100PT(1))
         SUMSQ = SUMSQ - DATA1(I100PT(1))**2
      ENDIF
      IF (I100PT(1).EQ.IDN(1)) IINC = 0
      DO M = 1, NLOCB+IINC
  150    IF (IPT.GT.NPTS) GOTO 250
         IF (ABS(DATA1(IPT)-BAD).LT.0.01) THEN
            IPT = IPT + 1
            GOTO 150
         ENDIF
         IUP(M) = IPT
         SUM = SUM + DATA1(IPT)
         SUMSQ = SUMSQ + DATA1(IPT)**2
         IPT = IPT + 1
         NTOTG = NTOTG + 1
      ENDDO
  250 CONTINUE
      INC = 1
      DO N = 1, 100
         IF ((N+INC).LE.100) THEN
            DO LL = 1, NLOCB
               IF (I100PT(N+INC).EQ.IDN(LL)) INC = INC + 1
            ENDDO
            IF ((N+INC).LE.100) THEN
               I100PT(N) = I100PT(N+INC)
            ELSE
               I100PT(N) = IUP(N+NLOCB-100+IINC)
            END IF
         ELSE
  175       I100PT(N) = IUP(N+NLOCB-100+IINC)
         ENDIF
      ENDDO
      AVE = SUM/100.0
      SUMDIFF = SUMSQ - SUM**2/100.0
      IF (SUMDIFF.GE.0.0) THEN
       SIG = DSQRT(SUMDIFF/100.0)  ! DBLE PREC
      ELSE
       SIG = 0.0D0
      END IF
C     SIG = DSQRT((SUMSQ - SUM**2/100.0)/100.0)
      GOTO 50   ! LOOP BACK TO THE TEST FOR THIS SET OF POINTS
  300 CONTINUE
C
C SET ALL POINTS TO FILL IF INSUFFICIENT INPUT ( < 100 NON-FILL POINTS)
C
      DO I = 1,NPTS
       DATA1(I) = BAD
      END DO
C
  200 CONTINUE
      IF (IPASS.EQ.1) NGD = NTOTG
      NBD = NBD + NTOTB
C
C END MULTI-PASS LOOP
C
      END DO
C
      NTOTG = NGD
      NTOTB = NBD
C
C  UPDATE THE HISTORY AND SAVE
C
      FRACT = REAL(NTOTB)/REAL(NTOTG)
C     WRITE(6,'(1X,,''FRACTION OF BAD PTS '',E10.4)') FRACT
C
      RETURN
      END
