module clean_arrays
  use clean_def
  use image_def
  !
  ! Static variables first, allocatable next.
  !
  type (uvmap_par), save :: themap      ! UV_MAP parameters
  type (clean_par), target :: method, user_method ! CLEAN parameters
  type (gildas), save, target :: hbeam  ! Synthesized beam Header
  type (gildas), save, target :: hdirty ! Dirty image Header
  type (gildas), save, target :: hclean ! Clean image Header
  type (gildas), save, target :: hresid ! Residual image Header
  type (gildas), save, target :: hatten ! Field weights header
  type (gildas), save, target :: hprim  ! Primary beams Header
  type (gildas), save :: hfields        ! Fields Header
  type (gildas), save, target :: hcct   ! Clean component table Header
  type (gildas), save, target :: hmask  ! Mask Header
  type (gildas), save, target :: hsky   ! Sky brightness image Header
  !
  ! Self-calibration headers
  type (gildas), save :: hraw           ! Raw (non self-calibrated) UV header
  type (gildas), save :: hself          ! Self-calibrated UV header
  type (gildas), save :: hagain         ! Antenna-based gain Header
  type (gildas), save :: hbgain         ! Baseline-based gain Header
  !
  ! Short spacings
  type (gildas), save :: hsingle        ! Single Dish Cube or Table
  type (gildas), save :: hshort         ! Short spacing Cube 
  !
  ! These are UV data
  type (gildas), save, target :: huvi   ! Initial UV data Header
  type (gildas), save, target :: huv    ! Current UV data Header 
  type (gildas), save, target :: huvt   ! Transposed UV data Header
  type (gildas), save, target :: huvc   ! Continuum UV data Header
  type (gildas), save :: huvm           ! Model UV data Header
  !
  ! For the Multi-Primary beams Mosaic deconvolution
  ! C_ stands for "Compact Array"
  type (clean_par), target :: c_method, cuse_method
  type (gildas), save :: c_hbeam, c_hdirty, c_hresid, c_hclean
  type (gildas), save :: c_hprim
  !
  real, allocatable, save :: g_weight(:)  ! UV weights
  real, allocatable, save :: g_v(:)       ! V values
  logical, save :: do_weig                ! Optimization of weight computing
  !
  ! Imaging and deconvolution arrays
  real, allocatable, target, save :: dbeam(:,:,:,:)   ! 4-D
  real, allocatable, target, save :: ddirty(:,:,:)    ! Dirty 3-D 
  real, allocatable, target, save :: dclean(:,:,:)    ! Clean 3-D
  real, allocatable, target, save :: dresid(:,:,:)    ! Residual 3-D
  real, allocatable, target, save :: dprim(:,:,:,:)   ! Primary beam 4-D
  real, allocatable, target, save :: datten(:,:,:)    ! Mosaic weights 3-D
  real, allocatable, target, save :: dsky(:,:,:)      ! Primary beam corrected 3-D
  real, allocatable, target, save :: dfields(:,:,:,:) ! Mosaic fields 4-D
  !
  ! Deconvolution arrays
  real, allocatable, target, save :: dmask(:,:,:)     ! Input 3-D 0, #0 mask
  integer, allocatable, target, save :: d_list(:)     ! List of selected pixels
  logical, allocatable, target, save :: d_mask(:,:)   ! Logical mask for pixel selection
  real, allocatable, target, save :: dcct(:,:,:)      ! Clean component values
  type (cct_par), allocatable, save :: tcc(:)         ! Clean component list
  !
  ! These are UV data-like arrays
  real, pointer :: duv(:,:)                        ! Current UV data
  real, allocatable, target, save :: duvi(:,:)     ! Original UV data
  real, pointer :: duvr(:,:)                       ! "Resampled" UV data
  real, pointer :: duvs(:,:)                       ! "Sorted" UV data
  real, allocatable, target, save :: duvc(:,:)     ! Sorted or Unsorted Continuum UV data
  real, allocatable, target, save :: duvt(:,:)     ! Time-Baseline sorted UV data, for UV_FLAG
  real, allocatable, target, save :: duvm(:,:)     ! Model UV data
  real, allocatable, target, save :: duvbg(:,:)    ! Baseline Gains (UV data like)
  real, allocatable, target, save :: duvraw(:,:)   ! Raw UV data for Self calibration
  real, allocatable, target, save :: duvself(:,:)  ! Self calibrated UV data
  real, allocatable, target, save :: dagain(:,:)   ! Antenna based gain
  !
  ! Short spacing data array
  real, allocatable, target, save :: dsingle(:,:,:)   ! Short spacing data (Table or Cube)
  !! real, allocatable, target, save :: dshort(:,:,:)    ! Short spacing 3-D cube
  ! The above one is actually accessible by hshort%r3d only
  !
  ! For the Multi-Primary beams Mosaic deconvolution
  ! C_ stands for "Compact Array"
  real, allocatable, target, save :: c_dbeam(:,:,:)
  real, allocatable, target, save :: c_ddirty(:,:,:)
  real, allocatable, target, save :: c_dclean(:,:,:)
  real, allocatable, target, save :: c_dresid(:,:,:)
  real, allocatable, target, save :: c_dprim(:,:,:)
  logical, allocatable, target, save :: c_mask(:,:)
  integer, allocatable, target, save :: c_list(:)
  real, allocatable, target, save :: c_atten(:,:,:)  ! 3-D
  !
  integer :: niter_listsize=0
  integer, allocatable :: niter_list(:)
  integer :: ares_listsize=0
  real, allocatable :: ares_list(:)
  ! List of selected fields in UV_MAP (used for UV_RESTORE and
  ! also for SHOW FIELDS)
  integer :: selected_fieldsize=0
  integer, allocatable :: selected_fields(:)
end module clean_arrays
!
module moment_arrays
  use image_def
  ! Moment Images
  type(gildas), save :: hpeak, hmean, hvelo, hwidth
  real, allocatable, target, save :: dmean(:,:), dpeak(:,:), dvelo(:,:), dwidth(:,:)
  ! Flux spectra
  integer, target, save :: flux_nf=0
  integer, target, save :: flux_nc=0
  real(4), target, save, allocatable :: flux_velo(:)
  real(8), target, save, allocatable :: flux_freq(:)
  real(4), target, save, allocatable :: flux_values(:,:)
end module moment_arrays
!
module uvsplit_mod
  ! Module for the UV_SPLIT command
  use image_def
  !
  integer, parameter :: opt_chan=1
  integer, parameter :: opt_file=2
  integer, parameter :: opt_freq=3
  integer, parameter :: opt_range=4
  integer, parameter :: opt_velo=5
  integer, parameter :: opt_width=6
  integer, parameter :: opt_zero=7
  !
  character(len=filename_length) :: in_file
  character(len=filename_length) :: ou_file
  !
  type(gildas) :: hiuv
  type(gildas) :: houv
  type(gildas) :: hfuv
  integer :: nblock        ! Blocking factor
  integer :: ncompr        ! Channel compression factor
  logical :: use_file      ! /FILE option
  real :: edge_drop=0.05   ! Fraction of bandwidth dropped at edges for continuum
  !
end module uvsplit_mod
!
module clean_support
  use gkernel_types
  ! CLEAN\SUPPORT polygon, mapped on SUPPORT%
  type(polygon_t), save :: supportpol
  integer, save :: support_type  
  integer, parameter :: support_mask = 1 
  integer, parameter :: support_poly = -1
  integer, parameter :: support_none = 0
  character(len=varname_length), parameter :: supportvar='SUPPORT'
end module clean_support
!
module clean_types
  use gkernel_types
  integer mtype
  parameter(mtype=25)
  character(len=12) :: vtype(1:mtype) = (/ &
  &  'COVERAGE    ',  &
  &  'UV_DATA     ',  &
  &  'BEAM        ',  &
  &  'DIRTY       ',  &
  &  'CLEAN       ',  &
  &  'PRIMARY     ',  &
  &  'RESIDUAL    ',  &
  &  'MASK        ',  &
  &  'SUPPORT     ',  &
  &  'CCT         ',  &
  &  'MODEL       ',  &
  &  'SKY         ',  &
  &  'FIELDS      ',  &
  &  'CGAINS      ',  &
  &  'SELFCAL     ',  &
  &  'SHORT       ',  &
  &  'SINGLEDISH  ',  &
  &  'NOISE       ',  &
  &  'SNR         ',  &     ! NOISE and SNR are special, just for SHOW NOISE  
  &  'MOMENTS     ',  &     ! special, just for SHOW MOMENTS
  &  'COMPOSITE   ',  &     ! special, Moments + Flux on one plot
  &  'FLUX        ',  &     ! special, for SHOW FLUX and WRITE FLUX    
  &  'SOURCES     ',  &     ! special, for SHOW SOURCES
  &  'SPECTRA     ',  &     ! special, for SHOW SPECTRA 
  &  'UV_FIT      ' /)
  !
  character(len=12) :: etype(1:mtype) = (/ &
  & '.uvt        ',  &
  & '.uvt        ',  &
  & '.beam       ',  &
  & '.lmv        ',  &
  & '.lmv-clean  ',  &
  & '.lobe       ',  &
  & '.lmv-res    ',  &
  & '.msk        ',  &
  & '.pol        ',  &
  & '.cct        ',  &
  & '.uvt        ',  &
  & '.lmv-sky    ',  &
  & '.fields     ',  &
  & '.uvt        ',  &      
  & '.tab        ',  &
  & '.lmv-sky    ',  &
  & '.tab        ',  &
  & '            ',  &
  & '            ',  &
  & '            ',  &
  & '            ',  &
  & '.tab        ',  &
  & '            ',  &
  & '            ',  &
  & '.uvfit      '  /)       
  !
  integer, parameter :: mbuffer=27
  character(len=12) :: cbuffer(1:mbuffer) = (/ &
  &  'AGAINS      ',  &
  &  'BEAM        ',  &
  &  'CCT         ',  &
  &  'CGAINS      ',  &
  &  'CLEAN       ',  &
  &  'CLIPPED     ',  &  
  &  'CONTINUUM   ',  &
  &  'DIRTY       ',  &
  &  'EXTRACTED   ',  &
  &  'MASK        ',  &
  &  'M_AREA      ',  &
  &  'M_PEAK      ',  &
  &  'M_VELO      ',  &
  &  'M_WIDTH     ',  &
!  &  'MODEL       ',  &
  &  'PRIMARY     ',  &
  &  'RESIDUAL    ',  &
  &  'WEIGHT      ',  &
  &  'FIELDS      ',  &
  &  'SHORT       ',  &
  &  'SINGLE      ',  &
  &  'SKY         ',  &
  &  'SLICE       ',  &
  &  'SPECTRUM    ',  &
  &  'UV          ',  &
  &  'UV_FIT      ',  &
  &  'UVCONT      ',  &
  &  'UVRADIAL    '  /)  
  character(len=36) :: sbuffer(1:mbuffer) = (/ &
!     123456789 12345678 123456789 12
  &  'Self-Cal Antenna Gains             ',  &
  &  'Synthesized Dirty Beam             ',  &
  &  'Clean Component Table              ',  &
  &  'Self-Calibration Complex Gains     ',  &
  &  'Clean-ed data cube                 ',  &
  &  'Clipped Spectrum from UV_PREVIEW   ',  &  
  &  'Continuum image from MAP_CONTINUUM ',  &
  &  'Dirty Image                        ',  &
  &  'Image extracted by EXTRACT         ',  &
  &  'Current Mask                       ',  &
  &  'Integrated Area from MOMENTS       ',  &
  &  'Peak flux from MOMENTS             ',  &
  &  'Mean Velocity from MOMENTS         ',  &
  &  'Line Width from MOMENTS            ',  &
!  &  'MODEL       ',  &
  &  'Primary Beam                       ',  &
  &  'Residual UV table                  ',  &  
  &  'Mosaic Weight Image                ',  &
  &  'Mosaic Fields                      ',  &
  &  'Short Spacing Image                ',  &
  &  'Single-Dish Data                   ',  &
  &  'Sky Brightness (PB corrected)      ',  &
  &  'Image extracted by SLICE           ',  &
  &  'Initial Spectrum from UV_PREVIEW   ',  &
  &  'UV data                            ',  &
  &  'UV Fit results binary table        ',  &
  &  'Continuum UV data                  ',  &
  &  'Azimutally averaged UV data        '  /)  
  
  character(len=12) ctype
  !
  integer, parameter :: code_save_uv=2
  integer, parameter :: code_save_beam=3
  integer, parameter :: code_save_dirty=4
  integer, parameter :: code_save_clean=5
  integer, parameter :: code_save_primary=6
  integer, parameter :: code_save_resid=7
  integer, parameter :: code_save_mask=8
  integer, parameter :: code_save_support=9
  integer, parameter :: code_save_cct=10
  integer, parameter :: code_save_model=11
  integer, parameter :: code_save_sky=12
  integer, parameter :: code_save_fields=13
  integer, parameter :: code_save_gains=14
  integer, parameter :: code_save_short=15
  integer, parameter :: code_save_single=16
  logical :: save_data(mtype)
  !
  ! Read / Write optimization
  type readop_t
    type(mfile_t) :: modif
    integer :: lastnc(2) = 0
    integer :: change = 0
  end type
  !
  type (readop_t), save :: optimize(mtype)
  !
  integer :: rw_optimize
end module clean_types
!
module clean_default
  use clean_def
  !
  real d_min,d_max                   ! min max of dirty image
  real major_sec
  real minor_sec
  !
  type (uvmap_par), save :: default_map, old_map, save_map
  !
  ! OPEN-MP control parameters
  logical, save :: omp_compiled = .false.
  logical, save :: omp_uvmap = .false.
  integer, save :: omp_grid = 0
  logical, save :: omp_restore_fast = .true.
  logical, save :: omp_uvmap_lock = .false.
  integer, save :: omp_single_beam = 0
  logical, save :: omp_debug = .false.
  !
  ! Parameter to select the imaging tool version. Non zero means old
  ! non-optimized code.
  integer, save :: map_version = 0
  !
  ! Parameters for determining image size
  integer, save :: map_power = 2           ! Max exponent of powers of 3 and 5
  real, save :: map_rounding = 0.05        ! Tolerance for rounding to floor
  !
  logical, save :: MappingError = .false.  ! Error status from scripts
  !
  character(len=16), save :: last_shown    ! CLEAN or DIRTY
  character(len=16), save :: last_resid    ! CCT or UV_FIT
  logical, save :: view_do_loop            ! Interactive mode for VIEW
  !
  integer, save :: sys_ramsize             ! RAM size in MBytes
  !
  real(4), save :: recmap_field(2)
  integer, save :: recmap_size(2)
  real(4), save :: recmap_xycell(2)
  real(4), save :: recmap_uvcell
end module clean_default

module uvfit_data
  ! Support module for command UV_FIT
  use image_def
  integer, parameter :: mpar=70         ! Max number of parameters
  integer, parameter :: mf=10           ! Max number of functions
  integer, parameter :: mpin=7          ! Max number of parameters per function
  real(kind=8) :: pars(mpar)            ! Parameter values
  real(kind=8) :: sw
  real, allocatable :: uvriw(:,:)       ! Work space for visibilities
  integer :: nf                         ! number of functions
  integer :: ifunc(mf)                  ! Function codes
  integer :: npfunc(mf)                 ! number of parameters per function
  logical :: savef(mf)                  ! Subtract function
  integer :: npuvfit                    ! number of points
  integer :: npar                       ! Number of parameters
  integer :: nstart(mpar)               ! Number of starts per parameter
  !
  real(kind=4) :: uvf_results(mpin,mf)  ! Results for each function
  real(kind=4) :: uvf_errors(mpin,mf)   ! Errors 
  !
  type (gildas) :: huvfit               ! Table of fitted parameters
  real, allocatable :: duvfit(:,:)      ! UV_FIT results
end module uvfit_data
!

