program sum
  use gildas_def
  use gkernel_interfaces
  use image_def
  use gbl_format
  !---------------------------------------------------------------------
  ! GDF	Main program for linear combination of images
  !		X(i,j) = X(i,j) + Z(i,j)
  !		Y(i,j) = Y(i,j) + 1
  ! Subroutines
  !	SUM001, SUM002
  !---------------------------------------------------------------------
  character(len=*), parameter :: pname = 'SUM'
  ! Local
  character(len=filename_length) :: namex,namey,namez
  logical :: start,error
  real :: fact
  integer :: i, j, ier
  type(gildas) :: x,y,z
  !
  call gildas_open
  call gildas_logi('START$',start,1)
  call gildas_char('Z_NAME$',namez)
  call gildas_char('Y_NAME$',namey)
  call gildas_char('X_NAME$',namex)
  call gildas_real('WEIGHT$',fact,1)
  call gildas_close
  !
  call gildas_null(z)
  call gdf_read_gildas(z,namez,'.gdf',error,data=.false.)
  if (error) then
    write(6,*) 'F-'//pname//',  Cannot read input file'
    goto 100
  endif
  !
  call gildas_null(y)
  if (start) then
    call gdf_copy_header(z,y,error)
    call sic_parsef(namey,y%file,' ','.gdf')
    y%gil%eval = -1
    call gdf_create_image(y,error)
    if (error) then
      write(6,*) 'F-'//pname//',  Cannot create weight file'
      goto 100
    endif
  else
    call gdf_read_gildas(y,namey,'.gdf',error,data=.false.)
    if (error) then
      write(6,*) 'F-'//pname//',  Cannot read weight file'
      goto 100
    endif
  endif
  !
  call gildas_null(x)
  if (start) then
    call gdf_copy_header(y,x,error)
    call sic_parsef(namex,x%file,' ','.gdf')
    call gdf_create_image(x,error)
    if (error) then
      write(6,*) 'F-'//pname//',  Cannot create accumulation image'
      goto 100
    endif
  else
    call sic_parsef(namex,x%file,' ','.gdf')
    call gdf_read_gildas(x,namex,'.gdf',error,data=.false.)
    if (error) then
      write(6,*) 'F-'//pname//',  Cannot read accumulation image'
      goto 100
    endif
  endif
  !
  allocate (x%r2d(x%gil%dim(1),x%gil%dim(2)), &
      & y%r2d(y%gil%dim(1),y%gil%dim(2)), &
      & z%r2d(z%gil%dim(1),z%gil%dim(2)), stat=ier)
  if (ier.ne.0) then
    write(6,*) 'F-'//pname//',  Cannot read accumulation image'
    goto 100
  endif      
  !
  if (z%gil%eval.ge.0) z%gil%eval = max(abs(z%gil%bval*1e-7),z%gil%eval)
  do j=1,x%gil%dim(4)
    x%blc(4) = j 
    x%trc(4) = j
    do i=1,x%gil%dim(3)
      x%blc(3) = i
      x%trc(3) = i
      y%blc = x%blc
      y%trc = x%trc
      z%blc = x%blc
      z%trc = x%trc
      call gdf_read_data(z,z%r2d,error)
      if (start) then
        call sum001(z%r2d, y%r2d, x%r2d,  &
     &          x%gil%dim(1)*x%gil%dim(2),z%gil%bval,z%gil%eval,fact)
      else
        call gdf_read_data(y,y%r2d,error)
        call sum002(z%r2d, y%r2d, x%r2d,  &
     &          x%gil%dim(1)*x%gil%dim(2),z%gil%bval,z%gil%eval,fact)
      endif
      call gdf_write_data (x,x%r2d,error)
    enddo
  enddo
  call gagout ('S-'//pname//',  Successful completion')
  call sysexi (1)
  !
100 call sysexi (fatale)
end program sum
!
subroutine sum002(z,y,x,n,bval,eval,fact)
  use gildas_def
  !---------------------------------------------------------------------
  !     GDF	Internal routine
  !     Linear combination of input arrays
  !     X = X + FACT*Z
  !     Y = Y + FACT
  !---------------------------------------------------------------------
  integer(index_length), intent(in) :: n          ! Array size
  real(4), intent(in) :: z(n)       ! Array to be added
  real(4), intent(inout) :: y(n)    ! Weight array
  real(4), intent(inout) :: x(n)    ! Accumulation array
  real(4), intent(in) :: bval       ! Blanking value
  real(4), intent(in) :: eval       ! Blanking tolerance
  real(4), intent(in) :: fact       ! Scale factor
  ! Local
  integer :: i
  !
  if (eval.lt.0.0) then
    do i=1,n
      x(i) = x(i) + fact*z(i)
      y(i) = y(i) + fact
    enddo
  else
    do i=1,n
      if (abs(z(i)-bval).gt.eval) then
        x(i) = x(i) + fact*z(i)
        y(i) = y(i) + fact
      endif
    enddo
  endif
end subroutine sum002
!
subroutine sum001(z,y,x,n,bval,eval,fact)
  use gildas_def
  !---------------------------------------------------------------------
  !     GDF	Internal routine
  !     Linear combination of input arrays: initialization
  !     X = Z
  !     Y = 1
  !---------------------------------------------------------------------
  integer(index_length), intent(in) :: n          ! Array size
  real(4), intent(in) :: z(n)       ! Array to be added
  real(4), intent(out) :: y(n)      ! Weight array
  real(4), intent(out) :: x(n)      ! Accumulation array
  real(4), intent(in) :: bval       ! Blanking value
  real(4), intent(in) :: eval       ! Blanking tolerance
  real(4), intent(in) :: fact       ! Scale factor
  ! Local
  integer :: i
  !
  if (eval.lt.0.0) then
    do i=1,n
      x(i) = fact*z(i)
      y(i) = fact
    enddo
  else
    do i=1,n
      if (abs(z(i)-bval).gt.eval) then
        x(i) = fact*z(i)
        y(i) = fact
      else
        y(i) = 0.0
        x(i) = 0.0
      endif
    enddo
  endif
end subroutine sum001
