subroutine write_sdm_totalPower(holodata, nd, rdata,   &
    error)
  !---------------------------------------------------------------------
  !     Write the totalPower SDM table.
  ! Many *TBD* items...
  !
  !---------------------------------------------------------------------
  use gildas_def
  use sdm_TotalPower
  use sdm_Enumerations
  ! Global variables:
  include 'clic_parameter.inc'
  include 'clic_par.inc'
  include 'clic_dheader.inc'
  include 'sdm_identifiers.inc'
  ! Dummy
  logical :: error, holodata
  integer :: nd
  real*4 :: rdata(nd)
  ! Local
  type (TotalPowerRow) :: tpmRow
  type (TotalPowerKey) :: tpmKey
  type (TotalPowerOpt) :: tpmOpt
  integer :: ia, i, ib, numBaseBand, ic, ip
  character, parameter :: sdmTable*20 = 'TotalPower'
  !c      integer, parameter :: numchannel = 1
  !---------------------------------------------------------------------
  call sdmMessage(1,1,sdmTable,'Starting...')
  numBaseBand = r_lband
  !
  ! Force numCorr to 6 products in holodata mode, and numBaseBand to 1
  if (holodata) then
    num_Corr = 6
    numBaseBand = 1
  else
    num_Corr = r_npol_rec
    numBaseBand = r_lband
  endif
  !! this is the old fashioned way...
  call allocTotalPowerRow(tpmRow, r_nant, num_Corr,   &
    numBaseBand, error)
  !      print *, r_nant, num_Corr, numBaseBand, error
  if (error) return
  !
  !     *TBD* THe dimensions of the floatData are unclear in documentation
  !
  !     For ALMA I would say:
  !
  !     - Nant, Nreceptors(2), Nbb for the baseband detectors (2GHz Bw)
  !
  !     - Nant, Nreceptors(2), Nsidebands(<2) for the downConverter
  !     detectors (2GHz Bw)
  !
  !     In all cases we need to define a spectral window and a configId
  !     for the continuum detectors.
  !
  !     The Key:
  !     The time interval midpoint
  tpmKey%time = time_Interval(1) + time_Interval(2)/2.
  if (.not. holodata) then
    tpmKey%configDescriptionId = TotPowConfigDescription_Id
  else
    tpmKey%configDescriptionId = ConfigDescription_Id
  endif
  !
  tpmKey%fieldId = Field_Id
  tpmRow%interval = time_Interval(2)
  tpmRow%execBlockId = execBlock_Id
  tpmRow%scanNumber = Scan_Number
  tpmRow%subScanNumber = subScan_Number
  tpmRow%exposure = time_interval(2)
  tpmRow%timeCentroid = time_Interval(1) + time_Interval(2)/2.
  !
  !     State_Id could depend on antenna, but doesn't.  exposures could
  !     too (for average record). We do not keep proper tracking at Bure
  !     for averaging....
  do i=1, r_nant
    tpmRow%stateId(i) = State_Id
  enddo
  !
  ! In e.g. holography each integration will be a dump in CLIC. (no spectral data).
  if (holodata) then
    tpmRow%integrationNumber = dh_dump
  else
    tpmRow%integrationNumber = 1
  endif
  !
  tpmRow%uvw = 0
  if (r_nbas.gt.0) then
    do ib = 1, r_nbas
      if (r_iant(ib).eq.1) then
        tpmRow%uvw(1,r_jant(ib)) = dh_uvm(1,ib)
        tpmRow%uvw(2,r_jant(ib)) = dh_uvm(2,ib)
      endif
    enddo
  endif
  !     ...     put dh_total in FloatData
  !
  !     *TBD* The dimensions of floatData are nant, nc, nf for total power
  !     I guess nc is always 1; should it not be numReceptors?  in fact nc
  !     is defined in polarization table, there shoudl be there en entry
  !     for the total powers. this is the number of corr products which
  !     can be 1 or 2.
  !     nc is num_Corr ...
  !
  if (.not.holodata) then
    !
    !     The order is : (pol. product, baseband, antenna). Bure has a single
    !     number of all basebands at this point.
    !
    do ic = 1, r_lband
      do ip = 1, r_npol_rec
        do ia = 1, r_nant
          tpmRow%FloatData(ip,ic,ia) = dh_total(ip,ia)
          if (r_totscale(ip,ia).ne.0) then
            tpmRow%FloatData(ip,ic,ia) = tpmRow%FloatData(ip   &
              ,ic,ia) * r_totscale(ip,ia)
          endif
        enddo
      enddo
    enddo
  else
    do ia = 1, r_nant
      do ic = 1, mCorrHolo
        if (holo_type(ic).eq.HolographyChannelType_S2) then
          tpmRow%FloatData(ic,1,ia) = dh_test0(2)
        elseif (holo_type(ic).eq.HolographyChannelType_R2) then
          tpmRow%FloatData(ic,1,ia) = dh_test0(1)
        elseif (holo_type(ic).eq.HolographyChannelType_Q2) then
          tpmRow%FloatData(ic,1,ia) = dh_test0(3)
        elseif (holo_type(ic).eq.HolographyChannelType_RS) then
          tpmRow%FloatData(ic,1,ia) = rdata(1)*dh_test0(1)
        elseif (holo_type(ic).eq.HolographyChannelType_QS) then
          tpmRow%FloatData(ic,1,ia) = dh_test0(4)
        elseif (holo_type(ic).eq.HolographyChannelType_QR) then
          tpmRow%FloatData(ic,1,ia) = rdata(2)*dh_test0(1)
        endif
      enddo
    enddo
  !
  endif
  !
  ! *TBD* The order of dimensions for floatData in TotalPower
  ! *TBD*  is not precised in ASDM documentation...
  !
  !     ...     put dh_aflag in flagAnt
  tpmRow%flagAnt = 0
  tpmRow%flagRow = .false.
  tpmRow%flagPol = 0
  ! *TBD* The order of dimensions for flagPol in TotalPower
  ! *TBD*  is not precised in ASDM documentation...
  !
  call addtotalPowerRow(tpmKey, tpmRow, error)
  if (error) return
  !
  ! Add subintegration number if this is is a subintegration:
  if (dh_integ.le.1.0 .and. .not.holodata) then
    tpmOpt%subintegrationNumber = dh_dump
    call addtotalPowerSubintegrationNumber(tpmKey, tpmOpt   &
      ,error)
    if (error) return
  endif
  call sdmMessage(1,1,sdmTable,'Written.')
  return
99 error = .true.
end subroutine write_sdm_totalPower
!---------------------------------------------------------------------
subroutine get_sdm_totalPower(holodata, tpmSize,   &
    tpmKeyList, error)
  !---------------------------------------------------------------------
  !     Read the totalPower SDM table.
  !     Specific holography data mode allowed
  ! Many *TBD* items...
  !
  !---------------------------------------------------------------------
  use gildas_def
  use sdm_TotalPower
  ! Global variables:
  include 'clic_parameter.inc'
  include 'clic_par.inc'
  include 'clic_dheader.inc'
  include 'sdm_identifiers.inc'
  ! Dummy
  integer :: tpmSize
  logical :: holodata, error, present
  type (TotalPowerKey) :: tpmKeyList(tpmSize)
  ! Local
  type (TotalPowerRow) :: tpmRow
  type (TotalPowerKey) :: tpmKey
  type (TotalPowerOpt) :: tpmOpt
  integer :: ia, i, ib, itpm, ic, ip, numCorr, numBaseBand
  character, parameter :: sdmTable*20 = 'TotalPower'
  !      integer, parameter :: numchannel = 1
  !---------------------------------------------------------------------
  call sdmMessage(1,1,sdmTable,'Starting...')
  !
  ! need to find the relevant totalpower row; assume only one ...
  error = .true.
  do itpm = 1, tpmSize
    if ((tpmKeyList(itpm)%fieldId.eq.field_Id) .and.   &
      (tpmKeyList(itpm)%time.ge.time_interval(1) -   &
      time_interval(2)/2) .and. (tpmKeyList(itpm)%time.le.   &
      (time_interval(1) + time_interval(2)/2))) then
      tpmKey = tpmKeyList(itpm)
      error = .false.
    endif
  enddo
  if (error) then
    call sdmMessage(6,3,sdmTable,'No relevant Row')
    return
  endif
  !
  TotPowConfigDescription_Id = tpmKey%configDescriptionId
  !
  !     Get numCorr (and numBaseBand) for this (should find them in
  !
  !     ConfigDescription -> DataDescription -> Polarization and Processor...
  !
  !     I assume here that numCorr is equal to numReceptors (=r_npol_rec),
  !     which is not necessary for ALMA.
  !
  numCorr = r_npol_rec
  numBaseBand = 1
  !
  call allocTotalPowerRow(tpmRow, mnant, numCorr, numBaseBand, error   &
    )
  if (error) return
  !
  !     *TBD* THe dimensions of the floatData are (ncorr, nbaseband, nant)
  !
  call getTotalPowerRow(tpmKey, tpmRow, error)
  if (error) return
  if (.not.holodata) then
    ! these could be checked...
    if (Scan_Number.ne.tpmRow%scanNumber .or. tpmRow%subScanNumber   &
      .ne.subScan_Number .or. tpmRow%execBlockId.ne.execBlock_Id   &
      .or.tpmRow%subScanNumber.ne.subScan_Number) then
    !$$$            print *, 'execBlock_Id, Scan_Number, subScan_Number'
    !$$$            print *, execBlock_Id, Scan_Number, subScan_Number
    !$$$            print *, 'tpmRow%execBlockId, tpmRow%scanNumber, ',
    !$$$     &           'tpmRow%subScanNumber'
    !$$$            print *, tpmRow%execBlockId, tpmRow%scanNumber,
    !$$$     &           tpmRow%subScanNumber
    endif
    !
    !     State_Id could depend on antenna, but doesn't.  exposures could
    !     too (for average record). We do not keep proper tracking at Bure
    !     for averaging....
    !     ...     put dh_total in FloatData
    !
    !
    do ip=1, numCorr
      do ia = 1, r_nant
        dh_total(ip, ia) = tpmRow%FloatData(ip, 1, ia)
      enddo
    enddo
    !
    !
    !     Get the subintegration number:
    call getTotalPowerSubintegrationNumber(tpmKey, tpmOpt   &
      ,present, error)
    if (error) return
    !     We have a problem if this does not match the one from Main!!
    if (present) then
      if (dh_dump.ne.tpmOpt%subintegrationNumber) then
        call sdmMessageI(6,2,sdmTable   &
          ,'Unexpected SubintegrationNumber'   &
          ,tpmOpt%subintegrationNumber)
        call sdmMessageI(6,2,sdmTable ,'I expected: ' ,dh_dump)
      endif
    endif
  else
    !
    ! holography is different
    !... put the floatdata where it should be put .....#############
    !
    !$$$         print *, 'execBlock_Id, Scan_Number, subScan_Number'
    !$$$         print *, execBlock_Id, Scan_Number, subScan_Number
    !$$$         print *, 'tpmRow%execBlockId, tpmRow%scanNumber, ',
    !$$$     &        'tpmRow%subScanNumber'
    !$$$         print *, tpmRow%execBlockId, tpmRow%scanNumber,
    !$$$     &        tpmRow%subScanNumber
    ExecBlock_Id = tpmRow%ExecBlockId
    Scan_Number = tpmRow%scanNumber
    subScan_Number = tpmRow%subScanNumber
    !$$$         print *, 'tpmRow%stateId'
    !$$$         print *, tpmRow%stateId
    state_Id = tpmRow%stateId(1)
    do ia = 1, r_nant
      if(state_Id.ne.tpmRow%stateId(ia)) then
        error = .true.
        call sdmmessageI(8,4,sdmTable ,'Unexpected State_Id '   &
          ,tpmRow%stateId(ia))
        return
      endif
    enddo
  !$$$         print *, 'state_Id ',state_Id
  endif
  call sdmMessage(1,1,sdmTable,'Read.')
  return
99 error = .true.
end subroutine get_sdm_totalPower
!---------------------------------------------------------------------
subroutine get_sdm_totalPowerHoloData(tpm, tpRow,   &
    dataArray, error)
  !---------------------------------------------------------------------
  !     Read the totalPower SDM holography data, for the
  !     relevant row.
  !
  !---------------------------------------------------------------------
  use gildas_def
  use sdm_TotalPower
  use sdm_Enumerations
  ! Global variables:
  include 'clic_parameter.inc'
  include 'clic_par.inc'
  include 'clic_dheader.inc'
  include 'sdm_identifiers.inc'
  ! Dummy
  type (TotalPower) :: tpm
  integer :: tpRow
  logical :: error, no_number
  real :: dataArray(4)
  ! Local
  integer :: ia, i, ib, itpm, k, ic
  character, parameter :: sdmTable*20 = 'TotalPower'
  real :: holoss, holoqq, holorr, holosq, holosr, holoqr
  real :: testArray(4)
  !---------------------------------------------------------------------
  call sdmMessage(1,1,sdmTable,'Starting...')
  !      num_Corr = 6
  !
  !...  put the floatdata where it should be put .....
  !
  ia = 1
  ! apparently the product number goes first...
  !'QQ', 'QR', 'QS', 'RR', 'RS', 'SS'/)
  do ic = 1, mCorrHolo
    if (no_number(tpm%FloatData(ic,1,ia,tpRow))) then
      tpm%FloatData(ic,1,ia,tpRow) = 0
      dh_bflag(1) = 2**30
      dh_aflag(1) = 2**30
    endif
    if (holo_type(ic).eq.HolographyChannelType_S2) then
      holoss = tpm%FloatData(ic,1,ia,tpRow)/1e5
    elseif (holo_type(ic).eq.HolographyChannelType_R2) then
      holorr = tpm%FloatData(ic,1,ia,tpRow)/1e5
    elseif (holo_type(ic).eq.HolographyChannelType_Q2) then
      holoqq = tpm%FloatData(ic,1,ia,tpRow)/1e5
    elseif (holo_type(ic).eq.HolographyChannelType_RS) then
      holosr = tpm%FloatData(ic,1,ia,tpRow)/1e5
    elseif (holo_type(ic).eq.HolographyChannelType_QS) then
      holosq = tpm%FloatData(ic,1,ia,tpRow)/1e5
    elseif (holo_type(ic).eq.HolographyChannelType_QR) then
      holoqr = tpm%FloatData(ic,1,ia,tpRow)/1e5
    endif
  enddo
  dh_test0(1) = holorr         ! true rr
  dh_test0(2) = holoss         ! true ss
  dh_test0(3) = holoqq         ! true qq
  dh_test0(4) = holosr         ! true sq
  dh_test0(5) = holoqr         ! true sq
  dh_test0(6) = holosq         ! true sq
  dh_test0(7) = 1d-9*(tpm%time(tpRow) - tpm%time(1))
  !      print *, tpRow, tpm%time(tpRow), dh_test0(7)
  ! holography has a single polarization:
  dh_total(1, 1) = holoss
  dh_total(2, 1) = holoss
  r_totscale(1,1) = 1.0
  r_totscale(2,1) = 1.0
  !
  !     1 subband, 2 side band ,1 baseline (2 side bands for
  !     compatibility) as clic poorly handles data with one sideband only
  !     .  LSB is used to hold data with phases reversed.  More precise
  !     formula is TBD
  dataarray(3) = holorr        ! reference beam in LSB
  dataarray(4) = 0             ! with zero phase ... uncalibrated in LSB
  if (holorr.ne.0) then
    holosr = holosr/holorr
    holoqr = holoqr/holorr
    dataarray(1) = holosr      ! true SR in USB (real)
    dataarray(2) = holoqr/0.99834  ! true QR in USB (imag)
    !         dataarray(3) = dataarray(1)    ! true SR in LSB (real)
    !         dataarray(4) = dataarray(2)    ! true QR in LSB (imag)
    dh_aflag = 0
    dh_bflag = 0
  else
    holosr = 0.0
    holoqr = 0.0
    dataarray(1) = holosr      ! true SR in USB (real)
    dataarray(2) = holoqr/0.99834  ! true QR in USB (imag)
    !         dataarray(3) = dataarray(1)    ! true SR in LSB (real)
    !         dataarray(4) = dataarray(2)    ! true QR in LSB (imag)
    dh_aflag(1) = -1
    dh_bflag(1) = -1
    print *, '== r_xnum, tpRow ',r_xnum, tpRow ,   &
      ' data flagged (holorr = 0) '
  endif
  if (tpm%flagrow(tpRow) .or. tpm%flagAnt(1,tpRow).ne.0 .or.   &
    tpm%flagpol(1,1,tpRow).ne.0) then
    dh_aflag(1) = -1
    dh_bflag(1) = dh_aflag(1)
    print *, '== r_xnum, tpRow ',r_xnum, tpRow , ' data flagged'
    print *, 'tpm%flagrow(tpRow) ', tpm%flagrow(tpRow)
    print *, 'tpm%flagAnt(1,tpRow) ', tpm%flagAnt(1,tpRow)
    print *, 'tpm%flagpol(1,1,tpRow) ', tpm%flagpol(1,1,tpRow)
  endif
  !
  call sdmMessage(1,1,sdmTable,'Read.')
  return
99 error = .true.
end subroutine get_sdm_totalPowerHoloData
!---------------------------------------------------------------------
subroutine allocTotalPowerRow(row, numAntenna,   &
    numCorr, numBaseBand, error)
  !---------------------------------------------------------------------
  !     integer, allocatable :: stateId(:)
  !     real*8, allocatable :: uvw(:,:)
  !     integer*8, allocatable :: exposure(:,:)
  !     integer*8, allocatable :: timeCentroid(:,:)
  !     real, allocatable :: floatData(:,:,:)
  !     integer, allocatable :: flagAnt(:)
  !     integer, allocatable :: flagPol(:,:)
  !---------------------------------------------------------------------
  use sdm_TotalPower
  type(TotalPowerRow) :: row
  integer :: numAntenna, numCorr, numBaseBand, ier
  logical :: error
  character, parameter :: sdmTable*20 = 'TotalPower'
  !---------------------------------------------------------------------
  !
  ! stateId (numAntenna)
  if (allocated(row%stateId)) then
    deallocate(row%stateId, stat=ier)
    if (ier.ne.0) goto 98
  endif
  allocate(row%stateId(numAntenna), stat=ier)
  if (ier.ne.0) goto 99
  !
  ! uvw (3, numAntenna)
  if (allocated(row%uvw)) then
    deallocate(row%uvw, stat=ier)
    if (ier.ne.0) goto 98
  endif
  allocate(row%uvw(3, numAntenna), stat=ier)
  if (ier.ne.0) goto 99
  !
  ! exposure (numBaseband, numAntenna)
  if (allocated(row%exposure)) then
    deallocate(row%exposure, stat=ier)
    if (ier.ne.0) goto 98
  endif
  allocate(row%exposure(numBaseband, numAntenna), stat=ier)
  if (ier.ne.0) goto 99
  !
  ! timeCentroid (numBaseband, numAntenna)
  if (allocated(row%timeCentroid)) then
    deallocate(row%timeCentroid, stat=ier)
    if (ier.ne.0) goto 98
  endif
  allocate(row%timeCentroid(numBaseband, numAntenna), stat=ier)
  if (ier.ne.0) goto 99
  !
  ! floatData (numChannel, numCorr, numAntenna)
  if (allocated(row%floatData)) then
    deallocate(row%floatData, stat=ier)
    if (ier.ne.0) goto 98
  endif
  allocate(row%floatData(numCorr, numBaseband, numAntenna), stat   &
    =ier)
  if (ier.ne.0) goto 99
  !
  ! flagAnt (numAntenna)
  if (allocated(row%flagAnt)) then
    deallocate(row%flagAnt, stat=ier)
    if (ier.ne.0) goto 98
  endif
  allocate(row%flagAnt(numAntenna), stat=ier)
  if (ier.ne.0) goto 99
  !
  ! flagPol (numCorr, numAntenna)
  if (allocated(row%flagPol)) then
    deallocate(row%flagPol, stat=ier)
    if (ier.ne.0) goto 98
  endif
  allocate(row%flagPol(numCorr, numAntenna), stat=ier)
  if (ier.ne.0) goto 99
  !
  return
  !
98 call sdmmessageI(8,4,sdmTable ,'Deallocation error ier ',ier)
  error = .true.
  return
  !
99 call sdmmessageI(8,4,sdmTable ,'Allocation error ier ',ier)
  error = .true.
  return
end subroutine allocTotalPowerRow
!!! !---------------------------------------------------------------------
