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

subroutine da_create_bins(ni, nj, nk, bin_type, num_bins, num_bins2d, bin, bin2d, &amp;,2
   lat_min, lat_max, binwidth_lat, hgt_min, hgt_max, binwidth_hgt, latitude, height)

   !----------------------------------------------------------------------------
   !
   ! Purpose: To create the bins for calculation of statistics.
   !
   ! Input:
   ! ni, nj, nk   Dimensions
   ! bin_type     0: No binning; 
   !              1: bins for X-direction mean; 
   !              2: bins for each of binwidth_lat/binwidth_hgt.  
   !              3: bins for each of binwidth_lat/nk.  
   !              4: num_hor_bins horizontal bins /nk.  
   !              5: Average over all horizontal points (nk bins for 3D fields)
   !              6: Average over all points (only 1 bin).
   ! Optional for bin_type = 2:
   ! lat_min, lat_max Minimum/maximum latitude ranges for bin_type = 2
   ! binwidth_lat interval between bins for latitude in degree for bin_type = 2
   ! binwidth_hgt interval between bins for height in meter for bin_type = 2
   ! num_bins_hgt the number of height bins for bin_type = 2
   ! latitude     3d field latitude in degree for bin_type = 2
   ! height       3d field height in meter for bin_type = 2
   !
   ! Output:
   ! num_bins,num_bins2d ---- the number of bins for 3d and 2d fields
   ! bin     ,     bin2d ---- Assigned bin to a gridpoints for 3d and 2d fields
   !
   !----------------------------------------------------------------------------

   implicit none

   integer,        intent(in)  :: ni, nj, nk          ! Dimensions read in.
   integer,        intent(in)  :: bin_type            ! Type of bin to average over
   integer,        intent(out) :: num_bins            ! Number of bins.
   integer,        intent(out) :: num_bins2d          ! Number of bins for 2D fields
   integer,        intent(out) :: bin(1:ni,1:nj,1:nk) ! Bin at each 3D point
   integer,        intent(out) :: bin2d(1:ni,1:nj)    ! Bin at each 2D point

   real, optional, intent(in)  :: lat_min, lat_max    ! Used if bin_type = 2 (deg)
   real, optional, intent(in)  :: binwidth_lat        ! Used if bin_type = 2 (deg)
   real, optional, intent(in)  :: hgt_min, hgt_max    ! Used if bin_type = 2 (deg)
   real, optional, intent(in)  :: binwidth_hgt        ! Used if bin_type = 2 (m).
   real, optional, intent(in)  :: latitude(1:ni,1:nj) ! Latitude (degrees).
   real, optional, intent(in)  :: height(1:ni,1:nj,1:nk)     ! Height (m).

   integer           :: b, i, j, k                 ! Loop counters.
   integer           :: count                      ! Counter
   integer           :: num_bins_lat               ! Used if bin_type = 2.
   integer           :: num_bins_hgt               ! Used if bin_type = 2.
   integer           :: bin_lat                    ! Latitude bin.
   integer           :: bin_hgt                    ! Height bin.
   integer           :: num_bins_i, num_bins_j     ! Used if bin_type = 4.
   integer           :: nii, njj                   ! Used if bin_type = 4.
   integer           :: bin_i(1:ni), bin_j(1:nj)   ! Used if bin_type = 4.
   real, allocatable :: binstart_lat(:)            ! Used if bin_type = 2 (deg)
   real, allocatable :: binstart_hgt(:)            ! Used if bin_type = 2 (deg)

   if (trace_use) call da_trace_entry("da_create_bins")

   if (bin_type == 0) then         ! No averaging in space

      num_bins = nk * nj * ni
      num_bins2d = nj * ni    ! Equals number of horizontal points.

      count = 1
      do k = 1, nk
         do j = 1, nj
            do i = 1, ni
               bin(i,j,k) = count
               count = count + 1
            end do
         end do
      end do
      bin2d(:,:) = bin(:,:,1)

   else if (bin_type == 1) then    ! Average over x-direction.

      num_bins = nj * nk
      num_bins2d = nj

      count = 1
      do k = 1, nk
         do j = 1, nj
            bin(1:ni,j,k) = count
            count = count + 1
         end do
      end do
      bin2d(:,:) = bin(:,:,1)

   else if (bin_type == 2) then    ! Global latitude/height bins:

      ! Setup latitude bins:
      write(unit=stdout,fmt='(/a,f12.5)')'   Minimum latitude = ', lat_min
      write(unit=stdout,fmt='(a,f12.5)')'    Maximum latitude = ', lat_max
      write(unit=stdout,fmt='(a,f12.5)') &amp;
         '    Latitude bin width = ', binwidth_lat
      num_bins_lat = nint((lat_max - lat_min) / binwidth_lat)
      write(unit=stdout,fmt='(a,i8)') &amp;
         '    Number of latitude bins = ', num_bins_lat
   
      allocate(binstart_lat(1:num_bins_lat))
      do b = 1, num_bins_lat ! Assume south to north (as in WRF).
         binstart_lat(b) = lat_min + real(b-1) * binwidth_lat
      end do

      ! Setup height bins:
      write(unit=stdout,fmt='(/a,f12.5)')'    Minimum height = ', hgt_min
      write(unit=stdout,fmt='(a,f12.5)')'    Maximum height = ', hgt_max
      write(unit=stdout,fmt='(a,f12.5)')'    Height bin width = ', binwidth_hgt
      num_bins_hgt = nint((hgt_max - hgt_min) / binwidth_hgt)
      write(unit=stdout,fmt='(a,i8)') &amp;
         '    Number of height bins = ', num_bins_hgt

      allocate(binstart_hgt(1:num_bins_hgt))
      do b = 1, num_bins_hgt
         binstart_hgt(b) = hgt_min + real(b-1) * binwidth_hgt
      end do

      num_bins = num_bins_lat * num_bins_hgt
      num_bins2d = num_bins_lat

      ! Select height bins:
      do j = 1, nj
         do i = 1, ni
            do k = 1, nk
               if (height(i,j,k) &lt; binstart_hgt(1)) then 
                  bin_hgt = 1 ! In first bin.
               else if (height(i,j,k) &gt;= binstart_hgt(num_bins_hgt)) then
                  bin_hgt = num_bins_hgt ! In final bin.
               else 
                  do b = 1, num_bins_hgt-1
                     if (height(i,j,k) &gt;= binstart_hgt(b) .and. &amp;
                          height(i,j,k) &lt;  binstart_hgt(b+1)) then
                        bin_hgt = b
                        exit
                     end if
                  end do
               end if

               ! Select latitude bin that point falls in:
               if (k == 1) then
                  do b = 1, num_bins_lat-1
                     if (latitude(i,j) &gt;= binstart_lat(b) .and. &amp;
                        latitude(i,j) &lt; binstart_lat(b+1)) then
                        bin_lat = b
                        exit
                     end if
                  end do
                  if (latitude(i,j) &gt;= binstart_lat(num_bins_lat)) then
                     ! In final bin.
                     bin_lat = num_bins_lat
                  end if
                  bin2d(i,j) = bin_lat
               end if
               bin(i,j,k) = bin_lat + num_bins_lat * (bin_hgt - 1)
            end do
         end do
      end do

      deallocate(binstart_lat)
      deallocate(binstart_hgt)

   else if (bin_type == 3) then    ! Latitude/nk bins:

      ! Setup latitude bins:
      write(unit=stdout,fmt='(/a,f12.5)')'   Minimum latitude = ', lat_min
      write(unit=stdout,fmt='(a,f12.5)')'    Maximum latitude = ', lat_max
      write(unit=stdout,fmt='(a,f12.5)')'    Latitude bin width = ',binwidth_lat
      num_bins_lat = nint((lat_max - lat_min) / binwidth_lat)
      write(unit=stdout,fmt='(a,i8)') &amp;
         '    Number of latitude bins = ', num_bins_lat
   
      allocate(binstart_lat(1:num_bins_lat))
      do b = 1, num_bins_lat ! Assume south to north (as in WRF).
         binstart_lat(b) = lat_min + real(b-1) * binwidth_lat
      end do

      num_bins = num_bins_lat * nk
      num_bins2d = num_bins_lat

      ! Select bins:
      do j = 1, nj
         do i = 1, ni
            do k = 1, nk
               ! Select latitude bin that point falls in:
               if (k == 1) then
                  do b = 1, num_bins_lat-1
                     if (latitude(i,j) &gt;= binstart_lat(b) .and. &amp;
                        latitude(i,j) &lt; binstart_lat(b+1)) then
                        bin_lat = b
                        exit
                     end if
                  end do
                  if (latitude(i,j) &gt;= binstart_lat(num_bins_lat)) then
                     ! In final bin.
                     bin_lat = num_bins_lat
                  end if
                  bin2d(i,j) = bin_lat
               end if
               bin(i,j,k) = bin_lat + num_bins_lat * (k - 1)
            end do
         end do
      end do

      deallocate(binstart_lat)

   else if (bin_type == 4) then    ! binwidth_lat/nk bins:

      ! Setup horizontal bins:
      write(unit=stdout,fmt='(/a,f12.5)') &amp;
         '   Number of grid-cells to average over = ', binwidth_lat
      ! use binwidth_lat, but actually an integer number of points.
 
      num_bins_j = int(real(nj) / real(binwidth_lat))
      njj = int(binwidth_lat) * num_bins_j
      do j = 1, njj
         bin_j(j) = 1 + int(real(j-1) / binwidth_lat)
      end do
      if (nj &gt; njj) bin_j(njj+1:nj) = bin_j(njj)

      num_bins_i = int(real(ni) / real(binwidth_lat))
      nii = int(binwidth_lat) * num_bins_i
      do i = 1, nii
         bin_i(i) = 1 + int(real(i-1) / binwidth_lat)
      end do
      if (ni &gt; nii) bin_i(nii+1:ni) = bin_i(nii)

      num_bins2d = num_bins_i * num_bins_j
      num_bins = num_bins2d * nk

      do j = 1, nj
         do i = 1, ni
            bin2d(i,j) = bin_i(i) + (bin_j(j) - 1) * num_bins_i
            do k = 1, nk
               bin(i,j,k) = bin2d(i,j) + (k - 1) * num_bins2d
            end do
         end do
      end do

   else if (bin_type == 5) then    ! Average over all horizontal points.

      num_bins = nk
      num_bins2d = 1

      do k = 1, nk
         bin(:,:,k) = k
      end do
      bin2d(:,:) = 1

   else if (bin_type == 6) then    ! Average over all points.

      num_bins = 1
      num_bins2d = 1
      bin(:,:,:) = 1
      bin2d(:,:) = 1
   end if

   if (trace_use) call da_trace_exit("da_create_bins")

end subroutine da_create_bins