subroutine write_sdm_ConfigDescription(holodata, tpOnly, error)
  !---------------------------------------------------------------------
  ! Write the ConfigDescription SDM table.
  !---------------------------------------------------------------------
  use gildas_def
  use sdm_configDescription
  use sdm_enumerations
  ! Global variables:
  include 'clic_parameter.inc'
  include 'clic_par.inc'
  include 'clic_dheader.inc'
  include 'clic_constant.inc'
  include 'gbl_memory.inc'
  include 'sdm_identifiers.inc'
  ! Dummy
  logical :: holodata, tpOnly, error
  ! Local
  ! Three Rows, spectral, continuum, totalpower
  type (ConfigDescriptionKey) :: cdKey(3)
  type (ConfigDescriptionRow) :: cdRow(3)
  type (ConfigDescriptionOpt) :: cdOpt
  integer, parameter :: mdd=mrlband*msideband*2
  integer :: ier, i, k, ia, isb, ilc, ic, ivc, ContDdListDim,   &
    numPhasedArrayList, numSwitchCycle(3), numNumSubBand,   &
    numDataDescription(3), irow, iautosb, numApc
  character, parameter  :: sdmTable*20='ConfigDescription'
  !---------------------------------------------------------------------
  call sdmMessage(1,1,sdmTable ,'starting...')
  !
  !     Normal case (correlator data).
  !
  if (.not. holodata) then
    if (r_lmode.eq.1) then     ! correlation
      numDataDescription(1) = v_lband*r_lnsb
      numDataDescription(2) = v_lband*r_lnsb
    elseif (r_lmode.eq.2) then ! Autocorrelation
      numDataDescription(1) = v_lband*1
      numDataDescription(2) = v_lband*1
    endif
    numDataDescription(3) = 1
    numPhasedArrayList = 1
    !     the numSwitchCycle should be equal to the number of basebands
    !     no now this is the number of data description
    !         numSwitchCycle = numDataDescription
    numNumSubBand = r_lnsb
    ! check which side band to define for autocorrelations.
    if (r_isb .eq.1) then
      iautosb = 1
    else
      iautosb = 2
    endif
    do irow = 1, 3
      if (numDataDescription(irow).gt.0) then
        cdRow(irow)%numAntenna = r_nant
        cdRow(irow)%numFeed = 1
        !
        ! atm phase corrections...
        if ( irow.eq.1) then   ! line
          if (r_ndatl.eq.0) then
            numApc = 1
            else if (r_ndatl.eq.1) then
            numApc = 1
            else if (r_ndatl.eq.2) then
            numApc = 2
          endif
        else
          numApc = 1
        endif
        cdRow(irow)%numDataDescription = numDataDescription(irow)
        cdRow(irow)%numAtmPhaseCorrection = numApc
        call allocConfigDescriptionRow(cdRow(irow), error)
        if (error) return
        !
        !     internal: corr_num = number of results, corr_modes = results, with
        !     1 corr, 2 for auto.
        !
        if (r_lmode.eq.1) then ! correlation
          cdRow(irow)%correlationMode =   &
            CorrelationMode_CROSS_ONLY
        elseif (r_lmode.eq.2) then ! auto correlation only
          cdRow(irow)%correlationMode =   &
            CorrelationMode_AUTO_ONLY
        elseif (r_lmode.eq.3) then ! auto correlation and correlation (some day),
          !  ... or ALMA data
          cdRow(irow)%correlationMode =   &
            CorrelationMode_CROSS_AND_AUTO
        endif
       do ia = 1, r_nant
          cdRow(irow)%antennaId(ia) = Antenna_Id(ia)
          !     may be put actual flag info there?
          cdRow(irow)%feedId(ia)  = 0
        enddo
        do i=1, numDataDescription(irow)
          cdRow(irow)%switchCycleId(i) = switchCycle_Id
        enddo
        !
        !     This is the configuration with both channel averages and spectra.
        !     loop on cont/line subbands, spectral  subbands (=basebands), basebands
        !
        !     The order is supposed to match the one in the binary header file
        !     (where every thing is grouped by baseband)
        !
        !     keep the indices in dd_isb, dd_ilc, dd_ic so that the binaries are
        !     in the right order.
        if (irow.eq.1) then
          i = 0
          ilc = 2
          cdRow(irow)%spectralType = SpectralResolutionType_FULL_RESOLUTION
          cdRow(irow)%processorType = ProcessorType_CORRELATOR 
          do ivc = 1, v_lband
            if (r_lmode.eq.1) then ! correlation
              do isb = 1, r_lnsb
                i = i+1
                cdRow(irow)%dataDescriptionId(i) =   &
                  DataDescription_Id(isb, ivc, ilc)
                cont_list(i) = .false. !! ilc.eq.1
              enddo
              if (r_ndatl.eq.0) then
                cdRow(irow)%atmPhaseCorrection   &
                  =AtmPhaseCorrection_AP_UNCORRECTED
                else if (r_ndatl.eq.1) then
                cdRow(irow)%atmPhaseCorrection   &
                  =AtmPhaseCorrection_AP_CORRECTED
                else if (r_ndatl.eq.2) then
                cdRow(irow)%atmPhaseCorrection =(/   &
                  AtmPhaseCorrection_AP_UNCORRECTED   &
                  ,AtmPhaseCorrection_AP_CORRECTED/)
              end if
            !     if autocorrelation, only one sideband...
            elseif (r_lmode.eq.2) then ! auto correlation only
              i = i+1
              !!! check which one!
              isb = iautosb
              cdRow(irow)%dataDescriptionId(i) =   &
                DataDescription_Id(isb, ivc, ilc)
              cdRow(irow)%atmPhaseCorrection   &
                =AtmPhaseCorrection_AP_UNCORRECTED
            endif
          enddo
          cdRow(irow)%processorId = processor_Id
        elseif (irow.eq.2) then
          ilc = 1
          cdRow(irow)%spectralType = SpectralResolutionType_CHANNEL_AVERAGE
          cdRow(irow)%processorType = ProcessorType_CORRELATOR 
          i = 0
          !                  do ic = 1, r_lband
          do ivc = 1, v_lband
            if (r_lmode.eq.1) then ! correlation
              do isb = 1, r_lnsb
                i = i+1
                cdRow(irow)%dataDescriptionId(i) =   &
                  DataDescription_Id(isb, ivc, ilc)
              enddo
            !     if autocorrelation, only one sideband...
            elseif (r_lmode.eq.2) then ! auto correlation only
              i = i+1
              isb = iautosb
              cdRow(irow)%dataDescriptionId(i) =   &
                DataDescription_Id(isb, ivc, ilc)
            endif
          enddo
          cdRow(irow)%processorId = processor_Id
          cdRow(irow)%atmPhaseCorrection =   &
            AtmPhaseCorrection_AP_UNCORRECTED
        else
          cdRow(irow)%spectralType = SpectralResolutionType_BASEBAND_WIDE
          cdRow(irow)%processorType = ProcessorType_RADIOMETER 
          cdRow(irow)%dataDescriptionId(1) =   &
            TotPowDataDescription_Id
          !!cdRow(irow)%numSubBand = 1
          cdRow(irow)%correlationMode = 1
          cdRow(irow)%processorId = totPowProcessor_Id
          cdRow(irow)%atmPhaseCorrection =   &
            AtmPhaseCorrection_AP_UNCORRECTED
        endif
        !
        call addConfigDescriptionRow(cdKey(irow), cdRow(irow),   &
          error)
        if (error) return
        if (irow.eq.1) then
          configDescription_Id = cdKey(irow)%configDescriptionId
        elseif (irow.eq.2) then
          contconfigDescription_Id = cdKey(irow   &
            )%configDescriptionId
        else
          TotPowConfigDescription_Id = cdKey(irow   &
            )%configDescriptionId
        endif
      else
        if (irow.eq.1) then
          configDescription_Id = -1
        elseif (irow.eq.2) then
          contConfigDescription_Id = -1
        endif
      endif
    enddo
    !
    ! New: add the associations
    ! this should be more exact. we may add meaningless data there in some cases...
    if (.not. tpOnly) then
!!!       call allocConfigDescriptionOpt(cdRow(1), cdOpt, cdRow(1)%numAntenna,   &
!!!         error)
      cdOpt%numAssocValues = 2
      call allocConfigDescriptionOpt(cdRow(1), cdOpt, error)
      if (configDescription_Id.ge.0) then
        cdOpt%assocConfigDescriptionId(1) =   &
          contConfigDescription_Id
        cdOpt%assocNature(1) =   &
          SpectralResolutionType_CHANNEL_AVERAGE
        cdOpt%assocConfigDescriptionId(2) =   &
          TotPowConfigDescription_Id
        cdOpt%assocNature(2) =   &
          SpectralResolutionType_BASEBAND_WIDE
        call addConfigDescriptionAssocConfigDescriptionId(cdKey(1   &
          ),cdOpt, error)
        call addConfigDescriptionAssocNature(cdKey(1),   &
          cdOpt, error)
        call addConfigDescriptionNumAssocValues(cdKey(1),   &
          cdOpt, error)
      endif
      if (contConfigDescription_Id.ge.0) then
        cdOpt%assocConfigDescriptionId(1) = ConfigDescription_Id
        cdOpt%assocNature(1) =   &
          SpectralResolutionType_FULL_RESOLUTION
        cdOpt%assocConfigDescriptionId(2) =   &
          TotPowConfigDescription_Id
        cdOpt%assocNature(2) =   &
          SpectralResolutionType_BASEBAND_WIDE
        call addConfigDescriptionAssocConfigDescriptionId(cdKey(2   &
          ),cdOpt, error)
        call addConfigDescriptionAssocNature(cdKey(2),   &
             cdOpt, error)
        call addConfigDescriptionNumAssocValues(cdKey(2),   &
          cdOpt, error)
      endif
      irow = 0
      if (configDescription_Id.ge.0) then
        irow = irow+1
        cdOpt%assocConfigDescriptionId(irow) =   &
          ConfigDescription_Id
        cdOpt%assocNature(irow) =   &
          SpectralResolutionType_FULL_RESOLUTION
      endif
      if (contconfigDescription_Id.ge.0) then
        irow = irow+1
        cdOpt%assocConfigDescriptionId(irow) =   &
          contConfigDescription_Id
        cdOpt%assocNature(irow) =   &
          SpectralResolutionType_CHANNEL_AVERAGE
      endif
      if (irow.gt.0) then
        call addConfigDescriptionAssocConfigDescriptionId(cdKey(3   &
          ),cdOpt, error)
        call addConfigDescriptionAssocNature(cdKey(3),   &
          cdOpt, error)
        call addConfigDescriptionNumAssocValues(cdKey(3),   &
          cdOpt, error)
      endif
    endif
  !
  !     Special case for Holography data:
  !
  else
    !
    !     There is a single data description and a single spectral window.
    numDataDescription(1) = 1
    numPhasedArrayList = 1
    !     the numSwitchCycle should be equal to the number of basebands
    numSwitchCycle = 1
    numNumSubBand = 1
    ! check which side band to define for autocorrelations.
    if (r_isb .eq.1) then
      iautosb = 1
    else
      iautosb = 2
    endif
    irow = 1
    cdRow(irow)%numAntenna = r_nant
    cdRow(irow)%numFeed = 1
    cdRow(irow)%numDataDescription = 1
    cdRow(irow)%numAtmPhaseCorrection = 1
    numApc = 1
    !$$$         call allocConfigDescriptionRow(cdRow(irow), cdRow(irow)
    !$$$     &        %numAntenna, numDataDescription(irow), cdRow(irow)
    !$$$     &        %numFeed, numPhasedArrayList, numSwitchCycle,
    !$$$     &        numNumSubBand , numApc, error)
!!!     call allocConfigDescriptionRow(cdRow(irow), cdRow(irow)   &
!!!       %numAntenna, numDataDescription(irow), cdRow(irow)   &
!!!       %numFeed, numPhasedArrayList, numNumSubBand , numApc,   &
!!!       error)
    call allocConfigDescriptionRow(cdRow(irow), error)
    if (error) return
    !
    !     one SubBand for line, one for continuum ...
    !! cdRow(irow)%numSubBand(1)  =  1
    !
    !     *TBD* The correlatio-only mode is not assumed to be present for
    !     ALMA !
    !
    !     internal: corr_num = number of results, corr_modes = results, with
    !     1 corr, 2 for auto.
    !
    cdRow(irow)%atmPhaseCorrection = AtmPhaseCorrection_AP_UNCORRECTED
    cdRow(irow)%correlationMode = 0
    do ia = 1, r_nant
      cdRow(irow)%antennaId(ia) = Antenna_Id(ia)
      !     may be put actual flag info there?
      ! OPTIONAL IN SS2 ...            cdRow(irow)%flagAntenna(ia) = .false.
      cdRow(irow)%feedId(ia)  = 0
    enddo
    cdRow(irow)%atmPhaseCorrection =   &
      AtmPhaseCorrection_AP_UNCORRECTED
    do i=1, r_lband
      cdRow(irow)%switchCycleId(i) = switchCycle_Id
    enddo
    !
    cdRow(irow)%dataDescriptionId(1) =   &
      TotPowDataDescription_Id
    !$$$         sb_list(1) = isb
    !$$$         bb_list(1) = ic
    !$$$         cont_list(1) = .false. !! ilc.eq.1
    cdRow(irow)%processorId = totPowProcessor_Id
    !
    call addConfigDescriptionRow(cdKey(1), cdRow(irow), error)
    if (error) return
    configDescription_Id = cdKey(1)%configDescriptionId
  endif
  call sdmMessage(1,1,sdmTable ,'Written.')
  return
!
end subroutine write_sdm_ConfigDescription
!---------------------------------------------------------------------
subroutine get_sdm_ConfigDescriptionModes(nmodes,modes,   &
    assocFullResolutionID, assocBasebandWideID,   &
    assocChannelAverageID, error)
  !---------------------------------------------------------------------
  !     Get the ConfigDescription SDM table: as a first pass we get only
  !     the number of clic r_modes (auto/cross)
  !---------------------------------------------------------------------
  use gildas_def
  use sdm_configDescription
  use sdm_enumerations
  ! Global variables:
  include 'clic_parameter.inc'
  include 'clic_par.inc'
  include 'clic_dheader.inc'
  include 'clic_constant.inc'
  include 'gbl_memory.inc'
  include 'sdm_identifiers.inc'
  ! Dummy
  integer :: nmodes, modes(2), assocFullResolutionID,   &
    assocBasebandWideID, assocChannelAverageID
  logical error
  ! Local
  type (ConfigDescriptionKey) :: cdKey
  type (ConfigDescriptionRow) :: cdRow
  type (ConfigDescriptionOpt) :: cdOpt
  !      integer :: ier, ia, isb, ilc, ic, i
  logical::  present
  integer :: k
  integer, parameter :: mapc=2
  character, parameter :: sdmTable*24='ConfigDescription(Modes)'
  !---------------------------------------------------------------------
  call sdmMessage(1,1,sdmTable ,'starting...')
  cdRow%numAntenna = mnant
  cdRow%numFeed = 1
  cdRow%numDataDescription = mrlband
  cdRow%numAtmPhaseCorrection = mapc
  call allocConfigDescriptionRow(cdRow, error)
  if (error) return
  cdOpt%numAssocValues = 1
  call allocConfigDescriptionOpt(cdRow, cdOpt, error)
  if (error) return
  cdKey%configDescriptionId = configDescription_Id
  call getConfigDescriptionRow(cdKey, cdRow, error)
  if (error) then
    print *, '!! cdKey%configDescriptionId = '   &
      ,cdKey%configDescriptionId, '  !!'
  endif
  if (error) return
  if (cdRow%correlationMode.eq.CorrelationMode_CROSS_ONLY) then
    nmodes = 1
    modes = 1
  elseif (cdRow%correlationMode.eq.CorrelationMode_AUTO_ONLY) then
    nmodes = 1
    modes = 2
  else
    nmodes = 2
    modes = (/ 1, 2 /)
  endif
  processor_Id = cdRow%processorId
  ! return three possible associations (two only may be there).
  assocFullResolutionID = -1
  assocBasebandWideID = -1
  assocChannelAverageID = -1
  call getConfigDescriptionNumAssocValues(cdKey, cdOpt, present, error)
  if (present) then
    call getConfigDescriptionAssocConfigDescriptionId(cdKey, cdOpt,   &
    present, error)
    call getConfigDescriptionAssocNature(cdKey, cdOpt, present, error)
    !print *, present, cdOpt%AssocNature
    !! This is a patch as in is omitted in 6.1.0 asdms.
    if (.not.present) then
      do k=1, cdOpt%numAssocValues
        cdOpt%AssocNature(k) = SpectralResolutionType_CHANNEL_AVERAGE
      enddo
    endif
    do k=1, cdOpt%numAssocValues
      select case(cdOpt%AssocNature(k))
      case(SpectralResolutionType_FULL_RESOLUTION)
        assocFullResolutionID =  cdOpt%AssocConfigDescriptionId(k)
      case(SpectralResolutionType_BASEBAND_WIDE)
        assocBasebandWideID =  cdOpt%AssocConfigDescriptionId(k)
      case(SpectralResolutionType_CHANNEL_AVERAGE)
        assocChannelAverageID = cdOpt%AssocConfigDescriptionId(k)
      end select
    enddo
  endif
  call sdmMessage(1,1,sdmTable ,'Read.')
  return
  !
99 error = .true.
end subroutine get_sdm_ConfigDescriptionModes
!---------------------------------------------------------------------
subroutine get_sdm_ConfigDescription(error)
  !---------------------------------------------------------------------
  ! Get the ConfigDescription SDM table.
  !---------------------------------------------------------------------
  use gildas_def
  use sdm_configDescription
  use sdm_enumerations
  ! Global variables:
  include 'clic_parameter.inc'
  include 'clic_par.inc'
  include 'clic_dheader.inc'
  include 'clic_constant.inc'
  include 'gbl_memory.inc'
  include 'sdm_identifiers.inc'
  ! Dummy
  logical error
  ! Local
  type (ConfigDescriptionKey) :: cdKey
  type (ConfigDescriptionRow) :: cdRow
  integer :: ier, ia, isb, ilc, ic, i
  integer, parameter :: mapc=2
  character, parameter :: sdmTable*20='ConfigDescription'
  !---------------------------------------------------------------------
  call sdmMessage(1,1,sdmTable ,'starting...')
  cdRow%numAntenna = mnant
  cdRow%numFeed = 1
  cdRow%numDataDescription = mrlband
  cdRow%numAtmPhaseCorrection = mapc
  call allocConfigDescriptionRow(cdRow, error)
  if (error) return
  !
  do i=1, cdRow%numDataDescription
    cdRow%dataDescriptionId(i) = -1
  enddo
  cdRow%atmPhaseCorrection = -1
  cdKey%configDescriptionId = configDescription_Id
  call getConfigDescriptionRow(cdKey, cdRow, error)
  if (error) then
    print *, '!! cdKey%configDescriptionId = '   &
         ,cdKey%configDescriptionId, '  !!  '
  endif
  if (error) return
  processor_Id = cdRow%processorId
  switchCycle_Id = cdRow%switchCycleId(1)
  if (r_nant.le.0) then
    r_nant = cdRow%numAntenna
  elseif ( cdRow%numAntenna.ne.r_nant) then
    call sdmMessageI(8,3,sdmTable, 'Wrong numAntenna '   &
      ,cdRow%numAntenna)
    goto 99
  endif
  if (cdRow%numFeed.gt.1) then
    call sdmMessageI(8,2,sdmTable, 'Wrong numFeed (for CLIC) '   &
      ,cdRow%numFeed)
  endif
  do i = 1, r_nant
    antenna_Id(i) = cdRow%antennaId(i)
  enddo
  ddId_size = 0
  do i = 1,  cdRow%numDataDescription
    if (cdRow%dataDescriptionId(i).ge.0) then
      ddId_size = ddId_size+1
      ddId_List(ddId_size) = cdRow%dataDescriptionId(i)
    endif
  enddo
  !!print *, 'cdRow%correlationMode, CorrelationMode_CROSS_ONLY ', & 
  !!     cdRow%correlationMode, CorrelationMode_CROSS_ONLY
  if ((cdRow%correlationMode.eq.CorrelationMode_CROSS_ONLY .and. r_lmode.ne.1) .or.   &
    (cdRow%correlationMode.eq.CorrelationMode_AUTO_ONLY .and. r_lmode.ne.2)) then
    call sdmMessageI(6,2,sdmTable,   &
      'Wrong correlationMode (for CLIC) ',cdRow%correlationMode)
    call sdmMessage(6,2,sdmTable,'Programming error?')
    if (cdRow%correlationMode.eq.CorrelationMode_CROSS_ONLY)  r_lmode=1
    if (cdRow%correlationMode.eq.CorrelationMode_AUTO_ONLY)  r_lmode=2
  endif
  ! TODO get actual flags from flagAntenna
  !     do ia = 1, r_nant
  !         phasedArrayList(ia) = -1
  !         flagAntenna(ia) = .false. ! may be put actual flag info there?
  !         feedList(ia)  = 0
  !      enddo
  if (cdRow%numAtmPhaseCorrection.ge.1) then
    r_ndatl = 2
  elseif (cdRow%atmPhaseCorrection(1).eq.   &
    AtmPhaseCorrection_AP_CORRECTED) then
    r_ndatl = max(r_ndatl,1)
  elseif (cdRow%atmPhaseCorrection(1).eq.   &
    AtmPhaseCorrection_AP_UNCORRECTED) then
    r_ndatl = max(r_ndatl,1)
  else
    call sdmMessageI(8,3,sdmTable,   &
      'Wrong atmPhaseCorrection (for CLIC) ',   &
      cdRow%atmPhaseCorrection)
    goto 99
  endif
  !$$$      print *, ddId_size, ' data description Ids ', (ddId_List(i), i=1,
  !$$$     &     ddId_size)
  call sdmMessage(1,1,sdmTable ,'Read.')
  return
  !
99 error = .true.
end subroutine get_sdm_ConfigDescription
