<HTML> <BODY BGCOLOR=#ccccdd LINK=#0000aa VLINK=#0000ff ALINK=#ff0000 ><BASE TARGET="bottom_target"><PRE>
<A NAME='GEN_BE_HIST'><A href='../../html_code/gen_be/gen_be_hist.f90.html#GEN_BE_HIST' TARGET='top_target'><IMG SRC="../../gif/bar_yellow.gif" border=0></A>

program gen_be_hist,6
!------------------------------------------------------------------------
!  Purpose: Computes frequency distributiopn of BE statistics
!  Auothor: Syed RH Rizvi (MMM/NESL/NCAR)   Date: 02/01/2010
!           &amp; Monika Krysta, (CTBTO, Vienna, Austria)
!
!  Note: Please acknowledge author/institute in work that uses this code.
!------------------------------------------------------------------------

   use da_control, only : stderr, stdout, filename_len
   use da_tools_serial, only : da_get_unit,da_advance_cymdh

   implicit none

   character*10        :: start_date, end_date       ! Starting and ending dates.
   character*10        :: date, new_date             ! Current date (ccyymmddhh).
   character*10        :: variable                   ! Variable name
   character(len=filename_len)        :: dat_dir     ! Input data directory.
   character(len=filename_len)        :: filename    ! Input filename.
   character*3         :: ce                         ! Member index -&gt; character.
   integer             :: ni, nj, nk, nkdum          ! Grid dimensions.
   integer             :: i, j, k, member            ! Loop counters.
   integer             :: b                          ! Bin marker.
   integer             :: sdate, cdate, edate        ! Starting, current ending dates.
   integer             :: interval                   ! Period between dates (hours).
   integer             :: ne                         ! Number of ensemble members.
   integer             :: bin_type                   ! Type of bin to average over.
   integer             :: num_bins                   ! Number of bins (3D fields).
   integer             :: num_bins2d                 ! Number of bins (3D fields).
   real                :: lat_min, lat_max           ! Used if bin_type = 2 (degrees).
   real                :: binwidth_lat               ! Used if bin_type = 2 (degrees).
   real                :: hgt_min, hgt_max           ! Used if bin_type = 2 (m).
   real                :: binwidth_hgt               ! Used if bin_type = 2 (m).
   logical             :: first_time                 ! True if first file.
   real, allocatable   :: field(:,:,:)               ! Field 
   integer, allocatable:: bin(:,:,:)                 ! Bin assigned to each 3D point.
   integer, allocatable:: bin2d(:,:)                 ! Bin assigned to each 2D point.
   integer, allocatable:: bin_pts(:)                 ! Number of points in bin (3D fields).
   integer, allocatable:: hist(:,:)                  ! Binned error values
   real, allocatable   :: var_field(:)               ! variance
   real, allocatable   :: stdev_field(:)               ! standard deviation
   real, allocatable   :: class_hist(:,:)            ! Binned error values
   integer, allocatable   :: rain_class(:,:)         ! 2D rain class of perturbation
   character*10           :: rainclvar               ! Variable name 
   integer                :: Nstdev, N_dim_hist      ! Histogram parameters
   integer             :: intcl                      ! Histogram loop counter

   namelist / gen_be_hist_nl / start_date, end_date, interval, &amp;
                                ne, variable, Nstdev, N_dim_hist

   integer :: ounit,iunit,namelist_unit

   stderr = 0
   stdout = 6

!---------------------------------------------------------------------------------------------
   write(6,'(a)')' [1] Initialize namelist variables and other scalars.'
!---------------------------------------------------------------------------------------------

   call da_get_unit(ounit)
   call da_get_unit(iunit)
   call da_get_unit(namelist_unit)

   start_date = '2004030312'
   end_date = '2004033112'
   interval = 24
   ne = 1
   variable = 'psi'
   dat_dir = '/mmmtmp1/dmbarker'
   Nstdev = 5
   N_dim_hist = 20

   open(unit=namelist_unit, file='gen_be_hist_nl.nl', &amp;
        form='formatted', status='old', action='read')
   read(namelist_unit, gen_be_hist_nl)
   close(namelist_unit)

   read(start_date(1:10), fmt='(i10)')sdate
   read(end_date(1:10), fmt='(i10)')edate
   write(6,'(2a)')' Computing error histogram for field ', variable
   write(6,'(4a)') ' Time period is ', start_date, ' to ', end_date
   write(6,'(a,i8,a)')' Interval between dates = ', interval, 'hours.'
   write(6,'(a,i8)')' Number of ensemble members at each time = ', ne
   write(6,'(2(a,i8))')' Parameters of the histogram Nstdev = ', Nstdev,&amp;
        ' and N_dim_hist = ',N_dim_hist

   date = start_date
   cdate = sdate

!---------------------------------------------------------------------------------------------
   write(6,'(a)')' [2] Accumulate values of errors per bin and vert. level'
!--------------------------------------------------------------------------------------------- 
   first_time = .true.

   do while ( cdate &lt;= edate )
      write(6,'(a,a)')'    Processing data for date ', date

      do member = 1, ne

         write(ce,'(i3.3)')member

!        Read field:
         filename = trim(variable)//'/'//date(1:10)
         filename = trim(filename)//'.'//trim(variable)//'.e'//ce
         open (iunit, file = filename, form='unformatted')
         read(iunit)ni, nj, nk
   
        if ( first_time ) then
            write(6,'(a,3i8)')'    i, j, k dimensions are ', ni, nj, nk
            allocate( bin(1:ni,1:nj,1:nk) )
            allocate( bin2d(1:ni,1:nj) )
            allocate( field(1:ni,1:nj,1:nk) )
!           Read bin info:
            filename = 'bin.data'
            open (iunit+1, file = filename, form='unformatted')
            read (iunit+1) bin_type
            read (iunit+1) lat_min, lat_max, binwidth_lat
            read (iunit+1) hgt_min, hgt_max, binwidth_hgt
            read (iunit+1) num_bins, num_bins2d
            read (iunit+1) bin(1:ni,1:nj,1:nk)
            read (iunit+1) bin2d(1:ni,1:nj)
            close(iunit+1)
         end if

         read(iunit)field
         close(iunit)

         if ( first_time ) then
            write(6,'(a)')' Setup of histogram parameters'
            allocate( class_hist(1:nk,1:N_dim_hist) )
            allocate( var_field(1:nk) )
            allocate( stdev_field(1:nk) )

            class_hist  = 0.0
            var_field   = 0.0
            stdev_field = 0.0

            ! finds out global stdev of first field to set up dimensions
            do k=1, nk
               var_field(k)   = 1.0/real(ni*nj-1.0)*sum(field(1:ni,1:nj,k)**2) &amp;
                    -real(ni*nj)/real(ni*nj-1.0)*(sum(field(1:ni,1:nj,k))/real(ni*nj))**2
               stdev_field(k) = sqrt(var_field(k))
               write(6,'(a,i4,3(a,e13.5))')' var_field(',k,')=  ', var_field(k),&amp;
                    ' lower=',-Nstdev*stdev_field(k),' upper=',Nstdev*stdev_field(k)
               do i=1,N_dim_hist
                  class_hist(k,i)=-Nstdev*stdev_field(k)+2*Nstdev*stdev_field(k)*real(i-1)/real(N_dim_hist-1)
!                  write(6,'(2(a,i4),a,e13.5') '       class_hist(',k,',',i,')=',class_hist(k,i)
               end do
            end do

            ! allocate histogram
            allocate( hist(1:N_dim_hist,1:num_bins))
            hist(:,:) = 0
            !--ym-- 2D rain class of perturbation    
            if (bin_type==7) allocate( rain_class(1:ni,1:nj) )
            !--ym-- 2D rain class of perturbation    
            first_time = .false.
         end if

         !--ym-- 2D rain class of perturbation     
         if (bin_type==7) then
            !        Read rain_class:
            rainclvar = 'raincl'
            filename = trim(rainclvar)//'/'//date(1:10)
            filename = trim(filename)//'.'//trim(rainclvar)//'.e'//ce//'.01'
            open (iunit, file = filename, form='unformatted')
            read(iunit)ni, nj, nkdum
            read(iunit)rain_class
            close(iunit)
  
            ! bin depends on rain class of perturbation!
            ! re-read bin info:
            filename = 'bin.data'
            open (iunit+1, file = filename, form='unformatted')
            read(iunit+1)bin_type
            read(iunit+1)lat_min, lat_max, binwidth_lat
            read(iunit+1)hgt_min, hgt_max, binwidth_hgt
            read(iunit+1)num_bins, num_bins2d
            read(iunit+1)bin(1:ni,1:nj,1:nk)
            read(iunit+1)bin2d(1:ni,1:nj)
            close(iunit+1)
            ! update it 2D
            do j = 1, nj
               do i = 1, ni
                  bin2d(i,j)=rain_class(i,j)*num_bins2d/4+bin2d(i,j)
               end do
            end do
            ! update it 3D
            do k = 1, nk
               do j = 1, nj
                  do i = 1, ni
                     bin(i,j,k)=rain_class(i,j)*num_bins/4+bin(i,j,k)
                  end do
               end do
            end do
         end if
        !--ym-- 2D rain class of perturbation         
          
!        accumulate values in histogram
         do k = 1, nk
            do j = 1, nj
               do i = 1, ni
                  b = bin(i,j,k)
                  ! finds out in which bin calls we fall
                  intcl=int(1+0.5*(N_dim_hist-1.0)*(1+field(i,j,k)/(Nstdev*stdev_field(k))))
                  if (intcl.ge.1 .and. intcl.le.N_dim_hist) then
                     hist(intcl,b)=hist(intcl,b)+1
                  else
                     ! finds out gross errors (to find bug in rh fields)
                     if (abs(field(i,j,k))&gt;50*Nstdev*stdev_field(k)) then
                        write(6,'(3(a,i3),2(a,e20.5e3))') ' WARNING Gross error -&gt; err_field(',i," ",j," ",k,&amp;
                             ") =",field(i,j,k)," whereas stdev =",stdev_field(k)
                     end if
                  end if
               end do
            end do
         end do
      
      end do  ! End loop over ensemble members.

!     Calculate next date:
      call da_advance_cymdh( date, interval, new_date )
      date = new_date
      read(date(1:10), fmt='(i10)')cdate
   end do     ! End loop over times.

!---------------------------------------------------------------------------------------------
   write(6,'(a)')' [3] Write out computed histogram'
!--------------------------------------------------------------------------------------------- 

   ! write out results
   filename = 'hist.'//trim(variable)//'.dat'
   open (ounit, file = filename, form='unformatted')
   write(ounit)nk,num_bins,N_dim_hist
   ! split until I do find a working NCL script that reads large binairies
   do k=1,nk
      write(ounit)class_hist(k,:)
   end do
   do b=1,num_bins
      write(ounit)hist(:,b)
   end do
   close(ounit)

end program gen_be_hist