subroutine write_sdm_calHolography(nmode, rmsu, rmsw, bmes, nscrew   &
    ,screwName, screwMotion, screwMotionError, surfaceMapUid,   &
    beamMapUid, error)
  use gildas_def
  use gkernel_interfaces
  use sdm_CalHolography
  use sdm_CalData
  use sdm_CalReduction
  use sdm_Enumerations
  !---------------------------------------------------------------------
  ! Write the calHolography SDM table, and related tables.
  !---------------------------------------------------------------------
  ! Dummy
  integer :: nmode, nscrew
  logical :: error
  real*8 bmes(7)
  real rmsu, rmsw, screwMotion(nscrew),   &
    screwMotionError(nscrew)
  character*12 screwName(nscrew)
  character*(*) surfaceMapUid, beamMapUid
  integer :: luid
  ! Global variables:
  include 'clic_parameter.inc'
  include 'clic_par.inc'
  include 'clic_dheader.inc'
  include 'clic_constant.inc'
  include 'clic_display.inc'
  include 'gbl_memory.inc'
  include 'gbl_xpar.inc'
  include 'gbl_ypar.inc'
  include 'sdm_identifiers.inc'
  character :: version*20
  ! Local
  type(CalHolographyRow) :: chRow
  type(CalHolographyKey) :: chKey
  type(CalHolographyOpt) :: chOpt
  type(CalDataRow) :: cdRow
  type(CalDataKey) :: cdKey
  type(CalReductionRow) :: crRow
  type(CalReductionKey) :: crKey
  integer sig, ima, nfreq, ia, isb, ier, i, l
  integer ireturn, sdm_addCalDataRow, sdm_addCalReductionRow,   &
    sdm_addCalHolographyRow
  character sdmTable*16, uid*80
  parameter (sdmTable = 'calHolography')
  !---------------------------------------------------------------------
  include 'clic_version.inc'
  call sdmMessage(1,1,sdmTable ,'starting...')
  !
  ! cal data table:
  cdRow%numScan = 1
!!  call allocCalDataRow(cdRow, cdRow%numScan, error)
  call allocCalDataRow(cdRow, error)
  if (error) return
  !
  cdRow%scanSet(1) = r_scan
  cdRow%calType = CalType_CAL_HOLOGRAPHY
  !     this is not stricly true, but we lost track of the time of actual
  !     load observations...
  !
  cdRow%startTimeObserved = time_interval(1)
  cdRow%endTimeObserved = time_interval(1)+time_interval(2)
  call addCalDataRow(cdKey, cdRow, error)
  if (error) goto 99
  !
  ! cal reduction table:
  !
  crRow%numApplied = 1
  crRow%numParam = 1
  crRow%numInvalidConditions = 1
!!!   call allocCalReductionRow(crRow, crRow%numApplied, crRow%numParam,   &
!!!     crRow%numInvalidConditions, error)
  call allocCalReductionRow(crRow, error)
  if (error) goto 99
  !
  !!crRow%calAppliedArray(1) = 'None'
  crRow%AppliedCalibrations(1) = 'None'
  crRow%paramSet(1) = 'None'
  !
  ! That's now! calculate...
  crRow%timeReduced = time_Interval(1) + time_Interval(2)
  crRow%messages = 'None'
  crRow%software = 'CLIC'
  crRow%softwareVersion = version
  crRow%invalidConditions = InvalidatingCondition_RECEIVER_EXCHANGE
  !
  call addCalReductionRow(crKey, crRow, error)
  if (error) goto 99
  !
  ! calHolography  table:
  !     TODO antenna name must somehow be saved in CLIC file! (holography
  !     section)
  if (r_kant(1).lt.100) then
    ia = r_kant(1)
    write (chKey%antennaName,'(a4,i2.2)')  'BURE',ia
  elseif (r_kant(1).lt.200) then
    ia = r_kant(1)-100
    write (chKey%antennaName,'(a4,i2.2)')  'ALMA',ia
  endif
  !
  chKey%CalReductionId = crKey%CalReductionId
  chKey%CalDataId = cdKey%CalDataId
  !
  ! in Data:
  !    integer :: numScrew
  ! this will be 2 for astronomical holography, probably.
  chRow%numReceptor = 1
!!!   call allocCalHolographyRow(chRow, chRow%numReceptor,   &
!!!     chRow%numScrew, error)
  call allocCalHolographyRow(chRow, error)
  if (error) return
  chOpt%numScrew = nscrew
  call allocCalHolographyOpt(chRow, chOpt, error)
  if (error) return
  !    integer*8 :: startValidTime
  !    integer*8 :: endValidTime
  chRow%startValidTime = cdRow%startTimeObserved
  chRow%endValidTime = -1      !???
  !    real*8, allocatable :: focusPosition(:) X, Y, Z
  chRow%focusPosition(1) = bmes(5)
  chRow%focusPosition(2) = bmes(6)
  chRow%focusPosition(3) = bmes(4)
  chRow%rawRms = rmsu
  chRow%weightedRms = rmsw
  ! could be X, I'm not sure
  chRow%polarizationTypes(1) = PolarizationType_Y
  do i=1, nscrew
    chOpt%screwName(i) = screwName(i)//char(0)
    chOpt%screwMotion(i) = screwMotion(i)
    chOpt%screwMotionError(i) = screwMotionError(i)
  enddo
  chRow%direction(1) = r_az
  chRow%direction(2) = r_el
  chRow%ambientTemperature = r_tamb
!!  chrow%panelModes = nmode
  chrow%numPanelModes = nmode
  !
  !     real*8 :: frequency
  if (i_band(1).eq.1) then
    chrow%frequencyRange = r_flo1+r_fif1
  elseif (i_band(1).eq.2) then
    chrow%frequencyRange = r_flo1-r_fif1
  else
    chrow%frequencyRange = r_flo1
  endif
  luid = lenc(surfaceMapUid)
  chrow%surfaceMapUID = '<EntityRef '//   &
    'entityId="'//surfaceMapuid(1:luid)//   &
    '" partId="X00000002" '//   &
    'entityTypeName="holographyMap" '//   &
    'documentVersion="1"/>'
  luid = lenc(beamMapUid)
  chrow%beamMapUID = '<EntityRef '//   &
    'entityId="'//beamMapuid(1:luid)//   &
    '" partId="X00000002" '//   &
    'entityTypeName="beamMap" '//   &
    'documentVersion="1"/>'
  call addCalHolographyRow(chkey, chRow, error)
  if (error) return
  call addCalHolographyNumScrew(chkey, chOpt, error)
  if (error) return
  call addCalHolographyScrewName(chkey, chOpt, error)
  if (error) return
  call addCalHolographyScrewMotion(chkey, chOpt, error)
  if (error) return
  call addCalHolographyScrewMotionError(chkey, chOpt, error)
  if (error) return
  call sdmMessage(1,1,sdmTable ,'Written.')
99 return
end subroutine write_sdm_calHolography
!---------------------------------------------------------------------
!---------------------------------------------------------------------
!!! subroutine allocCalHolographyRow(row, numReceptor, numScrew,   &
!!!     error)
!!!   !
!!!   ! Allocate memory for a CalHolography Row.
!!!   !
!!!   use sdm_CalHolography
!!!   type(CalHolographyRow) :: row
!!!   integer :: numReceptor, numScrew, ier
!!!   logical :: error
!!!   character, parameter :: sdmTable*16 = 'calHolography'
!!!   ! focusPosition
!!!   if (allocated(row%focusPosition)) then
!!!     deallocate(row%focusPosition, stat=ier)
!!!     if (ier.ne.0) goto 98
!!!   endif
!!!   allocate(row%focusPosition(3), stat=ier)
!!!   if (ier.ne.0) goto 99
!!!   ! frequencyRange
!!!   if (allocated(row%frequencyRange)) then
!!!     deallocate(row%frequencyRange, stat=ier)
!!!     if (ier.ne.0) goto 98
!!!   endif
!!!   allocate(row%frequencyRange(2), stat=ier)
!!!   if (ier.ne.0) goto 99
!!!   ! direction
!!!   if (allocated(row%direction)) then
!!!     deallocate(row%direction, stat=ier)
!!!     if (ier.ne.0) goto 98
!!!   endif
!!!   allocate(row%direction(2), stat=ier)
!!!   if (ier.ne.0) goto 99
!!!   ! screwName
!!!   if (allocated(row%screwName)) then
!!!     deallocate(row%screwName, stat=ier)
!!!     if (ier.ne.0) goto 98
!!!   endif
!!!   allocate(row%screwName(numScrew), stat=ier)
!!!   if (ier.ne.0) goto 99
!!!   ! screwMotion
!!!   if (allocated(row%screwMotion)) then
!!!     deallocate(row%screwMotion, stat=ier)
!!!     if (ier.ne.0) goto 98
!!!   endif
!!!   allocate(row%screwMotion(numScrew), stat=ier)
!!!   if (ier.ne.0) goto 99
!!!   ! screwMotionError
!!!   if (allocated(row%screwMotionError)) then
!!!     deallocate(row%screwMotionError, stat=ier)
!!!     if (ier.ne.0) goto 98
!!!   endif
!!!   allocate(row%screwMotionError(numScrew), stat=ier)
!!!   if (ier.ne.0) goto 99
!!!   ! polarizationTypes
!!!   if (allocated(row%polarizationTypes)) then
!!!     deallocate(row%polarizationTypes, stat=ier)
!!!     if (ier.ne.0) goto 98
!!!   endif
!!!   allocate(row%polarizationTypes(numReceptor), 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 sdm_holoTimes(first, error)
  logical :: error, first
  include 'clic_parameter.inc'
  include 'clic_par.inc'
  include 'clic_dheader.inc'
  include 'sdm_identifiers.inc'
  integer*8 times(2)
  !
  times(1) = ((dh_obs+60549.0d0)*86400.d0+dh_utc-0.5d0*dh_integ)   &
    *1d9
  times(2) = dh_integ*1d9
  if (first) then
    time_interval(1) = times(1)
    time_interval(2) = times(2)
  else
    time_interval(1) = min(time_interval(1), times(1))
    time_interval(2) = max(time_interval(1)+time_interval(2),   &
      times(1)+times(2)) - time_interval(1)
  endif
  return
end subroutine sdm_holoTimes
