      SUBROUTINE SNOALBA(ALVSSN,ALIRSN,ALVSSC,ALIRSC,ALBSNO,
     1                   TRSNOWC, ALSNO, TRSNOWG, FSDB, FSFB, RHOSNO,
     2                   REFSN,BCSN,SNO,CSZ,ZSNOW,FSNOW,ASVDAT,ASIDAT,
     3                   ALVSG, ALIRG,
     4                   ILG,IG,IL1,IL2,JL,IALS,NBS,ISNOALB) 
C
C     * FEB 09/15 - J.COLE.     New version for gcm18 and class 3.6:
C     *                         - BCSNO calculation only done if C_FLAG
C     *                           indicates it is relevant to do so.
C     * NOV 16/13 - J.COLE.     Final version for gcm17:
C     *                         - Fixes to get the proper BC mixing ratio in
C     *                           snow, which required passing in and using
C     *                           the snow density RHON.
C     * JUN 22/13 - J.COLE.     ADD CODE FOR "ISNOALB" OPTION,
C     *                         WHICH IS BASED ON 4-BAND SOLAR.
C     * FEB 05/07 - D.VERSEGHY. STREAMLINE CALCULATIONS OF
C     *                         ALVSSN AND ALIRSN.
C     * APR 13/06 - D.VERSEGHY. SEPARATE ALBEDOS FOR OPEN AND 
C     *                         CANOPY-COVERED SNOW.
C     * NOV 03/04 - D.VERSEGHY. ADD "IMPLICIT NONE" COMMAND.
C     * MAR 18/02 - D.VERSEGHY. UPDATES TO ALLOW ASSIGNMENT OF
C     *                         USER-SPECIFIED VALUES TO SNOW
C     *                         ALBEDO.
C     * JUN 05/97 - D.VERSEGHY. CLASS - VERSION 2.7.
C     *                         SPECIFY LOCATION OF ICE SHEETS
C     *                         BY SOIL TEXTURE ARRAY RATHER
C     *                         THAN BY SOIL COLOUR INDEX.
C     * NOV 29/94 - M.LAZARE.   CLASS - VERSION 2.3.
C     *                         CALL ABORT CHANGED TO CALL XIT TO 
C     *                         ENABLE RUNNING ON PC'S.
C     * MAR 13/92 - M.LAZARE.   CODE FOR MODEL VERSION GCM7 -
C     *                         DIVIDE PREVIOUS SUBROUTINE 
C     *                         "SNOALB" INTO "SNOALBA" AND
C     *                         "SNOALBW" AND VECTORIZE.
C     * AUG 12/91 - D.VERSEGHY. CODE FOR MODEL VERSION GCM7U -
C     *                         CLASS VERSION 2.0 (WITH CANOPY).
C     * APR 11/89 - D.VERSEGHY. DISAGGREGATE SNOW ALBEDO INTO
C     *                         VISIBLE AND NEAR-IR PORTIONS;
C     *                         CALCULATE TRANSMISSIVITY TO
C     *                         SHORTWAVE RADIATION.
C
      IMPLICIT NONE
C    
C     * INTEGER CONSTANTS.
C
      INTEGER ILG,IG,IL1,IL2,JL,IALS,IPTBAD,I,IB,NBS,ISNOALB
C
C     * OUTPUT ARRAYS.
C
      REAL   ALSNO(ILG,NBS), TRSNOWG(ILG,NBS)
      REAL   ALVSSN(ILG),  ALIRSN(ILG),  ALVSSC(ILG),  ALIRSC(ILG),
     1       ALVSG (ILG),  ALIRG (ILG),  TRSNOWC(ILG)
C
C     * INPUT ARRAYS.
C
      REAL   FSDB(ILG,NBS), FSFB(ILG,NBS)
      REAL   ALBSNO(ILG),  ZSNOW (ILG),  FSNOW (ILG),
     1       ASVDAT(ILG),  ASIDAT(ILG),  REFSN (ILG),  BCSN  (ILG),
     2       CSZ   (ILG),  SNO   (ILG),  RHOSNO(ILG)
C
C     * LOCAL ARRAYS
C
      REAL SALBG(ILG,NBS), ALDIR(ILG,NBS), ALDIF(ILG,NBS), 
     +                     TRDIR(ILG,NBS), TRDIF(ILG,NBS)
      REAL REFSNO(ILG), BCSNO(ILG)
      INTEGER C_FLAG(ILG)
C
C     * CONSTANTS.
C
      REAL WDIRCT, WDIFF
      INTEGER SUM_C_FLAG
C------------------------------------------------------------------
      IPTBAD=0
      DO 100 I=IL1,IL2                                           
         IF(ALBSNO(I).LT.0.50.AND.ALBSNO(I).GT.0.499) ALBSNO(I)=0.50                      
         IF(FSNOW(I).GT.0.0 .AND. IALS.EQ.0)              THEN  
             IF(ALBSNO(I).GT.0.70)                    THEN
                 ALVSSN(I)=0.7857*ALBSNO(I)+0.2900                                                                                                                       
                 ALIRSN(I)=1.2142*ALBSNO(I)-0.2900                                                                                                                       
             ELSE
                 ALVSSN(I)=0.9706*ALBSNO(I)+0.1347                                                                                                                   
                 ALIRSN(I)=1.0294*ALBSNO(I)-0.1347                                                                                                                       
             ENDIF
             IF(ALVSSN(I).GT.0.999.OR.ALVSSN(I).LT.0.001) IPTBAD=I
             IF(ALIRSN(I).GT.0.999.OR.ALIRSN(I).LT.0.001) IPTBAD=I
         ELSE IF(FSNOW(I).GT.0.0 .AND. IALS.EQ.1)         THEN  
             ALVSSN(I)=ASVDAT(I)
             ALIRSN(I)=ASIDAT(I)
         ENDIF                                                                   
         ALVSSC(I)=ALVSSN(I)
         ALIRSC(I)=ALIRSN(I)
         TRSNOWC(I)=EXP(-25.0*ZSNOW(I)) 
  100 CONTINUE
C
      IF(IPTBAD.NE.0) THEN
         WRITE(6,6100) IPTBAD,JL,ALVSSN(IPTBAD),ALIRSN(IPTBAD)
 6100    FORMAT('0AT (I,J)= (',I3,',',I3,'), ALVSSN,ALIRSN = ',2F10.5)
         CALL XIT('SNOALBA',-1)
      ENDIF
C
      IF (ISNOALB .EQ. 0) THEN
         DO I = IL1, IL2
            ALSNO(I,1) = ALVSSN(I)
            ALSNO(I,2) = ALIRSN(I)
            ALSNO(I,3) = ALIRSN(I)
            ALSNO(I,4) = ALIRSN(I)

            TRSNOWG(I,1:NBS) = TRSNOWC(I)
         END DO ! I
      ELSE IF (ISNOALB .EQ. 1) THEN
         DO IB = 1, NBS
            DO I = IL1, IL2
               IF (IB .EQ. 1) THEN
                  SALBG(I,IB) = ALVSG(I)
                  ALSNO(I,IB) = ALVSSN(I)
               ELSE
                  SALBG(I,IB) = ALIRG(I)
                  ALSNO(I,IB) = ALIRSN(I)
               END IF
            END DO ! I
         END DO ! IB
         SUM_C_FLAG = 0
         DO I = IL1, IL2
            IF (ZSNOW(I) .GT. 0.0) THEN
               C_FLAG(I) = 1
            ELSE
               C_FLAG(I) = 0
            END IF
            SUM_C_FLAG = SUM_C_FLAG + C_FLAG(I)
         END DO ! I

         IF (IALS .EQ. 0) THEN
            IF (SUM_C_FLAG .GT. 0) THEN
! Convert the units of the snow grain size and BC mixing ratio
! Snow grain size from meters to microns and BC from kg BC/m^3 to ng BC/kg SNOW
               DO I = IL1,IL2
                 IF (C_FLAG(I) .EQ. 1) THEN
                  REFSNO(I) = REFSN(I)*1.0E6
                  BCSNO(I)  = (BCSN(I)/RHOSNO(I))*1.0E12
                 END IF
               END DO ! I 

               CALL SNOW_ALBVAL(ALDIF, ! OUTPUT
     +                          ALDIR,
     +                          CSZ,   ! INPUT
     +                          SALBG,
     +                          BCSNO,
     +                          REFSNO,
     +                          SNO,
     +                          C_FLAG,
     +                          IL1,
     +                          IL2,
     +                          ILG,
     +                          NBS)

               CALL SNOW_TRANVAL(TRDIF, ! OUTPUT
     +                           TRDIR,
     +                           CSZ,   ! INPUT
     +                           SALBG,
     +                           BCSNO,
     +                           REFSNO,
     +                           SNO,
     +                           C_FLAG,
     +                           IL1,
     +                           IL2,
     +                           ILG,
     +                           NBS)

               DO IB = 1, NBS
                  DO I = IL1, IL2
                     IF (C_FLAG(I) .EQ. 1) THEN
                        WDIRCT = FSDB(I,IB)
     +                         /(FSDB(I,IB)+FSFB(I,IB)+1.E-10)
                        WDIFF  = 1.0-WDIRCT
                        ALSNO(I,IB) = ALDIF(I,IB)*WDIFF 
     +                              + ALDIR(I,IB)*WDIRCT
                        TRSNOWG(I,IB) = TRDIF(I,IB)*WDIFF 
     +                                + TRDIR(I,IB)*WDIRCT
                     END IF ! C_FLAG
                  END DO ! I
               END DO ! IB
            ELSE ! SUM_C_FLAG .EQ. 0
               DO I = IL1, IL2
                  ALSNO(I,1)     = ALVSSN(I)
                  ALSNO(I,2:NBS) = ALIRSN(I)
                  TRSNOWG(I,1:NBS) = TRSNOWC(I)
               END DO ! I
            ENDIF ! SUM_C_FLAG
         ELSE IF (IALS .EQ. 1) THEN
            DO I = IL1, IL2
               ALSNO(I,1) = ASVDAT(I)
               ALSNO(I,2) = ASIDAT(I)
               ALSNO(I,3) = ASIDAT(I)
               ALSNO(I,4) = ASIDAT(I)

               TRSNOWG(I,1:NBS) = TRSNOWC(I)
            END DO ! I
         END IF ! IALS
      END IF ! ISNOALB

      RETURN
      END
