! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE CLOUD_CV ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! ! SUBROUTINE cloud_cv (nx,ny,nz,i4time,time,dirname,runname, & 1,24 xs,ys,zs,dx,dy,topo,latgr,longr, & p_3d,t_3d,rh_3d, & nobsng,stn,obstype,xsng,ysng, & obstime,latsta,lonsta,elevsta, & kcloud,store_amt,store_hgt, & ref_mos_3d,istat_radar, & clouds_3d,cloud_ceiling, & istatus) ! !----------------------------------------------------------------------- ! ! PURPOSE: ! ! Perform 3D fractional cloud cover analysis using SAO ! cloud coverage observations, visible (VIS) and infrared (IR) ! satellite measurements, and radar reflectivity data. ! !----------------------------------------------------------------------- ! ! AUTHOR: (Jian Zhang) ! 02/01/96 ! ! MODIFICATION HISTORY: ! ! 07/12/96 J. Zhang ! Added remapping of the cloud cover fields onto the ! ARPS grid. ! 03/14/97 J. Zhang ! Cleaning up the code and implemented for the official ! arps4.2.4 version. ! 03/28/97 J. Zhang ! Using the lifiting condensation level as the cloud ! base when inserting radar reflectivity with no SAO ! cloud base. ! 04/11/97 J. Zhang ! Included dims.inc for nx,ny,nz. ! 04/15/97 J. Zhang ! Change the size of the arrays istn, jstn, hstn, and ! cstn from fixed (40) to adjustable (mx_sng) ! 08/06/97 J. Zhang ! Change adascld24.inc to adascld25.inc ! 09/04/97 J. Zhang ! Changed the radar echo thresholds for inserting clouds ! from radar reflectivities. ! 09/10/97 J. Zhang ! Calculate lifting condensation level in INICLDGRD, ! and used by other routines (INSERTIR and INSERTRAD). ! Change adascld25.inc to adascld26.inc ! 11/17/97 J. Zhang ! Change the length of "runname" from fixed number ! of letters (6) to flexible numbers. ! 11/18/97 J. Zhang ! Added flag 'clddiag' in adascld26.inc for whether to ! output the special cloud fields. ! 03/26/98 J. Zhang ! Some modifications based on the official adas 4.3.3. ! 04/27/98 J. Zhang ! Conform WRTCLDVAR to WRTVAR ! 05/05/98 J. Zhang ! Abandoned the cloud grid, using the ARPS grid instead. ! 10/25/98 K. Brewster ! Modified creation of file name for cloud observation ! diagnostic file. ! 08/21/01 K. Brewster ! Changed wrtvar calls to wrtvar1 to match new routine ! for writing 3-D arrays to be read by arpsplt as an ! arbitary array. ! !----------------------------------------------------------------------- ! ! INCLUDE: (from adas.inc) ! ! mx_sng ! max. possible # of surface obs. ! max_cld_snd ! max. possible # of stations ! with cloud coverage reports. ! refthr1 ! "significant" radar echo at lower levels ! refthr2 ! "significant" radar echo at upper levels ! hgtrefthr ! height criteria for "significant" radar ! echo thresholds ! clddiag ! flag for whether to output the special cloud ! fields ! ! INPUT: ! ! nx,ny,nz ! ARPS grid size ! ! i4time ! analysis time in seconds from 00:00 UTC ! Jan. 1, 1960 ! time ! analysis time in seconds from the model ! initial time ! dirname ! directory for data dump ! ! INPUT (for ARPS grid variables) ! xs (nx) ! The x-coord. of the physical and ! computational grid. Defined at p-point. ! ys (ny) ! The y-coord. of the physical and ! computational grid. Defined at p-point. ! zs (nx,ny,nz) ! The physical height coordinate defined at ! p-point of the staggered grid. ! temp_3d(nx,ny,nz)! the temperature field ! ! topo (nx,ny) ! The height of the terrain (equivalent ! dx, dy ! grid spacing ! ! INPUT for SAO obs. ! ! stn (mx_sng) ! station name of single-lvel data ! obstype (mx_sng) ! names of sfc sources ! obstime (mx_sng) ! time for the observation. ! latsta (mx_sng) ! latitude of single-level data ! lonsta (mx_sng) ! longitude of single-level data ! elevsta (mx_sng) ! height of single-level data ! xsng (mx_sng) ! x location of single-level data ! ysng (mx_sng) ! y location of single-level data ! ! kcloud (mx_sng) ! number of obs. cloud layers. ! store_amt (mx_sng,5) ! cloud coverage (ea. layer, ! ea. station). ! store_hgt (mx_sng,5) ! height of obs. cloud layers. ! ! LOCAL ! ! cf_modelfg (nx,ny,nz) ! first guess cloud cover field ! rh_modelfg (nx,ny,nz) ! first guess relative humidity field ! t_sfc_k (nx,ny) ! surface temperature field ! ! OUTPUT: ! ! istatus ! The flag indicating process status. ! clouds_3d (nx,ny,nz) ! final gridded cloud cover analysis ! cloud_ceiling (nx,ny) ! cloud ceiling (M AGL) ! ! LOCAL: ! n_cld_snd number of cloud soundings created ! cld_snd (max_cld_snd,nz) Cld snding obtained from SAO data. ! wt_snd (max_cld_snd,nz) weights assigned to cloud sounding ! obtained from SAO data. ! cvr_max (nx,ny) ! final column maximum cloud cover ! cvr_tot (nx,ny) ! final column total cloud cover ! cloud_top (nx,ny) ! cloud top (M ASL) ! ! LOCAL for SAO: ! ! ista_snd (max_cld_snd) index of cloud sounding stations ! i_snd (max_cld_snd) i-locn of each cld snd stn in ADAS grid ! j_snd (max_cld_snd) j-locn of each cld snd stn in ADAS grid ! ! ! LOCAL for gridded cloud cover analysis ! ! cldcv (nx,ny,nz) 3D gridded fractional cloud cover analysis. ! (when input, it's the first guess field) ! wtcldcv (nx,ny,nz) wts given to gridded fracn cld cvr anx. ! !----------------------------------------------------------------------- ! ! Variable Declarations. ! !----------------------------------------------------------------------- ! IMPLICIT NONE ! !----------------------------------------------------------------------- ! !----------------------------------------------------------------------- ! ! Include files: ! INCLUDE 'adas.inc' ! ADAS parameters. ! !----------------------------------------------------------------------- ! ! INPUT: general INTEGER :: nx,ny,nz ! ARPS grid size INTEGER :: i4time ! analysis time in seconds from ! 00:00 UTC Jan. 1, 1960 REAL :: time ! analysis time in seconds from the ! model initiali time CHARACTER (LEN=*) :: dirname ! directory for data dump CHARACTER (LEN=*) :: runname ! a string identify the run ! ! INPUT: model grid ! REAL :: dx,dy ! ADAS grid spacing REAL :: xs (nx) ! The x-coord. of the physical and ! computational grid. Defined at p-point. REAL :: ys (ny) ! The y-coord. of the physical and ! computational grid. Defined at p-point. REAL :: zs (nx,ny,nz) ! The physical height coordinate defined at ! p-point of the staggered grid. REAL :: t_3d(nx,ny,nz) ! temperature (K) REAL :: p_3d(nx,ny,nz) REAL :: rh_3d(nx,ny,nz) REAL :: topo (nx,ny) ! The height of the terrain (equivalent ! ! INPUT for SAO obs. ! INTEGER :: nobsng CHARACTER (LEN=5) :: stn (mx_sng) ! station name of single-lvel data CHARACTER (LEN=8) :: obstype (mx_sng)! names of sfc sources INTEGER :: obstime (mx_sng) ! time for the observation. REAL :: xsng (mx_sng) ! x location of single-level data REAL :: ysng (mx_sng) ! y location of single-level data REAL :: latsta (mx_sng) ! latitude of single-level data REAL :: lonsta (mx_sng) ! longitude of single-level data REAL :: elevsta (mx_sng) ! height of single-level data ! INTEGER :: kcloud (mx_sng) ! number of cloud layers. CHARACTER (LEN=4) :: store_amt (mx_sng,5) ! cld coverage (ea.lyr, ea. stn). REAL :: store_hgt (mx_sng,5) ! height of cloud layers. ! ! INPUT: for radar INTEGER :: istat_radar ! Valid radar reflectivity data? REAL :: ref_mos_3d(nx,ny,nz) ! 3D radar reflectivity on model grid ! may be modified by sate VIS data ! ! OUTPUT: INTEGER :: istatus ! Flag for process status REAL :: clouds_3d(nx,ny,nz) ! Final cloud cover field REAL :: cloud_ceiling (nx,ny) ! cloud ceiling (M AGL) ! ! LOCAL: for first guess fields REAL :: cf_modelfg (nx,ny,nz) ! first guess cloud cover field REAL :: rh_modelfg (nx,ny,nz) ! first guess relative humidity fld REAL :: z_lcl (nx,ny) ! lifting condensation level(MSL) ! ! LOCAL: for surface arrays REAL :: latgr (nx,ny) ! latitude at each grid point REAL :: longr (nx,ny) ! longitude at each grid point REAL :: pres_sfc_pa(nx,ny) ! sfc pressure (Pascal) REAL :: t_gnd_k(nx,ny) ! ground skin temp. REAL :: t_sfc_k (nx,ny) ! surface temperature field REAL :: cvr_snow (nx,ny) ! surface snow coverage REAL :: rland_frac (nx,ny) ! land coverage fraction ! ! LOCAL: for SAO cloud sounding INTEGER :: ista_snd (max_cld_snd) ! seq. index of cld snd stn INTEGER :: i_snd (max_cld_snd) ! i-loctn of cld snd INTEGER :: j_snd (max_cld_snd) ! j-loctn of cld snd INTEGER :: n_cld_snd ! # of cloud snds created REAL :: cld_snd (max_cld_snd,nz) ! SAO cld snd REAL :: wt_snd (max_cld_snd,nz) ! wgt for SAO cld snd ! ! LOCAL for gridded cloud cover analysis REAL :: cldcv (nx,ny,nz) ! 3D gridded frac cld cv analysis. ! (it's also bkgrnd field when input) REAL :: wtcldcv (nx,ny,nz) ! wts assgned to cld cvr analysis ! (it's also bkgrnd field when input) ! LOCAL: for solar positions REAL :: solar_alt(nx,ny) ! solar altitude angle REAL :: solar_ha(nx,ny) ! solar hour angle REAL :: solar_dec ! solar declination angle ! ! LOCAL: for satellite insertion INTEGER :: io_vis ! Valid satellite VIS albedo data? REAL :: albedo(nx,ny) ! vis. albedo derived from sat.vis.data REAL :: cloud_frac_vis_a(nx,ny)! cldcvr derived from vis. albedo INTEGER :: istat_vis ! status of inserting VIS data INTEGER :: io_ir ! Valid satellite bright. temp. data? REAL :: tb8_k(nx,ny) ! Obs. sate. band8 bright. temp. REAL :: tb8_cold_k(nx,ny) ! Cold filtered band8 bright. temp. REAL :: cldtop_m_tb8(nx,ny) ! Sat. cld top ht (m) from band 8 data REAL :: cldtop_m (nx,ny) ! cldtop height REAL :: cloud_top (nx,ny) ! cloud top (M ASL) INTEGER :: istatus_ir ! status of inserting IR data ! REAL :: sfc_sao_buffer ! No clearing cloud by sat. below ! this ht.(m AGL) (hence letting ! SAOs dominate) PARAMETER (sfc_sao_buffer = 800.) ! meters, keep lower SAO cld from ! cleared out by sate. ir data ! ! LOCAL: for radar data insertion REAL :: dbz_max_2d(nx,ny) ! column max. radar refl. (dbZ) REAL :: cloud_base (nx,ny) ! cloud base heights from SAO+sate REAL :: cloud_base_buf(nx,ny) ! lowest cloud base heights within ! a searching radius LOGICAL :: l_unresolved(nx,ny) ! no SAO+sate cld, yet radar echo is ! above the threshold REAL :: vis_rad_thdbz PARAMETER (vis_rad_thdbz=10.)! threshold define cloudy refl. REAL :: vis_rad_thcvr PARAMETER (vis_rad_thcvr=0.2)! VIS cld cvr threshold, ! below this thresh. may cause ! radar echo being cleared out. ! ! LOCAL: intermidiate products REAL :: cvr_max (nx,ny) ! column maximum cloud cover REAL :: cvr_tot (nx,ny) ! final column total cloud cover REAL :: cvr_1d (nz) ! cloud cover array for 1 grid col. ! ! LOCAL: for post-process REAL :: thresh_cvr_base,thresh_cvr_top,thresh_cvr_ceiling PARAMETER (thresh_cvr_base = 0.1) PARAMETER (thresh_cvr_top = 0.1) PARAMETER (thresh_cvr_ceiling = 0.65) REAL :: default_top,default_base,default_ceiling PARAMETER (default_base = 0.0) PARAMETER (default_top = 0.0) PARAMETER (default_ceiling = 0.0) ! !----------------------------------------------------------------------- ! ! Misc local variables ! !----------------------------------------------------------------------- ! INTEGER :: k1,l,j1,j2,ibeg LOGICAL :: l_stn_clouds ! Using SAO stns' cloud obs? PARAMETER (l_stn_clouds = .true.) LOGICAL :: cldprt ! REAL :: default_clear_cover PARAMETER (default_clear_cover=0.01) ! INTEGER :: istatus_sao,istatus_fg,istatus_barnes & ,istatus_rad,istatus_vis INTEGER :: i,j,k,imid,jmid REAL :: grid_spacing_m REAL :: albmin,albmax,vcfmin,vcfmax CHARACTER (LEN=6) :: varid CHARACTER (LEN=20) :: varname CHARACTER (LEN=20) :: varunits INTEGER :: nstn,istn(mx_sng),jstn(mx_sng) REAL :: hstn(mx_sng) CHARACTER (LEN=5) :: cstn(mx_sng) INTEGER :: istat_col CHARACTER (LEN=6) :: satnam CHARACTER (LEN=80) :: fname REAL :: latsat,lonsat INTEGER :: itime,isource,ifield,lrunnam,istatwrt ! ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! !----------------------------------------------------------------------- ! WRITE(6,*)' Welcome to the ADAS Cloud Analysis' cldprt=(clddiag == 1) ibeg=MAX(1,(nx-10)) istatus=0 imid=nx/2 jmid=ny/2 ! !----------------------------------------------------------------------- ! ! Initialize cloud cover fields on the analysis grid ! !----------------------------------------------------------------------- ! PRINT*,'Call background fields routine' CALL inicldgrd(nx,ny,nz,zs, & bgqcopt,default_clear_cover, & topo,t_3d,p_3d,rh_3d,cf_modelfg,t_sfc_k,pres_sfc_pa, & cldcv,wtcldcv,z_ref_lcl,z_lcl,rh_modelfg, & r_missing,istatus_fg) ! IF (cldprt) THEN WRITE(6,'(/a)') ' ==== CLOUD_CV cloud cover first guess====' WRITE(6,632) (i,i=ibeg,nx) WRITE(6,633) (k,(cf_modelfg(i,jmid,k),i=ibeg,nx) & ,k=nz,1,-1) END IF 632 FORMAT(/1X,3X,11(1X,i4,1X)) 633 FORMAT(1X,i3,11F6.1) ! IF (istatus_fg /= 1)THEN WRITE(6,*)' Error in background field: Aborting cloud analysis' GO TO 999 END IF ! IF (cloudopt == 2) THEN ! Using radar data only PRINT*,'## NOTE ##: Using radar data only. LCL is used.' GO TO 330 END IF ! !----------------------------------------------------------------------- ! ! Create cloud sounding from the SAO cloud observations. ! !----------------------------------------------------------------------- ! WRITE(6,*) WRITE(6,*)' Call Ingest/Insert SAO routines' WRITE(6,*) n_cld_snd = 0 IF (nobsng >= 1) THEN ! CALL insert_sao1 (nx,ny,nz,dx,dy,xs,ys,zs,topo,t_sfc_k & ,cldcv,wtcldcv,t_3d,rh_modelfg & ,nobsng,stn,obstype,xsng,ysng,ista_snd & ,obstime,latsta,lonsta,elevsta & ,kcloud,store_amt,store_hgt & ,l_stn_clouds,n_cld_snd,cld_snd,wt_snd & ,i_snd,j_snd & ,istatus_sao) ! IF(istatus_sao /= 1) THEN WRITE(6,*)' Error inserting SAO data: Aborting cloud analysis' GO TO 999 END IF ELSE WRITE(6,'(a,a,/a)') & ' !!!WARNING!!! No surface cloud obs. available.', & ' Skipping SAOs insertion' END IF ! !----------------------------------------------------------------------- ! ! Initialize clouds_3d array ! !----------------------------------------------------------------------- ! DO k=1,nz DO j=1,ny DO i=1,nx clouds_3d(i,j,k)=0.0 END DO END DO END DO ! !----------------------------------------------------------------------- ! ! Do grid analysis on SAO data using Barnes interpolation. ! !----------------------------------------------------------------------- ! WRITE(6,*) WRITE(6,*)' Analyzing SAO cloud soundings' ! grid_spacing_m = dx CALL barnes_r5 (nx,ny,nz,cldcv,clouds_3d,wtcldcv,cf_modelfg & ,l_stn_clouds,default_clear_cover,cld_snd,wt_snd & ,grid_spacing_m,i_snd,j_snd,n_cld_snd & ,istatus_barnes) ! IF(cldprt) THEN WRITE(6,'(/a)') ' ==== CLOUD_CV cloud cover barnes====' WRITE(6,632) (i,i=ibeg,nx) WRITE(6,633) (k,(clouds_3d(i,jmid,k),i=ibeg,nx) & ,k=nz,1,-1) END IF !632 format(/1x,3x,11(1x,i4,1x)) !633 format(1x,i3,11f6.1) IF (istatus_barnes /= 1) THEN WRITE(6,*)' Error in Barnes interp, Aborting cld analysis...' GO TO 999 END IF ! !----------------------------------------------------------------------- ! ! Find all stations within the model domain and print the cloud ! soundings at these station points after the Barnes interpolation. ! !----------------------------------------------------------------------- ! k=0 DO i=1,n_cld_snd IF(i_snd(i) >= 1.AND.i_snd(i) <= nx & .AND. j_snd(i) <= ny.AND.j_snd(i) >= 1) THEN k=k+1 cstn(k)=stn(ista_snd(i)) istn(k)=i_snd(i) jstn(k)=j_snd(i) hstn(k)=0.001*elevsta(ista_snd(i)) END IF END DO nstn=k ! IF (cld_files == 1) THEN CALL gtlfnkey( runname, lrunnam ) WRITE(fname,'(a,a)') runname(1:lrunnam),'.cld_brns_snd' OPEN (UNIT=14,FILE=trim(fname),STATUS='unknown') WRITE(14,404) nobsng,nstn,n_cld_snd 404 FORMAT(1X,' Total/in-domain # of stations:',2I5/ & ' Cloud observations used for deriving cloud soundings:',i3/) i = nstn/24 IF(i < 1) THEN WRITE(14,405) (cstn(k),k=1,nstn) 405 FORMAT(1X,' hgt(m)',1X,24A5) WRITE(14,407) (istn(k),k=1,nstn) WRITE(14,407) (jstn(k),k=1,nstn) 407 FORMAT(1X,7X,24I5) WRITE(14,408) (hstn(k),k=1,nstn) 408 FORMAT(1X,7X,24F5.2) DO k1=1,nz WRITE(14,406) zs(istn(1),jstn(1),k1) & ,(clouds_3d(istn(l),jstn(l),k1),l=1,nstn) 406 FORMAT(1X,f7.1,24F5.2) END DO !k1 ELSE DO k=1,i j1=(k-1)*24+1 j2=k*24 WRITE(14,405) (cstn(l),l=j1,j2) WRITE(14,407) (istn(l),l=j1,j2) WRITE(14,407) (jstn(l),l=j1,j2) WRITE(14,408) (hstn(l),l=j1,j2) DO k1=1,nz WRITE(14,'(1x,f7.1,24f5.2)') zs(istn(j1),jstn(j1),k1) & ,(clouds_3d(istn(l),jstn(l),k1),l=j1,j2) END DO !k1 END DO !k j=i*24+1 WRITE(14,405) (cstn(l),l=j,nstn) WRITE(14,407) (istn(l),l=j,nstn) WRITE(14,407) (jstn(l),l=j,nstn) WRITE(14,408) (hstn(l),l=j,nstn) DO k1=1,nz WRITE(14,406) zs(istn(j),jstn(j),k1) & ,(clouds_3d(istn(l),jstn(l),k1),l=j,nstn) END DO !k1 END IF CLOSE(14) END IF ! IF (cld_files == 1) THEN WRITE(6,*) 'Writing 3D cloud fraction after inserting SAOs.' varid='cldsao' varname='Clouds after SAO' varunits='Fraction' CALL wrtvar1(nx,ny,nz,clouds_3d,varid,varname,varunits, & time,runname,dirname,istatwrt) END IF ! !----------------------------------------------------------------------- ! ! Read in the surface snow coverage data. ! Currently, the snow cover field is simply set to zero ! !----------------------------------------------------------------------- ! ! varname='snwcvr' ! CALL READVAR(nx,ny,1, varname,time,cvr_snow, runname) DO j = 1,ny DO i = 1,nx cvr_snow(i,j) = 0.0 END DO END DO ! !----------------------------------------------------------------------- ! ! Read in the land (water) coverage fraction data. ! Currently, this is simply set to 1. ! !----------------------------------------------------------------------- ! ! varname='lndfrc' ! CALL READVAR(nx,ny,1, varname,time,rland_frac, runname) DO j = 1,ny DO i = 1,nx rland_frac(i,j) = 1.0 END DO END DO ! !----------------------------------------------------------------------- ! ! Calculate solar altitude ! !----------------------------------------------------------------------- ! WRITE(6,*) 'Calculating solar position parameters.' ! DO j = 1,ny DO i = 1,nx CALL solar_pos(latgr(i,j),longr(i,j) & ,i4time,solar_alt(i,j),solar_dec,solar_ha(i,j)) END DO END DO imid = nx/2 jmid = ny/2 PRINT*,' pt(',imid,',',jmid,'): Solar alt=',solar_alt(imid,jmid), & ' declin=',solar_dec,' hour_angle=',solar_ha(imid,jmid) ! !----------------------------------------------------------------------- ! ! READ IN SATELLITE VISIBLE DATA ! !----------------------------------------------------------------------- ! ifield=1 isource=1 WRITE(6,*) 'Getting satellite visible data remapped on the', & ' model grid' ! CALL rdsatfld(nx,ny,1,vis_fname,satnam,latsat,lonsat, & itime,isource,varname,albedo,io_vis) ! IF (cld_files == 1) THEN varid='albedo' varname='Albedo' varunits='Fraction' CALL wrtvar1(nx,ny,1 ,albedo, varid,varname,varunits, & time,runname,dirname,istatwrt) END IF IF(io_vis == 0) THEN WRITE(6,'(a)') ' Read successful, calling get_vis' CALL get_vis (solar_alt,nx,ny & ,cloud_frac_vis_a,albedo,r_missing,istat_vis) albmax = -999.0 albmin = 999.0 vcfmax = -999.0 vcfmin = 999.0 DO j=1,ny DO i=1,nx IF(albedo(i,j) >= 0.) THEN albmax=MAX(albmax,albedo(i,j)) albmin=MIN(albmin,albedo(i,j)) END IF IF(cloud_frac_vis_a(i,j) >= 0.) THEN vcfmax=MAX(vcfmax,cloud_frac_vis_a(i,j)) vcfmin=MIN(vcfmin,cloud_frac_vis_a(i,j)) END IF END DO END DO WRITE(6,'(a,a)') 'Visible Satellite Data: ',vis_fname WRITE(6,'(a,f10.4,a,f10.4)') & ' min albedo:',albmin,' max albedo:',albmax WRITE(6,'(a,f10.4,a,f10.4)') & ' min vis cf:',vcfmin,' max vis cf:',vcfmax ELSE WRITE(6,'(a,a,/a)') ' ###Problem reading ',vis_fname, & ' Skipping vis processing' END IF ! IF (cld_files == 1) THEN varid ='cldalb' varname='Cloud from Albedo' varunits='Fraction' CALL wrtvar1(nx,ny,1,cloud_frac_vis_a,varid,varname,varunits, & time,runname,dirname,istatwrt) END IF ! !----------------------------------------------------------------------- ! ! Insert satellite IR data ! !----------------------------------------------------------------------- ! ifield=1 isource=1 WRITE(6,*) 'Inserting satellite IR data.' WRITE(6,*) 'Getting satellite IR data remapped on the model', & ' grid' ! CALL rdsatfld(nx,ny,1,ir_fname,satnam,latsat,lonsat, & itime,isource,varname,tb8_k,io_ir) ! IF (cld_files == 1) THEN varid='cttemp' varname='Cloud Top Temperature' varunits='Degrees K' CALL wrtvar1(nx,ny,1, tb8_k,varid,varname,varunits, & time,runname,dirname,istatwrt) END IF ! IF(io_ir == 0) THEN WRITE(6,'(a)') ' Read successful, calling insert_ir' CALL insert_ir (nx,ny,nz,latgr,longr,rland_frac,cvr_snow, & topo,zs,z_lcl,t_3d,p_3d, & t_sfc_k,t_gnd_k,clouds_3d, & solar_alt,solar_ha,solar_dec, & tb8_k,tb8_cold_k,cldtop_m_tb8,cldtop_m, & grid_spacing_m,sfc_sao_buffer, & clouds_3d,istatus_ir) ELSE WRITE(6,'(a,a,/a)') & ' !!!WARNING!!! Problem using satellite IR data', & ' Skipping IR insertion' END IF ! IF (cld_files == 1) THEN WRITE(6,*) 'Writing cloud fraction after inserting IR data.' varid='cld_ir' varname='Clouds after IR Data' varunits='Fraction' CALL wrtvar1(nx,ny,nz,clouds_3d,varid,varname,varunits, & time,runname,dirname,istatwrt) END IF ! !----------------------------------------------------------------------- ! ! Getting the 2-D maximum radar reflectivity field ! !----------------------------------------------------------------------- ! DO i=1,nx DO j=1,ny dbz_max_2d(i,j) = r_missing DO k=1,nz dbz_max_2d(i,j) = MAX(dbz_max_2d(i,j),ref_mos_3d(i,j,k)) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! Insert radar data ! !----------------------------------------------------------------------- ! 330 CONTINUE IF (istat_radar == 1) THEN WRITE(6,*) 'Inserting radar reflectivity data.' CALL insert_radar(nx,ny,nz,clddiag,topo,zs,t_3d,z_lcl & ,refthr1,refthr2,hgtrefthr & ,ref_mos_3d,clouds_3d & ,cloud_base,cloud_base_buf,l_unresolved & ,istatus_rad) ! IF (istatus_rad /= 1) THEN WRITE(6,*)' Error inserting radar data,' & ,' Aborting cld analysis' GO TO 999 END IF ELSE WRITE(6,'(a,a,/a)') ' !!!WARNING!!! Problem using radar data', & ' Skipping RADAR insertion' END IF ! IF (cld_files == 1) THEN WRITE(6,*) 'Writing cloud fraction after inserting radar data.' varid='cldrad' varname='Clouds after Radar' varunits='Fraction' CALL wrtvar1(nx,ny,nz,clouds_3d,varid,varname,varunits, & time,runname,dirname,istatwrt) END IF ! IF (cloudopt == 2) GO TO 340 ! Using radar data only ! !----------------------------------------------------------------------- ! ! Inserting the satellite visible data ! !----------------------------------------------------------------------- ! IF (io_vis == 0) THEN WRITE(6,*) 'Inserting satellite VIS data.' CALL insert_vis (nx,ny,nz,zs,topo,clouds_3d & ,albedo,cloud_frac_vis_a & ,vis_rad_thcvr,vis_rad_thdbz & ,istat_radar,ref_mos_3d,refthr2,dbz_max_2d & ,r_missing,sfc_sao_buffer,istatus_vis) ! IF (istatus_vis /= 1) THEN WRITE(6,*)' Error inserting VIS data, Aborting cld analysis.' GO TO 999 END IF ELSE WRITE(6,'(a,a,/a)') & ' !!!WARNING!!! Problem using satellite VIS data', & ' Skipping VIS data insertion' END IF ! IF (cld_files == 1) THEN WRITE(6,*) 'Writing cloud fraction after inserting VIS data.' varid='cldvis' varname='Clouds after Vis' varunits='Fraction' CALL wrtvar1(nx,ny,nz,clouds_3d,varid,varname,varunits, & time,runname,dirname,istatwrt) END IF ! 340 CONTINUE ! !----------------------------------------------------------------------- ! ! Calculate the column maximum and column total cloud cover. ! !----------------------------------------------------------------------- ! DO i=1,nx DO j=1,ny DO k=1,nz cvr_1d (k) = clouds_3d(i,j,k) END DO CALL col_max_tot (nz,cvr_1d,cvr_max(i,j),cvr_tot(i,j) & ,istat_col) END DO END DO IF (cld_files == 1) THEN WRITE(6,*) 'Writing column total cloud cover.' varid='totcvr' varname='Total Column Cloud Cover' varunits='Fraction' CALL wrtvar1(nx,ny,1,cvr_tot,varid,varname,varunits, & time,runname,dirname,istatwrt) END IF ! !----------------------------------------------------------------------- ! ! Compare the final cloud analysis with radar reflectivity ! !----------------------------------------------------------------------- ! IF (istat_radar == 1) THEN CALL compare_radar(nx,ny,nz,ref_mos_3d,dbz_max_2d & ,cvr_max,refthr2,cloud_frac_vis_a & ,vis_rad_thcvr,vis_rad_thdbz,r_missing) END IF ! !----------------------------------------------------------------------- ! ! Get Cloud Bases and Tops ! !----------------------------------------------------------------------- ! WRITE(6,*)' Calculating Cloud Ceiling, Base and Top' ! DO j = 1,ny-1 DO i = 1,nx-1 cloud_base(i,j) = default_base cloud_ceiling(i,j) = default_ceiling cloud_top(i,j) = default_top ! !----------------------------------------------------------------------- ! ! Test for Cloud Base (MSL) ! !----------------------------------------------------------------------- ! IF (cvr_max(i,j) >= thresh_cvr_base) THEN DO k = nz-1,1,-1 IF(clouds_3d(i,j,k) < thresh_cvr_base .AND. & clouds_3d(i,j,k+1) >= thresh_cvr_base) THEN cloud_base(i,j) = 0.5 * (zs(i,j,k) + zs(i,j,k+1)) END IF END DO ! k END IF ! Clouds exist in this column ! !----------------------------------------------------------------------- ! ! Test for Cloud Top (MSL) ! !----------------------------------------------------------------------- ! IF (cvr_max(i,j) >= thresh_cvr_top) THEN DO k = 1,nz-1 IF(clouds_3d(i,j,k) > thresh_cvr_top .AND. & clouds_3d(i,j,k+1) <= thresh_cvr_top) THEN cloud_top(i,j) = 0.5 * (zs(i,j,k) + zs(i,j,k+1)) END IF END DO ! k END IF ! Clouds exist in this column ! !----------------------------------------------------------------------- ! ! Test for Cloud Ceiling (AGL) ! !----------------------------------------------------------------------- ! IF (cvr_max(i,j) >= thresh_cvr_ceiling) THEN DO k = nz-1,1,-1 IF(clouds_3d(i,j,k) < thresh_cvr_ceiling .AND. & clouds_3d(i,j,k+1) >= thresh_cvr_ceiling) THEN cloud_ceiling(i,j) = 0.5 * (zs(i,j,k)+zs(i,j,k+1)) & - topo(i,j) END IF END DO ! k END IF ! Clouds exist in this column END DO ! i END DO ! j ! !----------------------------------------------------------------------- ! ! Set the boundary values ! !----------------------------------------------------------------------- ! DO i = 1,nx-1 cloud_base(i,ny) = cloud_base(i,ny-1) cloud_ceiling(i,ny) = cloud_ceiling(i,ny-1) cloud_top(i,ny) = cloud_top(i,ny-1) END DO ! i ! DO j = 1,ny cloud_base(nx,j) = cloud_base(nx-1,j) cloud_ceiling(nx,j) = cloud_ceiling(nx-1,j) cloud_top(nx,j) = cloud_top(nx-1,j) END DO ! i ! IF (cld_files == 1) THEN varid='cldbas' varname='Cloudbase' varunits='Meters' CALL wrtvar1(nx,ny,1,cloud_base,varid,varname,varunits, & time,runname,dirname,istatwrt) varid='cldtop' varname='Cloud Top Height' varunits='Meters' CALL wrtvar1(nx,ny,1,cloud_top,varid,varname,varunits, & time,runname,dirname,istatwrt) varname='ceilng' varname='Cloud Ceiling' varunits='Meters' CALL wrtvar1(nx,ny,1,cloud_ceiling,varid,varname,varunits, & time,runname,dirname,istatwrt) END IF ! !----------------------------------------------------------------------- istatus=1 999 CONTINUE ! !----------------------------------------------------------------------- ! RETURN END SUBROUTINE cloud_cv ! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE COL_MAX_TOT ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE col_max_tot (nz,cvr,cvr_max,cvr_tot,istatus) 1 ! !----------------------------------------------------------------------- ! ! PURPOSE: ! To find the number of cloud decks in one column of grid. ! !----------------------------------------------------------------------- ! ! AUTHOR: (Jian Zhang) ! 06/01/96. ! ! MODIFICATION HISTORY: ! 04/11/97 J. Zhang ! Included adascld24.inc for ncloud ! 08/06/97 J. Zhang ! Change adascld24.inc to adascld26.inc ! 05/05/98 J. Zhang ! Abandon cloud grid. Using only ARPS grid. ! ! !----------------------------------------------------------------------- ! ! Variable Declarations. ! !----------------------------------------------------------------------- ! IMPLICIT NONE ! !----------------------------------------------------------------------- ! ! INPUT: INTEGER :: nz ! ! INPUT: REAL :: cvr(nz) ! Cloud cover in one column of grid. ! ! OUTPUT: INTEGER :: istatus REAL :: cvr_max ! column maximum cldcvr REAL :: cvr_tot ! column integrated cldcvr ! ! LOCAL: INTEGER :: nlyr ! number of cloud decks (layers) in the column. INTEGER :: ilyr(nz) ! Layer index for each cloud lvl (needs) REAL :: a(nz) ! max. cloud cover of each cloud layer REAL :: f(nz) ! Apparnt "x-sectn" of cldlyrs seen from above INTEGER :: ik(nz) ! Height level representative of cloud layers ! !----------------------------------------------------------------------- ! ! Misc local variables ! !----------------------------------------------------------------------- ! INTEGER :: k,n REAL :: cvr_thresh,sumf PARAMETER (cvr_thresh = 0.1) ! !----------------------------------------------------------------------- ! ! Convert from cld cvr to discreet cloud layer indices (cvr to a) ! ! Find the maximum cloud cover "a" in each cloud deck, and ! the level index "ik" associated with the maximum cloud cover. ! !----------------------------------------------------------------------- ! istatus=0 nlyr = 0 IF(cvr(nz) > cvr_thresh) THEN ! cld_top at upper bndry nlyr = nlyr + 1 a(nlyr) = cvr(nz) ik(nlyr) = nz END IF DO k = nz-1,1,-1 IF(cvr(k) >= cvr_thresh .AND. cvr(k+1) < cvr_thresh) THEN nlyr = nlyr + 1 ! at top of a new cld layer a(nlyr) = cvr(k) ik(nlyr) = k ELSE IF(nlyr >= 1) THEN IF(cvr(k) > a(nlyr)) THEN a(nlyr) = cvr(k) ! Max cldcvr within a layer ik(nlyr) = k ! the lvl index for the max. cldcv END IF END IF IF(cvr(k) >= cvr_thresh) THEN ! Still within layer ilyr(k) = nlyr ELSE ! Below layer ilyr(k) = 0 END IF END DO ! k ! !----------------------------------------------------------------------- ! ! Convert cloud layer fractions to "cross-section" seen from ! satellite. This solves for the "f" array given the "a" array ! !----------------------------------------------------------------------- ! IF(nlyr == 0) THEN istatus=1 cvr_max=0.0 cvr_tot=0.0 RETURN END IF a(1) = MIN( f(1) = a(1) sumf = f(1) cvr_max=a(1) cvr_tot=a(1) IF(nlyr >= 2) THEN DO n = 2,nlyr a(n) = MIN( cvr_max = MAX( f(n) = a(n) * (1.0 - sumf) ! fraction of radiation reaches ! top of atm from each cld layer sumf = sumf + f(n) ! fraction of radiation blked ! /attened by all cld lyrs above END DO ! n ! !----------------------------------------------------------------------- ! ! Calculate column integrated cloud cover as if the cloud ! particles are uniformly (fusely) distributed in the atmosphere. ! !----------------------------------------------------------------------- ! cvr_tot =sumf ! END IF ! nlyr ! !----------------------------------------------------------------------- ! istatus=1 RETURN END SUBROUTINE col_max_tot ! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE COMPARE_RADAR ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE compare_radar (nx,ny,nz,ref_mos_3d,dbz_max_2d & 1 ,cvr_max,ref_base,cf_vis_a & ,vis_rad_thcvr,vis_rad_thdbz,r_missing) ! !----------------------------------------------------------------------- ! ! PURPOSE: ! This routine compares the cloud and radar fields and flags ! remaining differences that weren't caught in earlier processing ! This routine does not alter any arrays or pass anything back, ! it is diagnostic only. ! !----------------------------------------------------------------------- ! ! AUTHOR: Jian Zhang ! 07/15/96 Based on the LAPS cloud analysis code of 9/1995 ! ! MODIFICATION HISTORY: ! ! !----------------------------------------------------------------------- ! ! !----------------------------------------------------------------------- ! ! Variable Declarations. ! !----------------------------------------------------------------------- ! IMPLICIT NONE ! !----------------------------------------------------------------------- ! ! INPUT: INTEGER :: nx,ny,nz ! Model grid size(dbz) REAL :: ref_mos_3d(nx,ny,nz) ! radar reflectivity remapped on grid REAL :: dbz_max_2d(nx,ny) ! Column max. radar reflectivity (dbz) REAL :: cvr_max(nx,ny) ! column maximum cloud cover REAL :: cf_vis_a(nx,ny) ! sate. visible albedo derived cldcvr REAL :: ref_base ! thrshld define signif. radar echo REAL :: vis_rad_thcvr ! thrshld define signif. vis cldcvr (0.2) REAL :: vis_rad_thdbz ! thrshld define signif. cldy radar ehco (10dbz) REAL :: r_missing ! flag for missing or bad data ! ! OUTPUT: ! None ! !----------------------------------------------------------------------- ! ! Misc local variables ! !----------------------------------------------------------------------- ! INTEGER :: i,j ! !----------------------------------------------------------------------- ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! !----------------------------------------------------------------------- ! WRITE(6,*) 'Comparing clouds and radar (_RDR)' WRITE(6,*) 'vis_rad_thcvr = ',vis_rad_thcvr WRITE(6,*) 'vis_rad_thdbz = ',vis_rad_thdbz DO i = 1,nx DO j = 1,ny IF(cvr_max(i,j) < vis_rad_thcvr .AND. dbz_max_2d(i,j) > ref_base) THEN ! !----------------------------------------------------------------------- ! ! We have a discrepancy between the VIS and radar ! !----------------------------------------------------------------------- ! IF(cvr_max(i,j) == cf_vis_a(i,j)) THEN ! CVR = VIS IF(dbz_max_2d(i,j) < vis_rad_thdbz) THEN WRITE(6,1) i,j,cvr_max(i,j),dbz_max_2d(i,j),cf_vis_a(i,j) 1 FORMAT(' VIS_RDR: cvr_mx/dbz/vis <',2I4,f5.2,f8.1,f5.2) ELSE WRITE(6,11) i,j,cvr_max(i,j),dbz_max_2d(i,j),cf_vis_a(i,j) 11 FORMAT(' VIS_RDR: cvr_mx/dbz/vis >',2I4,f5.2,f8.1,f5.2) END IF ! dbz_max_2d < vis_rad_thdbz ELSE IF (cvr_max(i,j) < cf_vis_a(i,j)) THEN ! !----------------------------------------------------------------------- ! ! Don't blame the VIS CVR < VIS ! !----------------------------------------------------------------------- ! IF(dbz_max_2d(i,j) < vis_rad_thdbz) THEN ! !----------------------------------------------------------------------- ! ! We can potentially block out the radar ! !----------------------------------------------------------------------- ! WRITE(6,2) i,j,cvr_max(i,j),dbz_max_2d(i,j),cf_vis_a(i,j) 2 FORMAT(' CLD_RDR: cvr_mx/dbz/vis <',2I4,f5.2,f8.1,f5.2) ELSE ! Radar is too strong to block out WRITE(6,3) i,j,cvr_max(i,j),dbz_max_2d(i,j),cf_vis_a(i,j) 3 FORMAT(' CLD_RDR: cvr_mx/dbz/vis >',2I4,f5.2,f8.1,f5.2) END IF ! dbz_max_2d < vis_rad_thdbz ELSE IF (cvr_max(i,j) > cf_vis_a(i,j)) THEN ! !----------------------------------------------------------------------- ! ! Don't know if VIS lowered cloud cover CVR > VIS ! At least if difference is less than VIS "cushion" ! !----------------------------------------------------------------------- ! IF(dbz_max_2d(i,j) < vis_rad_thdbz) THEN ! !----------------------------------------------------------------------- ! ! We can potentially block out the radar ! !----------------------------------------------------------------------- ! WRITE(6,4) i,j,cvr_max(i,j),dbz_max_2d(i,j),cf_vis_a(i,j) 4 FORMAT(' ???_RDR: cvr_mx/dbz/vis <',2I4,f5.2,f8.1,f5.2) ELSE ! Radar is too strong to block out WRITE(6,5) i,j,cvr_max(i,j),dbz_max_2d(i,j),cf_vis_a(i,j) 5 FORMAT(' ???_RDR: cvr_mx/dbz/vis >',2I4,f5.2,f8.1,f5.2) END IF ! dbz_max_2d < vis_rad_thdbz END IF ! cvr_max(i,j) = cf_vis_a(i,j) END IF ! cvr_max < vis_rad_thcvr & dbz_max_2d > ref_base END DO ! j END DO ! i RETURN END SUBROUTINE compare_radar