!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module mapping_gaussian_tool
  public :: mulgau
  private
  !
contains
  !
  subroutine mulgau(data,nx,ny,bmaj,bmin,pa,scale,xinc,yinc)
    use phys_const
    !----------------------------------------------------------------------
    ! Multiply the TF of an image by the TF of a convolving gaussian
    ! function. BMAJ and BMIN are the widths of the original gaussian. PA
    ! is the position angle of major axis (from north towards east). SCALE
    ! is a scaling factor.
    !----------------------------------------------------------------------
    integer, intent(in)    :: nx,ny       ! X,Y size
    real,    intent(in)    :: bmaj        ! Major axis
    real,    intent(in)    :: bmin        ! Minor axis
    real,    intent(in)    :: pa          ! Position Angle
    real,    intent(in)    :: scale       ! Flux scale factor
    real,    intent(in)    :: xinc        ! X pixel size
    real,    intent(in)    :: yinc        ! Y pixel size
    complex, intent(inout) :: data(nx,ny) ! TF of Data to be smoothed
    !
    logical :: norot,rot90
    integer :: i,j,nx1,nx2
    real :: amaj,amin,fact,cx,cy,sx,sy,gain,seuil
    real, parameter :: eps=1.e-7
    !
    norot = ( abs(mod(pa,180.)).le.eps)
    rot90 = ( abs(mod(pa,180.)-90.).le.eps)
    amaj = bmaj*pi/(2.*sqrt(log(2.)))
    amin = bmin*pi/(2.*sqrt(log(2.)))
    !
    gain = scale ! For brightness norm.
    seuil = 40.0
    !
    cx = cos(pa*pi/180.0d0)/nx*amin
    cy = cos(pa*pi/180.0d0)/ny*amaj
    sx = sin(pa*pi/180.0d0)/nx*amaj
    sy = sin(pa*pi/180.0d0)/ny*amin
    !
    ! Convert map units to pixels
    cx = cx / xinc
    cy = cy / yinc
    sx = sx / xinc
    sy = sy / yinc
    nx2 = nx/2
    nx1 = nx2+1
    !
    ! Optimised code for Position Angle 0 degrees
    if (norot) then
       do j=1,ny/2
          do i=1,nx2
             fact = (float(j-1)*cy)**2 + (float(i-1)*cx)**2
             if (fact.gt.seuil) then
                data(i,j) = 0.0
             else
                data(i,j) = data(i,j)*exp(-fact)*gain
             endif
          enddo
          do i=nx1,nx
             fact = (float(j-1)*cy)**2 + (float(i-nx-1)*cx)**2
             if (fact.gt.seuil) then
                data(i,j) = 0.0
             else
                data(i,j) = data(i,j)*exp(-fact)*gain
             endif
          enddo
       enddo
       do j=ny/2+1,ny
          do i=1,nx2
             fact = (float(j-ny-1)*cy)**2 + (float(i-1)*cx)**2
             if (fact.gt.seuil) then
                data(i,j) = 0.0
             else
                data(i,j) = data(i,j)*exp(-fact)*gain
             endif
          enddo
          do i=nx1,nx
             fact = (float(j-ny-1)*cy)**2 + (float(i-nx-1)*cx)**2
             if (fact.gt.seuil) then
                data(i,j) = 0.0
             else
                data(i,j) = data(i,j)*exp(-fact)*gain
             endif
          enddo
       enddo
       !
       ! Optimised code for Position Angle 90 degrees
    elseif (rot90) then
       do j=1,ny/2
          do i=1,nx2
             fact = (float(i-1)*sx)**2 + (float(j-1)*sy)**2
             if (fact.gt.seuil) then
                data(i,j) = 0.0
             else
                data(i,j) = data(i,j)*exp(-fact)*gain
             endif
          enddo
          do i=nx1,nx
             fact = (float(i-nx-1)*sx)**2 + (float(j-1)*sy)**2
             if (fact.gt.seuil) then
                data(i,j) = 0.0
             else
                data(i,j) = data(i,j)*exp(-fact)*gain
             endif
          enddo
       enddo
       do j=ny/2+1,ny
          do i=1,nx2
             fact = (float(i-1)*sx)**2 + (float(j-ny-1)*sy)**2
             if (fact.gt.seuil) then
                data(i,j) = 0.0
             else
                data(i,j) = data(i,j)*exp(-fact)*gain
             endif
          enddo
          do i=nx1,nx
             fact = (float(i-nx-1)*sx)**2 + (float(j-ny-1)*sy)**2
             if (fact.gt.seuil) then
                data(i,j) = 0.0
             else
                data(i,j) = data(i,j)*exp(-fact)*gain
             endif
          enddo
       enddo
    else
       ! General case of a rotated elliptical gaussian
       do j=1,ny/2
          do i=1,nx2
             fact = ( float(i-1)*sx + float(j-1)*cy)**2  &
                  + (-float(i-1)*cx + float(j-1)*sy)**2
             if (fact.gt.seuil) then
                data(i,j) = 0.0
             else
                data(i,j) = data(i,j)*exp(-fact)*gain
             endif
          enddo
          do i=nx1,nx
             fact = (  float(i-nx-1)*sx + float(j-1)*cy)**2   &
                  + ( -float(i-nx-1)*cx + float(j-1)*sy)**2
             if (fact.gt.seuil) then
                data(i,j) = 0.0
             else
                data(i,j) = data(i,j)*exp(-fact)*gain
             endif
          enddo
       enddo
       do j=ny/2+1,ny
          do i=1,nx2
             fact = ( float(i-1)*sx + float(j-ny-1)*cy)**2   &
                  + (-float(i-1)*cx + float(j-ny-1)*sy)**2
             if (fact.gt.seuil) then
                data(i,j) = 0.0
             else
                data(i,j) = data(i,j)*exp(-fact)*gain
             endif
          enddo
          do i=nx1,nx
             fact = ( float(i-nx-1)*sx + float(j-ny-1)*cy)**2 &
                  + (-float(i-nx-1)*cx + float(j-ny-1)*sy)**2
             if (fact.gt.seuil) then
                data(i,j) = 0.0
             else
                data(i,j) = data(i,j)*exp(-fact)*gain
             endif
          enddo
       enddo
    endif
  end subroutine mulgau
end module mapping_gaussian_tool
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
