      PROGRAM ENSAVG                                                                                                                
C     PROGRAM ENSAVG (MERG,       AVG,        OUTPUT,                   )       C2                                                  
C    1          TAPE1=MERG, TAPE2=AVG, TAPE6,=OUTPUT)                                                                               
C     -----------------------------------------------                           C2                                                  
C                                                                               C2                                                  
C     JUL 03/03 - A.IRWIN,F.MAJAESS (REVISED FOR F90 AND LINUX PLATFORMS)       C2                                                  
C     JUN 16/93 - S.PIGGOTT                                                                                                         
C                                                                               C2                                                  
CENSAVG  - CALCULATES ENSEMBLE AVERAGES FROM THE MERGED OUTPUT FILE             C1                                                  
C          OF PROGRAM ENSMERG                                           1  1    C1                                                  
C                                                                               C3                                                  
CAUTHOR  - S.PIGGOTT                                                            C3                                                  
C                                                                               C3                                                  
CPURPOSE - CALCULATES ENSEMBLE AVERAGES OVER AN ARBITRARY NUMBER OF             C3                                                  
C          IDENTICALLY SIZED AND STRUCTURED ORIGINAL FILES AFTER THE FILES      C3                                                  
C          HAVE BEEN MERGED INTO ONE FILE BY THE ENSMERG PROGRAM.               C3                                                  
C                                                                               C3                                                  
C          THE MERGED INPUT FILE CONTAINS A SERIES OF TIME LEVELS TAKEN         C3                                                  
C          ACROSS THE ORIGINAL FILES. ONE TIME LEVEL CONTAINS A GROUP OF        C3                                                  
C          IDENTICALLY STRUCTURED SINGLE/MULTI-LEVEL SETS THAT OCCUPY THE       C3                                                  
C          SAME POSITION IN EACH ORIGINAL FILE.                                 C3                                                  
C                                                                               C3                                                  
C          EACH TIME LEVEL IS ENSEMBLE AVERAGED TO GIVE ONE SET THAT CONTAINS   C3                                                  
C          THE AVERAGE OVER ALL THE SETS OF THAT TIME LEVEL.                    C3                                                  
C                                                                               C3                                                  
CINPUT FILES...                                                                 C3                                                  
C                                                                               C3                                                  
C   MERG = MERGED FILE CONTAINING TIME LEVELS TAKEN ACROSS SEVERAL ORIGINAL     C3                                                  
C          FILES TO BE ENSEMBLE AVERAGED (OUTPUT FILE FROM ENSMERG PROGRAM)     C3                                                  
C                                                                               C3                                                  
COUTPUT FILE...                                                                 C3                                                  
C                                                                               C3                                                  
C    AVG = A SERIES OF SINGLE/MULTI-LEVEL ENSEMBLE AVERAGED SETS.               C3                                                  
C          EACH SET IS THE AVERAGE OVER ALL THE SETS IN A PARTICULAR TIME       C3                                                  
C          LEVEL OF MERG.                                                       C3                                                  
C                                                                               C3                                                  
C          NOTE: IBUF(2) IS ASSIGNED A POSITIVE 9-DIGIT LABEL:                  C3                                                  
C                                                                               C3                                                  
C                TTT000NNN                                                      C3                                                  
C                                                                               C3                                                  
C                TTT = THE TIME LEVEL NUMBER                                    C3                                                  
C                000 = THREE ZEROS (THIS PART OF IBUF(2) CONTAINS NO            C3                                                  
C                      INFORMATION BUT PRESERVES A FORM SIMILAR TO THE IBUF(2)  C3                                                  
C                      OF THE MERGED FILE. (SEE THE ENSMERG PROGRAM)            C3                                                  
C                NNN = THE NUMBER OF ORIGINAL FILES THAT ARE ENSEMBLE AVERAGED  C3                                                  
C-------------------------------------------------------------------------------                                                    
C                                                                                                                                   
      IMPLICIT REAL (A-H,O-Z),                                                                                                      
     +INTEGER (I-N)                                                                                                                 
      INTEGER TIME,BASE,TTT                                                                                                         
      INTEGER IBOUT(800)                                                                                                            
      LOGICAL OK,SPEC,DUN                                                                                                           
C                                                                                                                                   
      COMMON/ICOM/IBUF(8),IDAT(65341)                                                                                               
      COMMON/JCOM/JBUF(8),JDAT(65341)                                                                                               
      COMMON/BLANCK/A(65341),G(6534100)                                                                                             
C                                                                                                                                   
      DATA MAXX/65341/                                                                                                              
      DATA MAXLBIJ/6534100/,MAX8L/800/                                                                                              
                                                                                                                                    
C-------------------------------------------------------------------------------                                                    
      NF=3                                                                                                                          
      CALL JCLPNT(NF,1,2,6)                                                                                                         
      REWIND 1                                                                                                                      
      REWIND 2                                                                                                                      
C                                                                                                                                   
C     * NRIN  = THE NUMBER OF RECORDS READ FROM THE INPUT FILE.                                                                     
C     * NTIM  = THE TIME LEVEL NUMBER                                                                                               
C     * NROUT = THE NUMBER OF RECORDS SENT TO THE OUTPUT FILE.                                                                      
C     * NSTLV = THE NUMBER OF SETS PROCESSED FROM THE CURRENT TIME LEVEL                                                            
C     *         OF THE INPUT FILE.                                                                                                  
C     * NRTLV = THE NUMBER OF RECORDS READ FROM THE CURRENT TIME LEVEL                                                              
C     *         OF THE INPUT FILE.                                                                                                  
C     * NRSET = THE NUMBER OF RECORDS READ FROM THE CURRENT SET OF THE                                                              
C     *         INPUT FILE.                                                                                                         
C                                                                                                                                   
      NRIN=0                                                                                                                        
      NTIM=0                                                                                                                        
      NROUT=0                                                                                                                       
      NSTLV=0                                                                                                                       
      NRTLV=0                                                                                                                       
      NRSET=0                                                                                                                       
C                                                                                                                                   
C                                                                                                                                   
      DUN=.FALSE.                                                                                                                   
      MAXLEN=MAXX+8                                                                                                                 
C-------------------------------------------------------------------------------                                                    
C                                                                                                                                   
C     * GET THE 8 WORD LABEL FROM THE FIRST RECORD OF THE INPUT FILE.                                                               
C     * GET THE NUMBER OF ORIGINAL FILES MERGED FROM THE LAST 3 DIGITS                                                              
C     * OF IBUF(2). (SEE THE ENSMERG PROGRAM FOR AN EXPLANATION OF THE                                                              
C     * IBUF(2) OF THE MERGED FILE)                                                                                                 
C                                                                                                                                   
      CALL FBUFFIN(-1,IBUF,-8,K,LEN)                                                                                                
      IF(K.GE.0) CALL                              XIT(' ENSAVG',-1)                                                                
      LAB2=IABS(IBUF(2))                                                                                                            
      NNN=MOD(LAB2,1000)                                                                                                            
C                                                                                                                                   
C     * INITIALIZE VARIABLES TTT AND TIME.                                                                                          
C     * THESE VARIABLES ARE USED LATER IN THE PROGRAM TO LOCATE THE                                                                 
C     * BEGINNING OF SETS AND TIME LEVELS IN THE INPUT FILE.                                                                        
C                                                                                                                                   
      TTT=IBUF(2)/1000000                                                                                                           
      TIME=IBUF(2)                                                                                                                  
C                                                                                                                                   
C     * WRITE OUT THE FIRST 8-WORD LABEL OF THE INPUT FILE AND SET                                                                  
C     * THE VALUE OF NWDS.                                                                                                          
C                                                                                                                                   
      WRITE(6,6010)                                                                                                                 
      CALL PRTLAB(IBUF)                                                                                                             
      NWDS=IBUF(5)*IBUF(6)                                                                                                          
      KIND=IBUF(1)                                                                                                                  
      SPEC=(KIND.EQ.NC4TO8("FOUR").OR.KIND.EQ.NC4TO8("SPEC"))                                                                       
      IF(SPEC) NWDS=NWDS*2                                                                                                          
C                                                                                                                                   
      REWIND 1                                                                                                                      
                                                                                                                                    
C-------------------------------------------------------------------------------                                                    
C                                                                                                                                   
C     * DURING ONE PASS OF THE FOLLOWING LOOP A COMPLETE TIME LEVEL OF                                                              
C     * SINGLE/MULTI-LEVEL SETS IS READ FROM THE INPUT FILE, AVERAGED                                                               
C     * OVER THE SETS TO PRODUCE ONE SET OF ENSEMBLE AVERAGED DATA,                                                                 
C     * AND SENT TO THE OUTPUT FILE.                                                                                                
C     * THIS IS DONE ONCE FOR EVERY TIME LEVEL IN THE INPUT FILE.                                                                   
C                                                                                                                                   
  100 CONTINUE                                                                                                                      
C                                                                                                                                   
C     * INITIALIZE COUNTERS AT THE BEGINNING OF EACH PASS.                                                                          
C                                                                                                                                   
      NSTLV=0                                                                                                                       
      NRTLV=0                                                                                                                       
      NRSET=0                                                                                                                       
C                                                                                                                                   
C     * DURING THE FIRST PASS OF THE FOLLOWING LOOP THE FIRST FIELD                                                                 
C     * IS READ FROM THE INPUT FILE AND ASSIGNED TO THE FIRST 'NWDS'                                                                
C     * ELEMENTS OF LINEAR ARRAY G. DURING THE NEXT PASS OF THE LOOP THE                                                            
C     * NEXT FIELD IS READ AND ASSIGNED TO THE NEXT NWDS ELEMENTS OF G.                                                             
C     * THIS IS REPEATED UNTIL G HOLDS THE FIRST SINGLE/MULTI-LEVEL SET OF                                                          
C     * THE FIRST TIME LEVEL FROM THE INPUT FILE. THE REST OF THE SETS IN                                                           
C     * THAT TIME LEVEL ARE PROCESSED IN A SIMILAR MANNER EXCEPT THAT THEY ARE                                                      
C     * ADDED TO ARRAY G. AFTER THE WHOLE TIME LEVEL OF SETS IS READ G WILL                                                         
C     * CONTAIN ONE SET THAT IS THE SUM OVER ALL THE SETS IN THAT TIME LEVEL.                                                       
C     * AT THAT POINT ARRAY G CAN BE DIVIDED BY THE NUMBER OF SETS IN THE                                                           
C     * TIME LEVEL TO OBTAIN THE ENSEMBLE AVERAGED SET.                                                                             
C                                                                                                                                   
  200 CALL GETFLD2(1,A,-1,-1,-1,-1,IBUF,MAXX,OK)                                                                                    
C                                                                                                                                   
C     * IF THE END OF THE FILE IS ENCOUNTERED SET LOGICAL VARIABLE DUN                                                              
C     * TO TRUE AND GOTO 500 TO CALCULATE THE FINAL ENSEMBLE AVERAGES.                                                              
C     * AFTER THEY ARE CALCULATED AND OUTPUTTED VARIABLE DUN WILL SIGNAL                                                            
C     * THE PROGRAM TO STOP.                                                                                                        
C                                                                                                                                   
      IF(.NOT.OK) THEN                                                                                                              
        IF(NRIN.EQ.0) CALL                         XIT(' ENSAVG',-2)                                                                
        DUN=.TRUE.                                                                                                                  
        GOTO 500                                                                                                                    
      ENDIF                                                                                                                         
C                                                                                                                                   
C     * IF THE END OF A TIME LEVEL OF SETS IN THE MERGED INPUT FILE IS                                                              
C     * ENCOUNTERED THEN GOTO 500 TO CALCULATE THE ENSEMBLE AVERAGES FOR                                                            
C     * THAT TIME LEVEL. THIS OCCURS WHEN THE TIME LEVEL PART OF IBUF(2)                                                            
C     * INCREMENTS FROM ONE RECORD TO THE NEXT. (SEE THE ENSMERG PROGRAM                                                            
C     * FOR AN EXPLANATION OF THE IBUF(2) OF THE MERGED INPUT FILE.)                                                                
C                                                                                                                                   
      J=IBUF(2)/1000000                                                                                                             
      IF(J.NE.TTT) THEN                                                                                                             
        TTT=J                                                                                                                       
        TIME=IBUF(2)                                                                                                                
        BACKSPACE 1                                                                                                                 
        BACKSPACE 1                                                                                                                 
        GOTO 500                                                                                                                    
      ENDIF                                                                                                                         
C                                                                                                                                   
C     * IF NEITHER OF THE ABOVE CONDITIONS ARE MET THEN THE CURRENT                                                                 
C     * FIELD IN ARRAY A WILL BE ADDED TO ARRAY G.                                                                                  
C     * THEREFORE INCREMENT THE FOLLOWING COUNTERS.                                                                                 
C                                                                                                                                   
      NRSET=NRSET+1                                                                                                                 
      NRTLV=NRTLV+1                                                                                                                 
      NRIN=NRIN+1                                                                                                                   
C                                                                                                                                   
C     * DETERMINE IF A NEW SET WITHIN THE SAME TIME LEVEL HAS BEEN REACHED                                                          
C     * IN THE INPUT FILE. THIS OCCURS WHEN THE ORIGINAL FILE PART OF                                                               
C     * IBUF(2), FFF, OF THE MERGED INPUT FILE INCREMENTS FROM ONE RECORD TO                                                        
C     * THE NEXT. TO DETECT THIS ALL WE NEED DO IS LOOK FOR A CHANGE IN                                                             
C     * IBUF(2), SINCE THE NNN PART IS FIXED AND THE TTT PART HAS ALREADY                                                           
C     * BEEN TESTED FOR A CHANGE.(SEE THE ENSMERG PROGRAM FOR AN EXPLANATION                                                        
C     * OF THE IBUF(2) OF THE MERGED INPUT FILE)                                                                                    
C     * IF A NEW SET IS DETECTED, PUT NRSET BACK TO 1 AND INCREMENT                                                                 
C     * NSTLV BY 1.                                                                                                                 
C                                                                                                                                   
      IF(IBUF(2).NE.TIME) THEN                                                                                                      
        TIME=IBUF(2)                                                                                                                
        NRSET=1                                                                                                                     
        NSTLV=NSTLV+1                                                                                                               
      ENDIF                                                                                                                         
C                                                                                                                                   
C     * IF ARRAY A CONTAINS A FIELD FROM THE FIRST SET OF THE                                                                       
C     * CURRENT TIME LEVEL THEN ASSIGN THIS FIELD TO ARRAY G. OTHERWISE                                                             
C     * ADD THE FIELD TO G. (THIS AVOIDS THE NEED FOR INITIALIZING G TO                                                             
C     * 0 BEFORE EACH TIME LEVEL OF SINGLE/MULTI-LEVEL SETS IS ADDED TO IT.)                                                        
C     * WHEN A COMPLETE TIME LEVEL OF SETS HAS BEEN READ, ARRAY G WILL                                                              
C     * CONTAIN ONE SINGLE/MULTI-LEVEL SET THAT IS THE SUM OF ALL THE                                                               
C     * SETS IN THAT TIME LEVEL.                                                                                                    
C                                                                                                                                   
      IF( NRSET*NWDS .GT. MAXLBIJ ) THEN                                                                                            
        WRITE(6,6070)                                                                                                               
        CALL                                       XIT(' ENSAVG',-3)                                                                
      ENDIF                                                                                                                         
      DO 300 J=1,NWDS                                                                                                               
        K=(NRSET-1)*NWDS+J                                                                                                          
        IF(NSTLV.EQ.0) THEN                                                                                                         
          G(K)=A(J)                                                                                                                 
        ELSE                                                                                                                        
          G(K)=G(K)+A(J)                                                                                                            
        ENDIF                                                                                                                       
  300 CONTINUE                                                                                                                      
C                                                                                                                                   
C     PUT THE 8-WORD LABELS IN IBOUT FOR USE IN THE OUTPUT FILE.                                                                    
C                                                                                                                                   
      IF(NSTLV.EQ.0) THEN                                                                                                           
        IF( NRSET*8 .GT. MAX8L ) THEN                                                                                               
          WRITE(6,6070)                                                                                                             
          CALL                                     XIT(' ENSAVG',-4)                                                                
        ENDIF                                                                                                                       
        DO 400 J=1,8                                                                                                                
          K=(NRSET-1)*8+J                                                                                                           
          IBOUT(K)=IBUF(J)                                                                                                          
  400   CONTINUE                                                                                                                    
      ENDIF                                                                                                                         
C                                                                                                                                   
C     * GO BACK TO 200 TO GET THE NEXT RECORD FROM THE INPUT FILE.                                                                  
C                                                                                                                                   
      GOTO 200                                                                                                                      
C-------------------------------------------------------------------------------                                                    
C                                                                                                                                   
C     * CALCULATE THE ENSEMBLE AVERAGES FOR THE CURRENT TIME LEVEL BY DIVIDING                                                      
C     * ARRAY G BY THE TOTAL NUMBER OF SETS IN THE TIME LEVEL (NNN).                                                                
C                                                                                                                                   
  500 FNI=1.E0/FLOAT(NNN)                                                                                                           
      NTIM=NTIM+1                                                                                                                   
      K=NRSET*NWDS                                                                                                                  
      DO 600 J=1,K                                                                                                                  
        G(J)=G(J)*FNI                                                                                                               
  600 CONTINUE                                                                                                                      
C                                                                                                                                   
C     * PUT THE ENSEMBLE AVERAGED SET FROM G TO OUTPUT WITH THE 8 WORD LABELS                                                       
C     * SAVED IN IBOUT. JBUF(2) IS ASSIGNED A LABEL THAT INDICATES THE                                                              
C     * TIME LEVEL NUMBER (NTIM) OF THE ENSEMBLE AVERAGED SETS IN THE OUTPUT                                                        
C     * FILE AND THE TOTAL NUMBER OF ORIGINAL FILES THAT ARE ENSEMBLE                                                               
C     * AVERAGED (NNN).                                                                                                             
C                                                                                                                                   
      DO 700 L=1,NRSET                                                                                                              
        DO 800 M=1,8                                                                                                                
          JBUF(M)=IBOUT((L-1)*8+M)                                                                                                  
  800   CONTINUE                                                                                                                    
        JBUF(2)=NTIM*1000000+NNN                                                                                                    
        BASE=(L-1)*NWDS+1                                                                                                           
        CALL PUTFLD2(2,G(BASE),JBUF,MAXX)                                                                                           
        NROUT=NROUT+1                                                                                                               
  700 CONTINUE                                                                                                                      
C                                                                                                                                   
C     * IF THE FLAG DUN IS TRUE THEN WRITE PROGRAM STATISTICS TO                                                                    
C     * OUTPUT AND EXIT.                                                                                                            
C                                                                                                                                   
      IF(DUN) THEN                                                                                                                  
        WRITE(6,6020) NTIM,NNN                                                                                                      
        WRITE(6,6040) NTIM                                                                                                          
        WRITE(6,6050) NRIN                                                                                                          
        WRITE(6,6060) NROUT                                                                                                         
        CALL                                       XIT(' ENSAVG',0)                                                                 
      ENDIF                                                                                                                         
C                                                                                                                                   
C     * GO BACK TO 100 TO START PROCESSING THE NEXT TIME LEVEL FROM THE                                                             
C     * INPUT FILE.                                                                                                                 
C                                                                                                                                   
      GOTO 100                                                                                                                      
C-------------------------------------------------------------------------------                                                    
 6010 FORMAT('0  FIRST RECORD OF THE INPUT FILE:')                                                                                  
 6020 FORMAT('0  THE INPUT FILE CONTAINS ',I6,' TIME LEVELS FROM ',                                                                 
     1       I6,' ORIGINAL FILES.'/                                                                                                 
     2       '   ENSEMBLE AVERAGING IS DONE FOR EACH TIME LEVEL.')                                                                  
 6040 FORMAT('0  THE OUTPUT FILE CONTAINS ',I6,                                                                                     
     1       ' SINGLE/MULTI-LEVEL ENSEMBLE AVERAGED SETS.')                                                                         
 6050 FORMAT('0',I7,' RECORDS READ FROM THE INPUT FILE.')                                                                           
 6060 FORMAT('0',I7,' RECORDS SENT TO THE OUTPUT FILE.')                                                                            
 6070 FORMAT('0 INSUFFICIENT ARRAY SIZE.')                                                                                          
      END                                                                                                                           
