module astro_types
  use gildas_def
  use ast_params
  !
  !side band handling
  integer(kind=4), parameter :: m_sideband=2
  integer(kind=4), parameter :: usb_code=1
  integer(kind=4), parameter :: lsb_code=2
  integer(kind=4), parameter :: sb_sign(m_sideband) =  (/ 1, -1/) ! +1 USB/-1 LSB used for tuning
  character(len=16), parameter :: sb_col(m_sideband) =  (/ 'BLUE', 'RED '/) ! USB in blue/ LSB in red
  character(len=3), parameter  :: sideband(m_sideband) = (/ 'USB', 'LSB'/)
  !
  ! Polarisation
  integer(kind=4), parameter :: m_polars=10     !max number of polarizations for a receiver
  integer(kind=4), parameter :: hpol_code=1
  integer(kind=4), parameter :: vpol_code=2
  !
  ! Maximum numbers
  integer(kind=4), parameter :: m_boxes=20      !max number of frequency boxes in a plot page
  integer(kind=4), parameter :: m_tunings=10    !max number of tunings
  integer(kind=4), parameter :: m_rbands=10     !max number of receiver bands in a receiver
  integer(kind=4), parameter :: m_bbands=10     !max number of basebandsbands in a sideband
  integer(kind=4), parameter :: m_ifcables=16   !max number of if transport cable (PICO/EMIR)
  integer(kind=4), parameter :: m_backends=10   !max number of backends for a receiver
  integer(kind=4), parameter :: m_backunits=32  !max number of units for a given backend
  integer(kind=4), parameter :: m_backmodes=10  !max number of units for a given backend
  integer(kind=4), parameter :: m_ch=128        !max number of chunks (fix or flexible)
  integer(kind=4), parameter :: m_chtypes=10    !max number of chunk types
  integer(kind=4), parameter :: m_spw=256       !max number of spectral windows
  integer(kind=4), parameter :: m_res=3         !max number of spectral resolution in a setup
  !
  ! Frequency related
  real(kind=8), parameter :: undef_freq=-1d0
  real(kind=8), parameter :: khzpermhz=1d3
  real(kind=8), parameter :: mhzperkhz=1d0/1d3
  real(kind=8), parameter :: mhzperghz=1d3
  real(kind=8), parameter :: ghzpermhz=1d0/1d3
  real(kind=8), parameter :: toldoppler=1d-10
  !
  ! Plot Configuration
  ! Global colors
  integer(kind=4), parameter  :: idefcol=0
  integer(kind=4), parameter  :: iconfliccol=1
  character(len=16), parameter :: adefcol='BLACK' !
  character(len=16), parameter :: azcol='DARK_RED' !
  character(len=16), parameter :: apolcol='GREEN' !
  character(len=16),parameter :: amolcol='BLACK'
  character(len=16),parameter :: asweepfcol='WEB_PURPLE' ! spec sweep frequency coverage
  !
  ! Plot modes (NOEMA)
  integer(kind=4), parameter :: m_pm=6
  integer(kind=4), parameter :: pm_receiver=1 ! RECEIVER mode (1 box = H/V IF)
  integer(kind=4), parameter :: pm_basebands=2 ! BASEBAND mode (1 box = H/V basebands)
  integer(kind=4), parameter :: pm_proposal=3 ! PROPOSAL mode (1 box with all)
  integer(kind=4), parameter :: pm_allbands=4 ! All bands mode 
  integer(kind=4), parameter :: pm_tunedbands=5 ! Tuned bands mode 
  integer(kind=4), parameter :: pm_zoom=6 ! Zoom mode 
  character(len=*), parameter  :: pm_names(m_pm) =  (/ 'RECEIVER  ','BASEBAND  ','PROPOSAL  ', &
                                                       'ALLBANDS  ','TUNEDBANDS','ZOOM      '/)
  !
  !Frequency axis choices
  integer(kind=4), parameter :: m_freqax=10
  integer(kind=4), parameter :: freqax_rest=1 ! REST
  integer(kind=4), parameter :: freqax_rf=2 ! RF
  integer(kind=4), parameter :: freqax_lsr=3 ! LSR
  integer(kind=4), parameter :: freqax_if1=4 ! IF1
  integer(kind=4), parameter :: freqax_if2=5 ! IF2
  integer(kind=4), parameter :: freqax_chunks=6 ! CHUNKS
  integer(kind=4), parameter :: freqax_imrest=7 ! IMREST
  integer(kind=4), parameter :: freqax_imrf=8 ! IMRF
  integer(kind=4), parameter :: freqax_imlsr=9 ! IMLSR
  integer(kind=4), parameter :: freqax_null=10 ! NULL
  character(len=12), parameter  :: freqax_names(m_freqax) = (/ 'REST  ','RF    ','LSR   ','IF1   ','IF2   ' &
                                                              ,'CHUNKS','IMREST','IMRF  ','IMLSR ','NULL  '/)
  !
  !Conflict/warnings
  character(len=16), parameter  :: aconflictcol='ORANGE' ! fill area + text
  character(len=16), parameter  :: aconflictcolh='CHOCOLATE' ! hatched area
  character(len=16), parameter  :: aconfucol='GREY'
  !Color at receiver level
  character(len=16), parameter :: aoutcol='BLACK' ! out of rec band
  character(len=16), parameter :: aavailcol='DARK_GREY' ! available, not tuned
  character(len=16), parameter :: atunedcol='WHITE' ! tuned
  character(len=16), parameter :: anotselcol='LIGHT_GREY' !
  character(len=16), parameter :: abbifproccol='WEB_PURPLE' !
  character(len=16), parameter :: altunecol='MAGENTA' ! tuned freq
  character(len=16), parameter :: afrepcol='ROYAL_BLUE' ! representative freq
  ! Other global parameters
  real(kind=4), parameter :: ltuneheight=3./4. ! hight of the tuning line indicator
  real(kind=4), parameter :: frepheight=9./16. ! hight of the tuning line indicator
  !
  !Backend
  integer(kind=4), parameter :: m_typecol=3
  integer(kind=4), parameter :: icol_fill=1
  integer(kind=4), parameter :: icol_hatch=2
  integer(kind=4), parameter :: icol_border=3
  character(len=16), parameter  :: ahighrescol='PALE_GREEN'
  character(len=16), parameter  :: ahighrescolh='DARK_GREEN'
  character(len=16), parameter  :: ahighrescolr='LIME_GREEN'
  character(len=16), parameter  :: alowrescol='PAPAYA_WHIP'
  character(len=16), parameter  :: alowrescolh='SANDY_BROWN'
  character(len=16), parameter  :: alowrescolr='SANDY_BROWN'
  character(len=16), parameter  :: a250col='LIGHT_STEEL_BLUE'
  character(len=16), parameter  :: a250colh='LIGHT_SKY_BLUE'
  character(len=16), parameter  :: a250colr='LIGHT_SKY_BLUE'
  character(len=16), parameter  :: achunkcol='WEB_GREY'
  character(len=16), parameter  :: aoverlapcol='SEA_GREEN'
  !
  ! Types
  type :: receiver_desc_t
    ! describe an heterodyne receiver
    character(len=20) :: name                ! name of the receiver
    real(kind=8)      :: iflim(2)              ! IF limits
    real(kind=8)      :: ifband                 ! IF bandwidth
    integer(kind=4)   :: n_rbands               ! number of receiver bands
    character(len=20) :: bandname(m_rbands)     ! name of the Bands
    real(kind=8)      :: rflim(2,m_rbands)     ! limits of the receiver bands --> RF (sky) limits TRUE
    real(kind=8)      :: rfcall(2,m_rbands)     ! limits of the receiver bands --> RF (sky) limits CALL for PROP
    real(kind=8)      :: restlim(2,m_rbands)     ! limits of the receiver bands TRUE --> taking into account current source doppler
    real(kind=8)      :: restcall(2,m_rbands)     ! limits of the receiver bands CALL FOR PROP --> taking into account current source doppler
    real(kind=8)      :: lolim(2,m_rbands)     ! limits of the LO for all the bands (used to check freq)
    real(kind=8)      :: lohard(2,m_rbands)     ! limits of the LO for all the bands ("true" hard limits)
    real(kind=8)      :: locall(2,m_rbands)     ! limits of the LO for all the bands (call for proposal limits)
    real(kind=8)      :: lotol                 ! tolerance beyond the call value
    real(kind=8)      :: rejection(m_rbands)    ! image side band rejection (dB)
    integer(kind=4)   :: n_sbands               ! number of sidebands in output of the receiver
    integer(kind=4)   :: n_polar                ! number of polar in output of the receiver
    integer(kind=4)   :: n_bbands                ! number of basebands in output of the receiver
    real(kind=8)      :: flo2                  ! LO frequency used to downconvert the basebands
    real(kind=8)      :: if1conf(2)           ! confusion zone (in IF1 because not the same in upper and lower)
    real(kind=8)      :: bblim(2,m_bbands)      ! limit of the basebands
    character(len=20) :: bbname(m_bbands)       ! name of the basebands
    real(kind=8)      :: bbref(m_bbands)       ! ref in the basebands
    character(len=20) :: polname(m_polars)       ! name of the polars
    integer(kind=4)   :: n_backends                   !number of associated Backends
    logical           :: tuninggrid             ! use a tuning grid
    real(kind=8)      :: gridbin                ! bins of the tuning grid (in LO) MHz
    real(kind=8)      :: gridtol                ! tolerance around the grid nodes MHz
    logical           :: redshift               ! .true. to take into account source redshift, .false. to ignore it
  end type receiver_desc_t
  !
  type :: receiver_source_t
    integer(kind=4)    :: sourcetype ! source kind to define the source handling
    character(len=3)    :: invtype ! kind of velocity used to define the source
    character(len=sourcename_length) :: name
    character(len=2)   :: coord ! coordinate frame
    real(kind=4)       :: eq ! equinox (in case of ra dec)
    character(len=16)  :: lambda
    character(len=16)  :: beta
    real(kind=8)       :: vdop !doppler + source LSR velocity 
    real(kind=8)       :: vdopmin !doppler + source LSR velocity  min over 1 year
    real(kind=8)       :: vdopmax !doppler + source LSR velocity  max over 1 year
    real(kind=8)       :: vlsr ! source LSR velocity
    logical            :: lsrdefined ! true if LSR actually set
    real(kind=8)       :: z      ! redshift
    real(kind=8)       :: zshift ! freq shift due to redshift
    real(kind=8)       :: dopshift ! freq shift dure to doppler + [source LSR velocity or redshift]
    real(kind=8)       :: dopmin ! min doppler shift
    real(kind=8)       :: dopmax ! max doppler shift
    real(kind=8)       :: lsrshift ! freq shift due source [LSR velocity OR redshift] only (no earth motion)
  end type receiver_source_t
  !
  type :: receiver_comm_t
    ! describe user input of receiver command
    character(len=20)  :: rec_name           ! rec name
    character(len=100) :: name           ! line name
    real(kind=8)       :: frest          ! line rest frequency GHz
    character(len=3)   :: sideband        ! USB/LSB
    real(kind=8)       :: fcent          ! IF frequency where RF Frest is tuned
  end type receiver_comm_t
  !
  type receiver_tune_t
    ! tuning dependent parameters of a receiver
    character(len=40) :: name=''           ! line name
    integer(kind=4)   :: iband          ! Used frequency band
    real(kind=8)      :: flo1=0d0           ! LO1 frequency (including doppler tracking)
    real(kind=8)      :: flo1dmin=0d0           ! LO1 frequency (including min doppler)
    real(kind=8)      :: flo1dmax=0d0          ! LO1 frequency (including max doppler)
    real(kind=8)      :: flotune        ! LO1 frequency (used for tuning on a grid)
    real(kind=8)      :: frest          ! reference rest frequency MHz
    real(kind=8)      :: frf           ! RF (sky) frequency MHz
    real(kind=8)      :: flsr           ! frequency corrected for lsr (no doppler) MHz
    real(kind=8)      :: fcent          ! IF center frequency (where frest is tuned)
    character(len=200) :: label         ! Summary of tuning parameters
    logical           :: outlo          ! to warn when between the call and the wide values
    logical           :: ongrid          ! to indicate whether the current tuning respects the optimized tuning grid
    !sideband related
    integer(kind=4)    :: sb_code       !
  end type receiver_tune_t
  !
  type receiver_t
    integer(kind=4)       :: n_tunings
    type(receiver_desc_t) :: desc
    type(receiver_source_t) :: source
    type(receiver_comm_t) :: comm(m_tunings)
    type(receiver_tune_t) :: tune(m_tunings)
  end type receiver_t
  !
  !
  type emir_comm_t
    !emir command parameters
    integer(kind=4)     :: n_tunings
    real(kind=8)        :: frest(m_tunings) ! GHz
    character(len=2)    :: code(m_tunings)
    character(len=50)     :: zoommode 
    real(kind=8)        :: fz1,fz2
    logical             :: fixed_scale
  end type emir_comm_t
  !
  type emir_setup_t
    !emir setup
    character(len=3):: sb_mode ! sideband connected to backend 2SB or SSB
    integer(kind=4):: sb_code(m_tunings) !
    character(len=10) :: polmode          ! polar connected to backend: DUAL/SINGLE/USER
    character(len=3) :: polar(m_tunings)  ! in single polar, the 2 tunings have different polar
    integer(kind=4)    :: pol_code(m_tunings) ! 1=H or 2=V
  end type emir_setup_t
  !
  type if_cable_t
    character(len=5)    :: label
    integer(kind=4)     :: iband
    integer(kind=4)     :: sb_code
    integer(kind=4)     :: bb_code
    integer(kind=4)     :: pol_code
  end type if_cable_t
  !
  type correlator_input_t
    character(len=20)   :: mode              ! switchbox command mode : AUTO/SINGLE/LIST
    logical             :: defined           ! to know whether it has been configured
    integer(kind=4)     :: m_usercables      ! number of cables defined by the user !for emir
    integer(kind=4)     :: n_ifcables        ! number of if cables
    type(if_cable_t)    :: ifc(m_ifcables)   ! individual if cable descritpion
  end type correlator_input_t
  !
  type emir_t
    type(emir_comm_t) :: comm
    type(emir_setup_t) :: setup
    type(correlator_input_t) :: switch
  end type emir_t
  !
  type if_selection_t
    ! define a subset of if_cables on which the following SPW commands will work
    integer(kind=4)     :: n_ifsel              ! number of if ranges in the present SPW session
    character(len=4)    :: polmode              ! H,V,B to make the difference between single and dual polar cases
    integer(kind=4)      :: usel(m_backunits)    ! index of the selected pfx units
  end type if_selection_t
  !
  type noema_tuning_comm_t
    !recnoema command parameters
    integer(kind=4)     :: n_tunings
    character(len=12)   :: name(m_tunings)
    real(kind=8)        :: frest(m_tunings) ! GHz
    real(kind=8)        :: fcent(m_tunings) ! MHz
    character(len=3)    :: sideband(m_tunings) ! LSB or USB
    character(len=50)   :: zoommode
    real(kind=8)        :: fz1,fz2
    logical             :: fixed_scale
    logical             :: fixedfreq
  end type noema_tuning_comm_t
  !
  type noema_t
!    type(noema_comm_t) :: comm
    type(correlator_input_t) :: ifproc
    type(if_selection_t) :: selunit
  end type noema_t
  !
  type backend_unit_t
  !describe a correlator unit
    integer(kind=4)     :: n_chunks             ! number of chunks
    real(kind=8)        :: ifmin
    real(kind=8)        :: ifmax
    real(kind=8)        :: ifcenter
    real(kind=8)        :: width
    integer(kind=4)     :: iband    ! receiver processed by unit
    integer(kind=4)     :: sb_code   ! sideband processed by unit
    integer(kind=4)     :: bb_code   ! baseband processed by unit
    integer(kind=4)     :: pol_code  ! polar processed by unit
    character(len=5)    :: label        !
  end type backend_unit_t
  !
  type backend_mode_t
    !describe backend mode
    character(len=50)   :: backname             !backend name
    character(len=50)   :: modename             ! mode name
    integer(kind=4)     :: n_backunits          ! number of units (processes 1 baseband)
    real(kind=8)        :: iflim(2,m_bbands)    ! iflim as a function of baseband - order should be the same as taken in rec%desc
    integer(kind=4)     :: m_chunks
    type(backend_unit_t) :: unit(m_backunits)
  end type backend_mode_t
  !
  type backend_t
    character(len=50) :: name
    integer(kind=4) :: n_backmodes
    integer(kind=4) :: imode
    type(backend_mode_t) :: mode(m_backmodes)
  end type backend_t
  !
  type spw_comm_t
    real(kind=4)    :: resol ! in kHz
    integer(kind=4) :: itype
    integer(kind=8) :: time=-1 ! time when the command was typed (to have chronology)
    logical     :: allowconflict ! if true then it is authorized to go on when a conflict occurs 
    real(kind=8) :: fmin
    real(kind=8) :: fmax
    character(len=32) :: user_label=''
  end type spw_comm_t
  !
  type spw_unit_t
    integer(kind=4)     :: iband     ! receiver processed by unit
    integer(kind=4)     :: sb_code   ! sideband processed by unit
    integer(kind=4)     :: bb_code   ! baseband processed by unit
    integer(kind=4)     :: pol_code  ! polar processed by unit
    character(len=5)    :: label        !
    integer(kind=4)     :: itype        ! Correl mode/type used for the SPW
    real(kind=8)  :: restmin       !rest freq
    real(kind=8)  :: restmax       !rest freq
    integer(kind=4) :: ich1
    integer(kind=4) :: ich2
    real(kind=4) :: resol              !kHz
    character(len=32)    :: user_label=''        !
    logical             :: flexible     ! true = tunable, false = fixed
    logical             :: conflict     ! true if 1 of the chunks is used by several spw
    logical             :: overload     ! true if correl unit uses more resource than possible
    logical             :: chunk1     ! true if highres chunk 1 is used
    integer(kind=8)     :: ctime        ! creation time
  end type spw_unit_t
  !
  type spw_output_t
    integer(kind=4) :: n_spw
    type(spw_unit_t) :: win(m_spw)
  end type spw_output_t
  !
  type spw_t
    type(spw_comm_t)      :: comm
    type(spw_output_t)    :: out
  end type spw_t
  !
  type pfx_type_t
    character(len=50)   :: typename
    character(len=16)   :: itypecol(m_typecol)      ! color name (1=filled, 2 =hatched, 3 =border)
    logical(kind=4)     :: move_chunk   !
    integer(kind=4)     :: n_chunks     ! number of existing chunks of this type / unit
    integer(kind=4)     :: use_chunks     ! number of chunks that can be used/ unit
    integer(kind=4)     :: usage ! number of chunks configured
    real(kind=8)        :: df_chunks    ! resolution of chunks
    real(kind=8)        :: width_chunk  ! spacing of the chunks
    real(kind=8)        :: if2ch0      ! first position in grid of chunks
    integer(kind=4)     :: chunks(m_ch) !chunk usage (=0 => unused, >0 => used)
  end type pfx_type_t
  !
  type pfx_mode_t
    !describe a polyfix mode
    character(len=50)   :: backname             ! backend name
    character(len=50)   :: modename             ! mode name
    integer(kind=4)     :: n_types          ! number of type of chunks (e.g. hi and low res = 2)
    type(pfx_type_t)    :: chtype(m_chtypes)
  end type pfx_mode_t
  !
  type pfx_unit_t
    integer(kind=4)     :: iband    ! receiver processed by unit
    integer(kind=4)     :: sb_code   ! sideband processed by unit
    integer(kind=4)     :: bb_code   ! baseband processed by unit
    integer(kind=4)     :: pol_code  ! polar processed by unit
    character(len=5)    :: label     !
    integer(kind=4)     :: n_modes   ! number of existing modes
    integer(kind=4)     :: imode      ! used mode
    type(pfx_mode_t)    :: mode(m_backmodes)
  end type pfx_unit_t
  !
  type pfx_t
    character(len=50) :: name
    real(kind=8)      :: if2lim(2) ! IF2 limits of the signal processed by the unit
    integer(kind=4)   :: n_units
    type(pfx_unit_t)  :: unit(m_backunits)
  end type pfx_t
  !
  ! For spectral sweep tool
  type noema_spsweep_in_t
    logical :: in_range=.false.
    logical :: in_ntune=.false.
    ! Range mode
    real(kind=8) :: restlim(2)=[undef_freq,undef_freq] ! frequency limits in rest
    real(kind=8) :: rflim(2)=[undef_freq,undef_freq] ! frequency limits in rf
    real(kind=8) :: width=undef_freq
    logical :: do_limrange
    ! n tuning mode
    integer(kind=4) :: n_tunings=undef_freq ! integer number of tuning to co
    real(kind=8) :: restref=undef_freq     ! frequency to align the tuning
    real(kind=8) :: rfref=undef_freq     ! frequency to align the tuning, in RF
    character(len=8) :: align='MIN'   ! how to align tuning on ref freq
  end type noema_spsweep_in_t
  !
  type noema_spsweep_param_t
    real(kind=8) :: tuning_width=undef_freq
    real(kind=8) :: if_width=undef_freq !
    real(kind=8) :: couple_width=undef_freq
  end type noema_spsweep_param_t
  !
  type noema_spsweep_out_t  
    integer(kind=4)    :: iband=0             ! band where sweep is done
    type(receiver_source_t) :: srsou
    type(receiver_desc_t)    :: srdesc                 ! receiver type = source, desc, and n_tunings
    type(receiver_tune_t), allocatable :: srtune(:)     ! Tuning: 1 per tuning of the sweep
    type(correlator_input_t), allocatable  :: sifproc(:)  ! IFproc step: 1 per tuning of the sweep
    type(spw_t), allocatable :: sspw(:) ! SPW output: 1 per tuning of the sweep
    type(pfx_t), allocatable :: spfx(:)       ! polyfix output: 1 per tuning
  end type noema_spsweep_out_t
  !
  type noema_spsweep_t
    type(noema_spsweep_in_t) :: in
    type(noema_spsweep_param_t) :: param
    type(noema_spsweep_out_t) :: out
  end type noema_spsweep_t
  !
  type info_pms_t
    ! put together all info to be provided to PMS (plot /proposal)
    ! Related to tuning
    integer(kind=4)     :: tuning_band
    real(kind=8)        :: tuning_freq
    real(kind=8)        :: tuning_flo1
    real(kind=8)        :: tuning_maxrf ! highest rf freq
    real(kind=8)        :: tuning_minrf ! lowest rf freq
    logical             :: tuning_ongrid
    logical             :: tuning_outlo ! true means out of Call for prop limits
    logical             :: redshift
    real(kind=8)        :: lsrlim(m_sideband,2)  ! lsb min, lsb max, usb min, usb max limits in LSR (for Tsys comparison)
    ! Related to backend
    ! - LSR/Redshift range
    real(kind=8)        :: lsrrange
    real(kind=8)        :: zrange
    ! Usage
    integer(kind=4)     :: mflex ! total number of flexible chunks available (all units merged)
    integer(kind=4)     :: nflex ! total number of flexible chunks used (all units merged)
    ! - Representative frequency
    real(kind=8)        :: frep                 !rest frame
    real(kind=8)        :: freplsr               ! representative freq in LSR frame (for Tsys and sensitivity)
    real(kind=8)        :: resrep                ! user input spectral resolution
    integer(kind=4)     :: npolrep                ! nb of polar with user input spectral resolution
    integer(kind=4)     :: nspw
    integer(kind=4)     :: nresol              ! number of different spectral resolution covering the repr. freq
    real(kind=8)        :: resol(m_chtypes)     ! resolutions covering the repr. freq
    integer(kind=4)     :: npol(m_chtypes)      ! numb of polarization covering the repr. freq (in each resolution)
    ! Continuum Part
    real(kind=8)        :: fcont                ! representative frequency for continuum (REST FRAME)
    real(kind=8)        :: fcontlsr             ! representative frequency for continuum (LSR frame)
#if defined(GAG_OMS)
    real(kind=8)        :: fcontw20             ! representative frequency for continuum (LSR frame) - special semester W20
#endif
    real(kind=8)        :: dfcont               ! total bandwidth covered
    real(kind=8)        :: rescont              ! Channel spacing (lowest resolution for information only in PMS)
    integer(kind=4)     :: npolcont             ! number of polarization in continuum mode
    !Tracksharing case
    logical             :: tracksharing 
    real(kind=8)        :: tsdf(2)              ! offset in frequency for Sources with values Vmin and Vmax
    logical             :: ts_freqout           ! true if 1 of the frequency gets out of range
  end type info_pms_t
  !
  type draw_axis_t
    character(len=3)    :: pos          ! UP or LOW
    character(len=4)    :: tick='IN'     ! I O N
    character(len=1)    :: label='P'    !  P O N
    character(len=16)   :: aboxcol='BLACK'
    character(len=16)   :: alabcol='BLACK'
  end type draw_axis_t
  !
  type frequency_box_phys_t
    ! Physical description of a box
    real(kind=8)        :: xmin          ! x left position
    real(kind=8)        :: xmax          ! x right position
    real(kind=8)        :: ymin          ! y lower position
    real(kind=8)        :: ymax          ! y upper position
    real(kind=8)        :: sx           ! x size
    real(kind=8)        :: sy           ! y size
  end type frequency_box_phys_t
  !
  type frequency_box_user_t
    ! user defined parameters of a box
    real(kind=8)        :: xmin          ! x left limit
    real(kind=8)        :: xmax          ! x right limit
    real(kind=8)        :: ymin=0        ! y lower limit
    real(kind=8)        :: ymax=5        ! y upper limit
    character(len=50)   :: name=''       ! name of the Axis
    character(len=3)   :: unit='MHz'     ! unit
    logical :: defined=.false.           ! to check before drawing
  end type frequency_box_user_t
  !
  type frequency_box_t
    !global structure that characterize a box : physical coordinates + all frequency axis
    integer(kind=4)                  :: bb_code
    integer(kind=4)                  :: sb_code
    integer(kind=4)                  :: iband
    type(frequency_box_phys_t)       :: phys
    type(frequency_box_user_t)       :: rest            ! freq in the frame of the source
    type(frequency_box_user_t)       :: lsr             ! freq corrected for LSR or Redshift (no earth)
    type(frequency_box_user_t)       :: rf             ! freq corrected for LSR or Redshift + earth
    type(frequency_box_user_t)       :: imrest
    type(frequency_box_user_t)       :: imrf
    type(frequency_box_user_t)       :: imlsr
    type(frequency_box_user_t)       :: if1
    type(frequency_box_user_t)       :: if2
    type(frequency_box_user_t)       :: chunks
  end type frequency_box_t
  !
  type current_boxes_desc_t
    integer(kind=4)   :: plotmode  ! according to plotmodes defined above
    real(kind=4)      :: defchar   
    real(kind=4)      :: smallchar
    real(kind=4)      :: molchar
  end type  current_boxes_desc_t
  !
  type current_boxes_t
    ! current state of the plot pages - nbox boxes described by frequency_box_t(nbox)
    integer(kind=4) :: nbox=0
    type(current_boxes_desc_t) :: desc
    type(frequency_box_t) :: box(m_boxes)
  end type current_boxes_t
  !
  type draw_mark_t
    !parameters needed to draw a line
    real(kind=8)        :: x    ! x positions
    real(kind=8)        :: y    ! y positions
    character(len=16)   :: ref       ! reference for coordinates (USER,PHYSICAl,BOX,CHARACTER)
    integer(kind=4)   :: iref       ! iref (for box and character)
    integer(kind=4)     :: nside=0        ! number of sides of the marker
    integer(kind=4)     :: style=0        ! follows g\set mark
    real(kind=4)     :: s=0.5            ! size in physical units
    character(len=16)   :: col='BLACK'  ! pen color
    logical             :: clip=.false.
  end type draw_mark_t
  !
  type draw_line_t
    !parameters needed to draw a line
    real(kind=8)        :: xmin,xmax    ! x positions
    real(kind=8)        :: ymin,ymax    ! y positions
    character(len=16)   :: col='BLACK'  ! pen color
    integer(kind=4)     :: dash=1       ! pen dash
  end type draw_line_t
  !
  type draw_interbox_line_t
    !parameters needed to draw a line between 2 boxes
    integer(kind=4)     :: ibox(2)      ! boxes
    real(kind=8)        :: xpos(2)      ! x position
    real(kind=8)        :: ypos(2)      ! y positions
    character(len=16)   :: frame(2)     ! frame for values
    character(len=16)   :: col='BLACK'  ! pen color
    integer(kind=4)     :: dash=1       ! pen dash
  end type draw_interbox_line_t
  !
  type draw_rect_t
    !parameters needed to draw a rectangle
    real(kind=8)        :: xmin,xmax    ! x positions
    real(kind=8)        :: ymin,ymax    ! y positions
    character(len=16)     :: col='BLACK'   ! pen color
    integer(kind=4)     :: dash=1          ! pen dash
  end type draw_rect_t
  !
  type draw_gauss_t
    !parameters needed to draw a guassian
    real(kind=8)        :: xcent    ! x position
    real(kind=8)        :: fwhm    ! fwhm
    real(kind=8)        :: ymin,ymax    ! y positions
    character(len=16)   :: col='BLACK'          ! pen color
    integer(kind=4)     :: dash=1          ! pen dash
  end type draw_gauss_t
  !
  type plot_molecules_t
    ! Describes the global behavior for plotting molecular lines
    character(len=filename_length) :: catalog='' ! Name of the catalog. Default is GILDAS one.
    logical            :: doplot=.False.          ! Plot the lines ?
    character(len=12)  :: profile="BOXCAR"        ! Profile of the lines to plot
    real(kind=8)       :: width=0d0               ! Width of the lines to plot [MHz]
  end type plot_molecules_t
  !
  type frequency_axis_t
    ! Describes the global frequency axis used (for NOEMA and EMIR frequency coverages)
    character(len=16)  :: main='REST'        ! lower axis of plots + commands
    character(len=16)  :: second='NULL'        ! upper axis of plots
  end type frequency_axis_t
  !
  type astro_noemareceiver_t
    ! plot pfx configuration from outside ASTRO (CLIC/OBS)
    ! receiver/source part
    real(kind=8) :: flo1 ! frequency of the tuning
    real(kind=8) :: fcent ! MHZ IF1
    integer(kind=4) :: sbcode ! USB or LSB
    character(len=12) :: tuningname ! tuning name
    character(len=12) :: sourcename ! sourcename
    real(kind=8) :: obsdoppler ! current doppler
  end type astro_noemareceiver_t
  !
  type astro_noemaspw_t
    ! plot pfx configuration from outside ASTRO (CLIC/OBS)
    ! spw part
    integer(kind=4) :: n_spw=0 ! number of defined spw
    integer(kind=4) :: chunkmin(m_spw) ! first chunk of spw
    integer(kind=4) :: chunkmax(m_spw) ! last chunk of spw
    real(kind=8) :: resol(m_spw) ! spectral resolution
    character(len=5) :: label(m_spw) ! format: B1HUO,B2HUI,...
    character(len=32) :: user_label(m_spw) ! spw name as stated by user
    integer(kind=4) :: corrmode(m_spw) ! correlator mode
  end type astro_noemaspw_t
  !
  type astro_noemasetup_t
    ! plot pfx configuration from outside ASTRO (CLIC/OBS)
!     character(len=4)  :: mode ! CLIC or OBS ! could set defaults for computations/visualization ?
    type(astro_noemareceiver_t) :: rec
    type(astro_noemaspw_t) :: spw
  end type astro_noemasetup_t
  !
end module astro_types
!
module string_parser_types
  !
  ! Support module for "string parser". See string-parser.f90 for details.
  !
  integer(kind=4), parameter :: substring_parser_mval=4
  integer(kind=4), parameter :: substring_parser_mchar=2
  type :: substring_parser_t
    integer(kind=4) :: nval
    character(len=substring_parser_mchar) :: val(substring_parser_mval)
  end type substring_parser_t
  !
  integer(kind=4), parameter :: string_parser_msub=4
  type :: string_parser_t
    logical :: active(string_parser_msub) = .false.
    type(substring_parser_t) :: substring(string_parser_msub)
  end type string_parser_t
  !
end module string_parser_types
!
module plot_molecules_globals
  use astro_types
  !
  type(plot_molecules_t), save :: molecules
  !
end module plot_molecules_globals
!
module frequency_axis_globals
  use astro_types
  !
  type(frequency_axis_t), save :: freq_axis
  !
end module frequency_axis_globals
!
!
module my_receiver_globals
  use astro_types
  !
  type(receiver_t), save      :: rec            ! receiver global
  type(emir_t), save          :: emir           ! emir global
  type(noema_tuning_comm_t), save         :: noematune          ! noema tuning command
  type(noema_t), save         :: noema          ! noema backend global
  type(backend_t), save       :: be(m_backends) ! backends
  type(pfx_t), save           :: pfx            ! polyfix backend
  type(spw_t), save           :: spw            ! spw collection (defined by polyfix settings)
  type(spw_t), save           :: spw2            ! spw collection 2nd list (when comparison are done)
  type(current_boxes_t), save :: cplot          ! current plot
  !
end module my_receiver_globals
