subroutine map_polar(line,comm,error)
  use gkernel_interfaces
  use image_def
  !---------------------------------------------------------------------
  ! TASK  
  !   Derive 
  !   1) Polarized fraction
  !   2) Polarization angle
  ! from I,Q,U (and V ?) polarization images
  !
  !---------------------------------------------------------------------
  character(len=*), intent(in) :: line, comm
  logical, intent(inout) :: error  
  !
  real, parameter :: pi=acos(-1.0)
  ! Local
  character(len=filename_length) :: stokes, fich
  integer :: n
  type(gildas) :: hi, hu, hq, hf, ha
  real :: seuil, threshold, pnoise, p2, pa
  integer :: ip, ix, iy
  !------------------------------------------------------------------------
  ! Code:
  call sic_ch(line,0,1,stokes,n,.true.,error)
  if (error) return
  threshold = 2.0
  call sic_r4(line,0,2,threshold,.false.,error)
  if (error) return
  !
  call gildas_null(hi)
  call gildas_null(hu)
  call gildas_null(hq)
  call gildas_null(hf)
  call gildas_null(ha)
  !
  fich = trim(stokes)//'-I'
  call sic_parse_file(fich,' ','.lmv-clean',hi%file)
  fich = trim(stokes)//'-U'
  call sic_parse_file(fich,' ','.lmv-clean',hu%file)
  fich = trim(stokes)//'-Q'
  call sic_parse_file(fich,' ','.lmv-clean',hq%file)
  !
  call gdf_read_header(hi,error)
  if (error) return
  call gdf_read_header(hu,error)
  if (error) return
  call gdf_read_header(hq,error)
  if (error) return
  if (hi%gil%ndim.ne.3) then
    call gdf_trim_header(hi,3,error)
    if (error) return
    call gdf_trim_header(hu,3,error)
    if (error) return
    call gdf_trim_header(hq,3,error)
    if (error) return
  endif
  !
  call gdf_copy_header(hi,hf,error)
  if (error) return
  call gdf_copy_header(hi,ha,error)
  if (error) return
  fich = trim(stokes)//'-P'
  call sic_parse_file(fich,' ','.lmv-clean',hf%file)
  fich = trim(stokes)//'-A'
  call sic_parse_file(fich,' ','.lmv-clean',ha%file)
  !
  call gdf_allocate(hi,error)
  if (error) return
  call gdf_allocate(hu,error)
  if (error) return
  call gdf_allocate(hq,error)
  if (error) return
  call gdf_allocate(hf,error)
  if (error) return
  call gdf_allocate(ha,error)
  if (error) return
  !
  call gdf_read_data(hi,hi%r3d,error)
  if (error) return
  call gdf_read_data(hu,hu%r3d,error)
  if (error) return
  call gdf_read_data(hq,hq%r3d,error)
  if (error) return
  !
  seuil = threshold*max(hi%gil%rms,hi%gil%noise)
  Print *,'Seuil ',seuil,' Noise ',max(hi%gil%rms,hi%gil%noise),' Threshold ',threshold
  !
  pnoise = sqrt(max(hu%gil%noise,hu%gil%rms) * max(hq%gil%noise,hq%gil%rms) )
  pnoise = (2.0*pnoise)**2
  !
  do ip=1,hi%gil%dim(3)
    do iy=1,hi%gil%dim(2)    
      do ix=1,hi%gil%dim(1)
        if (hi%r3d(ix,iy,ip).gt.seuil) then
          p2 = hu%r3d(ix,iy,ip)**2 + hq%r3d(ix,iy,ip)**2
          if (p2.lt.pnoise) then
            hf%r3d(ix,iy,ip) = 0
            ha%r3d(ix,iy,ip) = -2.*pi
          else
            ! Get the fractional polarization
            p2 = sqrt(p2-pnoise)          ! De-bias the polarized intensity
            hf%r3d(ix,iy,ip) = p2/hi%r3d(ix,iy,ip)  ! Go to fraction
            !
            ! Polarization angle is atan(U/Q)/2 in the [0,pi[ domain
            ! see Hull & Plambeck 2015, DOI:10.1142/S2251171715500051
            pa = atan2(hu%r3d(ix,iy,ip),hq%r3d(ix,iy,ip)) 
            if (pa.lt.0) pa = pa+2*pi
            ha%r3d(ix,iy,ip) = 0.5*pa 
          endif
        else
          hf%r3d(ix,iy,ip) = 0
          ha%r3d(ix,iy,ip) = -2.*pi
        endif
      enddo
    enddo
  enddo
  !
  hf%gil%bval = 0.
  hf%gil%eval = 0.
  call cube_minmax('FRACTION',hf,error)
  !
  ha%gil%bval = -2.*pi
  ha%gil%eval = 0.1*pi
  call cube_minmax('ANGLE',ha,error)
  !
  call gdf_write_image(hf,hf%r3d,error)
  if (error) return
  call gdf_write_image(ha,ha%r3d,error)
end subroutine map_polar
