subroutine statistic (line,error)
  use gkernel_interfaces
  use mapping_interfaces, except_this=>statistic
  use clean_def
  use clean_arrays
  use clean_types
  use gbl_message
  !----------------------------------------------------------------------
  ! @ private
  !
  ! MAPPING
  !     Statistics on internal images
  !----------------------------------------------------------------------
  character(len=*), intent(inout) :: line
  logical, intent(out) :: error
  !
  real(8), parameter :: pi=3.14159265358979323846d0
  !
  type (gildas), pointer :: hstat
  real, pointer :: dstat(:,:,:)
  integer ier, plane, na, nx, ny
  character(len=12) argum,stype
  logical do_whole, do_mask
  real valmin, valmax, mean, rms, noise, beam, flux, sec, lambda, jyperk
  integer imin, imax, jmin, jmax, n_sup, n_off, box(4), ntype
  character(len=4) :: rname = 'STAT'
  character(len=8) :: prefix
  character(len=2) :: fixpre
  real :: scale, uscale
  !
  ! Save DO_MASK
  do_mask = user_method%do_mask
  !
  ! Type of image (default = clean)
  !
  argum = 'CLEAN'
  call sic_ke (line,0,1,argum,na,.false.,error)
  call sic_ambigs ('STATISTIC',argum,stype,ntype,vtype,mtype,error)
  if (error) return
  !
  ! Plane
  if (sic_present(0,2)) then
    call sic_i4(line,0,2,plane,.false.,error)
    if (error) return
  else
    call sic_get_inte ('FIRST',plane,error)
  endif
  if (plane.eq.0) plane = 1
  !
  ! Allocate memory
  if (stype.eq.'CLEAN') then
    if (.not.allocated(dclean)) then
      call map_message(seve%e,rname,'No clean image')
      error = .true.
      return
    endif
    hstat => hclean
    dstat => dclean
  elseif (stype.eq.'DIRTY') then
    if (.not.allocated(ddirty)) then
      call map_message(seve%e,rname,'No dirty image')
      error = .true.
      return
    endif
    hstat => hdirty
    dstat => ddirty
  elseif (stype.eq.'RESIDUAL') then
    if (.not.allocated(dresid)) then
      call map_message(seve%e,rname,'No residual image')
      error = .true.
      return
    endif
    hstat => hresid
    dstat => dresid
  else
    call map_message(seve%e,rname,'Unkown image type')
    error = .true.
    return
  endif
  !
  ! Local support
  nx = hstat%gil%dim(1)
  ny = hstat%gil%dim(2)
  !
  !  - set all the support to .true. (ie compute stat on the whole image)
  !    1) /WHOLE option
  !
  !  - otherwise, use the current mask:
  !       - call check_msk to define mask if necessary (e.g. support
  !         just loaded)
  !       - copy mask in the local support memory
  !
  if (sic_present(1,0)) then
    do_whole = .true.
  elseif  (do_mask) then
    if (.not.allocated(d_mask)) then
      allocate(d_mask(nx,ny),d_list(nx*ny),stat=ier)
      if (ier.ne.0) then
        call map_message(seve%e,rname,'Error getting support memory')
        error = .true.
        return
      endif
      method%do_mask = .true.
      method%nlist = 0
    endif
    do_whole = .false.
  else
    if (method%nlist.eq.0) do_whole = .true.
  endif
  !
  ! Avoid edges
  box = [nx/16,ny/16,15*nx/16,15*ny/16]
  if (do_whole) then
    call map_message(seve%i,rname,'Using the whole image')
    if (sic_present(1,1)) box = [1,1,nx,ny]
  else
    call check_area(method,hstat,.true.)
    call check_mask(method,hstat)
    box(1) = min(box(1),method%box(1))
    box(2) = min(box(2),method%box(2))
    box(3) = max(box(3),method%box(3))
    box(4) = max(box(4),method%box(4))
    call map_message(seve%i,rname,'Using current support')
  endif
  !
  ! Compute stat
  if (do_whole) then
    call compute_stat(nx,ny,dstat(:,:,plane),box,   &
       &    valmin,imin,jmin,valmax,imax,jmax,mean,rms,noise,n_sup,n_off)
  else
    call compute_stat(nx,ny,dstat(:,:,plane),box,   &
       &    valmin,imin,jmin,valmax,imax,jmax,mean,rms,noise,n_sup,n_off, &
       &    d_mask)
  endif
  !
  write(6,101) 'Found ',n_sup,' pixels on, ',n_off,' off source'
  write(6,102) 'Map maximum: ',valmax,' at ',imax,jmax
  write(6,102) 'Map minimum: ',valmin,' at ',imin,jmin
  !
  !
  ! Find the appropriate unit (Jy, mJy or microJy)
  if (noise.lt.1e-5) then
    scale = 1e6
    prefix = ' microJy'
  else if (noise.lt.0.01) then
    scale = 1e3
    prefix = ' mJy'
  else
    scale = 1.0
    prefix = ' Jy'
  endif
  !
  ! If CLEAN image, compute total flux
  if (stype.eq.'CLEAN') then
    write(6,'(A,1PG11.2,A,A)') ' Mean: ',mean*scale,trim(prefix)//'/beam'
    write(6,'(A,F10.3,A,F10.3,A)') ' rms:  On:', rms*scale, '  Off:', noise*scale,trim(prefix)//'/beam'
    beam = pi*hclean%gil%majo*hclean%gil%mino/4./log(2.0)
    beam = beam/abs(hclean%gil%convert(3,1)*hclean%gil%convert(3,2))
    flux = (mean*n_sup)/beam
    write(6,104) 'Total flux in CLEAN map: ',flux*scale,trim(prefix)
    sec = 180.*3600./pi
    lambda = 2.99792458e8/hclean%gil%freq*1e-6
    jyperk = 2.0*1.38e3*   &
     &      pi*hclean%gil%majo*hclean%gil%mino/4./log(2.0)   &
     &      /lambda**2.
    if (jyperk*scale.gt.1e3) then
      uscale = 1e-3
      fixpre = 'mK'
    else
      uscale = 1
      fixpre = ' K'
    endif
    write(6,105) 'Tb scale for CLEAN map: 1 '//fixpre//' = ',   &
     &      jyperk*uscale*scale,trim(prefix)//'/beam'
    write(6,106) 'Clean Beam is ',   &
     &      hclean%gil%majo*sec,' x ',hclean%gil%mino*sec,   &
     &      ' sec at PA = ',hclean%gil%posa*180/pi,' deg'
    call sic_delvariable ('CLEANFLUX',.false.,error)
    call sic_def_real ('CLEANFLUX',flux,0,0,.false.,error)
  else
    write(6,'(A,F10.2,A,A)') ' Mean: ',mean*scale,trim(prefix)
    write(6,'(A,F10.2,A,F10.2,A)') ' rms:  On:', rms*scale, '  Off:', noise*scale,trim(prefix)
  endif
  !
  !
  101   format (1x,a,i8,a,i8,a)
  102   format (1x,a,f10.3,a,'(',i6,',',i6,')')
  104   format (1x,a,f9.3,a)
  105   format (1x,a,1pg11.3,a)
  106   format (1x,a,f7.3,a,f7.3,a,f5.0,a)
end subroutine statistic
!
subroutine compute_stat(nx,ny,amap,box, &
     &    valmin,imin,jmin,valmax,imax,jmax,mean,rms,noise,np,nn, &
     &    support)
  !--------------------------------------------------------------
  ! @ private-mandatory
  !
  ! MAPPING
  !    Statistics on image
  !--------------------------------------------------------------
  integer, intent(out) :: np, nn
  integer, intent(in) :: nx,ny
  real, intent(in) :: amap(nx,ny)
  integer, intent(out) :: imin, jmin, imax, jmax
  integer, intent(in) ::  box(4)
  real, intent(out) :: valmin, valmax, mean, rms, noise
  logical, intent(in), optional :: support(nx,ny)
  !
  integer i,j
  real val, mean2
  !
  valmin = 1e30                ! ??
  valmax = -1e30
  mean = 0.
  mean2 = 0.
  noise = 0.
  nn = 0
  np = 0
  !
  if (present(support)) then
    do i = box(1),box(3)
      do j = box(2),box(4)
        val = amap(i,j)
        if (support(i,j)) then
          np  = np+1
          mean = mean+val
          mean2 = mean2+val*val
          if (valmax.lt.val) then
            valmax = val
            imax = i
            jmax = j
          endif
          if (valmin.gt.val) then
            valmin= val
            imin = i
            jmin = j
          endif
        else
          nn = nn+1
          noise = noise+val*val
        endif
      enddo
    enddo
  else
    do i = box(1),box(3)
      do j = box(2),box(4)
        val = amap(i,j)
        mean = mean+val
        mean2 = mean2+val*val
        if (valmax.lt.val) then
          valmax = val
          imax = i
          jmax = j
        endif
        if (valmin.gt.val) then
          valmin= val
          imin = i
          jmin = j
        endif
      enddo
    enddo
    np  = (box(4)-box(2)+1)*(box(3)-box(1)+1)
  endif
  !
  mean = mean/np
  mean2 = mean2/np
  rms = sqrt(mean2-mean*mean)
  if (nn.ne.0) then
    noise = sqrt(noise/nn)
  else
    noise = rms
  endif
end subroutine compute_stat
