subroutine write_sdm_pointing(ndata, data, error)
  use gkernel_interfaces
  use classic_api
  !---------------------------------------------------------------------
  !     Write the Pointing SDM table.
  ! now a single row per subscan.
  !
  !---------------------------------------------------------------------
  use gildas_def
  use sdm_pointing
  ! Global variables:
  include 'clic_parameter.inc'
  include 'clic_par.inc'
  include 'clic_dheader.inc'
  include 'sdm_identifiers.inc'
  include 'gbl_pi.inc'
  INCLUDE 'clic_constant.inc'
  ! Dummy
  logical :: error
  integer(kind=data_length) :: ndata, h_offset
  integer :: data(ndata)
  ! Local
  type (PointingRow) :: pRow
  type (PointingKey) :: pKey
  type (PointingOpt) :: pOpt
  integer :: ia, ir, isw, k
  real*8 lat, trfm_24(3,3), x_2(3), ho(2)
  real*8 ::  x_6(3), s_2(2), s_6(2), trfm_62(3,3), psi, the,   &
       phi, radpersec
  character, parameter :: sdmTable*8 = 'Pointing'
  integer*8 :: pointingTime
  logical first
  data first/.true./
  save first
  save pointingTime
  data pointingTime /-1/

  !---------------------------------------------------------------------
  radpersec = pi/180d0/3600d0
  !
  ! ensure a minimal granularity of 48ms
  k = 1+ h_offset(r_ndump+1)
  call decode_header (data(k))
  !print *, dh_obs, dh_integ, dh_utc
  call get_time_interval
  !print *, 'pointing time_Interval ', time_Interval
!  if (time_Interval(1).ge.pointinTime+48000000) then
!    pKey%timeInterval = ArrayTimeInterval(time_Interval(1), -1)
!    pointingTime = time_Interval(1)
!  else
!    return
!  endif
  pKey%timeInterval = ArrayTimeInterval(time_Interval(1),time_Interval(2))
  !print *, 'pKey%timeInterval ', pKey%timeInterval
  call sdmMessage(1,1,sdmTable ,'starting...')
  ! we do not use polynomials
  ! one sample is one PdB dump.cp  /diskb/ALMA_ACS8/ASDMImpl/ICD/HLA/
  pRow%numSample = r_ndump
  pRow%numTerm = r_ndump
  ! pRow%numPoly = 0
  !!   call allocPointingRow(pRow, pRow%numPoly, error)
  call allocPointingRow(pRow, error)
  if (error) return
  call allocPointingOpt(pRow, pOpt, error)
  if (error) return
  pRow%numTerm = 1

  
  !
  do ia = 1, r_nant
    ! OPTIONAL IN SS2 ...         pRow%name = r_sourc
    pRow%timeOrigin = time_Interval(1)
    ! loop on the dumps
    do ir=1, r_ndump
      k = 1+ h_offset(ir)
      call decode_header (data(k))
      if (error) return
      ! print *, dh_utc
      ! get the time interval from CLIC data_header.
      call get_time_interval
      pOpt%sampledTimeInterval(ir) = ArrayTimeInterval(time_Interval(1), &
           time_interval(2))

      if (r_nswitch.gt.0) then
        isw = dh_test0(1)
        dh_offlam = dh_offlam - r_pswitch(1,isw)
        dh_offlam = dh_offlam - r_pswitch(2,isw)
      endif

      !
      !     pRow%target is the source direction as seen from antenna
      !
      !     equatorial coordinates system
      !
      if (r_typec.eq.type_eq) then
        !     get it from dh_svec:
        !     dh_svec is the source vector in hour-angle, dec coordinates (4)
        !     n_4 is the normal to the source meridian plane
        !     TRFM_24 goes from (4) to (2)
        !     x_2 is the source vector in in horiz coords(2).
        !     lat is the latitude of antenna...
        lat = atan2(r_antgeo(3,ia), sqrt(r_antgeo(1,ia)**2   &
             +(r_antgeo(2,ia)**2)))
        psi = pi/2               ! 90 degrees
        the = pi/2-lat           ! 90 degrees minus latitude
        phi = -pi/2              ! -90 degrees
        call eulmat (psi, the, phi,trfm_24)
        call matvec (dh_svec, trfm_24, x_2)
        call spher(x_2, ho)
        ho(1) = mod(-ho(1)+3d0*pi,2d0*pi)
        ho(2) = mod(ho(2)+3d0*pi,2d0*pi)-pi
        !
        ! horizontal coordinates system
        !
      elseif (r_typec.eq.type_ho) then
        ho(1) = r_az
        ho(2) = r_el
        ho(1) = mod(ho(1)+3d0*pi,2d0*pi)
        ho(2) = mod(ho(2)+3d0*pi,2d0*pi)-pi
      elseif (r_typec.eq.type_un) then
        ! this must be old holo data from ATF, with reference to North?
        ho(1) = r_az
        ho(2) = r_el
        ho(1) = mod(ho(1)+3d0*pi,2d0*pi)-pi
        ho(2) = mod(ho(2)+3d0*pi,2d0*pi)-pi
      endif
      !print *, r_typec, type_eq, type_ho, type_un, ho
      ! use az reference to North...
      pRow%target(1,ir) = ho(1)
      pRow%target(2,ir) = ho(2)
      !
      ! Euler angles from  descriptive system to AzEl system:
      psi = pi/2.
      the = pRow%target(2,ir)
      phi = -pi/2 -pRow%target(1,ir)
      s_6(1) = dh_offlam(ia) * radpersec
      s_6(2) = dh_offbet(ia) * radpersec
      call rect(s_6, x_6)
      call eulmat (psi, the, phi, trfm_62)
      call matvec (x_6, trfm_62, x_2)
      call spher(x_2, s_2)
      pRow%pointingDirection(1,ir) = s_2(1)
      pRow%pointingDirection(2,ir) = s_2(2)

      pRow%offset(1,ir) = s_6(1)
      pRow%offset(2,ir) = s_6(2)
      !14712
      !     This is antenna measured pointing direction (add the errors back in)
      !
      pRow%encoder(1,ir) = pRow%pointingDirection(1,ir) + dh_rmspe(1,ia)   &
           * radpersec
      pRow%encoder(2,ir) = pRow%pointingDirection(2,ir) + dh_rmspe(2,ia)   &
           * radpersec
    enddo
    pRow%pointingTracking = .true.
    ! OPTIONAL IN SS2 ...            pRow%phaseTracking = .true.
    pKey%antennaId = antenna_Id(ia)
    !         pKey%timeInterval = ArrayTimeInterval(time_Interval(1), -1)
    pRow%pointingModelId = pointingModel_Id(ia)
    !print *, ' pKey%timeInterval ', pKey%timeInterval
    !print *, ' pKey%antennaId ', pKey%antennaId
    call addPointingRow(pKey, pRow, error)
    if (error) return
    if (first) then
      call addPointingSampledTimeInterval(pKey, pOpt, error)
      if (error) return
    endif
    first = .not.first
    
  enddo
  call sdmMessage(1,1,sdmTable,'Written.')
  return
  !
99 error = .true.
end subroutine write_sdm_pointing
!---------------------------------------------------------------------
!!! subroutine get_sdm_pointing(first, error)
!!!   !---------------------------------------------------------------------
!!!   !     Read  the Pointing SDM table.
!!!   !
!!!   !---------------------------------------------------------------------
!!!   use gildas_def
!!!   use sdm_pointing
!!!   ! Global variables:
!!!   include 'clic_parameter.inc'
!!!   include 'clic_par.inc'
!!!   include 'clic_dheader.inc'
!!!   include 'sdm_identifiers.inc'
!!!   include 'gbl_pi.inc'
!!!   ! Dummy
!!!   logical error, first
!!!   ! Local
!!!   type (PointingRow) :: pRow
!!!   type (PointingKey) :: pKey
!!!   integer :: ia
!!!   integer, parameter :: mpoly = 10
!!!   real*8 ::  x_2(3), x_6(3), s_2(2), s_6(2), trfm_26(3,3), psi, the,   &
!!!     phi, radpersec, rad, slat, clat
!!!   character, parameter :: sdmTable*8 = 'Pointing'
!!!   !---------------------------------------------------------------------
!!!   call sdmMessage(1,1,sdmTable ,'starting...')
!!!  call allocPointingRow(pRow, mPoly, error)14961
!!!   pRow%numTerm = 1
!!!   call allocPointingRow(pRow, error)
!!!   if (error) return
!!!   radpersec = pi/180d0/3600d0
!!!   !
!!!   !      pKey%timeInterval = ArrayTimeInterval(time_Interval(1),-1)
!!!   pKey%timeInterval = ArrayTimeInterval(time_interval(1)+1   &
!!!     ,time_interval(2)-1)
!!!   do ia = 1, r_nant
!!!     pKey%antennaId = antenna_Id(ia)
!!!     !!print *, 'pKey%antennaId, pKey%timeInterval ', pKey%antennaId, pKey%timeInterval
!!!     call getPointingRow(pKey, pRow, error)
!!!     if (error) return
!!!     ! print *, pKey%timeInterval, pRow%numSample
!!!     ! OPTIONAL in SS2 ...          r_sourc = pRow%name
!!!     !
!!!     !     This is the source direction as seen from antenna
!!!     !     this is in the CLIC header, check only of first point.
!!!     r_az = pRow%target(1,1)
!!!     r_el = pRow%target(2,1)
!!!     ! print *, r_az, r_el
!!!     !
!!!     !     Compute offsets i.e. coordinates in the system of origin p%target.
!!!     !
!!!     psi = pi/2 + pRow%target(1,1)
!!!     the = - pRow%target(2,1)
!!!     phi = -pi/2.
!!!     s_2 = pRow%encoder(:,1)
!!!     call rect(s_2, x_2)
!!!     call eulmat (psi, the, phi, trfm_26)
!!!     call matvec (x_2, trfm_26, x_6)
!!!     call spher(x_6, s_6)
!!! !    dh_offlam(ia) = s_6(1) / radpersec
!!! !    dh_offbet(ia) = s_6(2) / radpersec
!!! ! not exactly ...
!!!     dh_offlam(ia) = pRow%offset(1,1) / radpersec
!!!     dh_offbet(ia) = pRow%offset(2,1) / radpersec
!!!     ! print *, dh_offlam, dh_offbet
!!!     !
!!!     !     These are the antenna tracking errors:
!!!    dh_rmspe(1,ia) = (pRow%encoder(1)-pRow%pointingDirection(1,1))   &
!!!      / radpersec
!!!    dh_rmspe(2,ia) = (pRow%encoder(2)-pRow%pointingDirection(2,1))   &
!!!      / radpersec
!!!     dh_rmspe(1,ia) = (pRow%encoder(1,1)-pRow%pointingDirection(1,1))   &
!!!       / radpersec
!!!     dh_rmspe(2,ia) = (pRow%encoder(2,1)-pRow%pointingDirection(2,1))   &
!!!       / radpersec
!!!     dh_offlam(ia) = dh_offlam(ia)+dh_rmspe(1,ia)
!!!     dh_offbet(ia) = dh_offbet(ia)+dh_rmspe(2,ia)
!!!     pointingModel_Id(ia) = pRow%pointingModelId
!!!     ! calculate source direction vector:
!!!     ! in horizontal:
!!!     dh_svec(1) = cos(pRow%target(1,1)) * cos(pRow%target(2,1))
!!!     dh_svec(2) = -sin(pRow%target(1,1)) * cos(pRow%target(2,1)) ! az backwards
!!!     dh_svec(3) = sin(pRow%target(2,1))
!!!     !in Bure hour-angle system : rotate pi around z:
!!!     dh_svec(1) = -dh_svec(1)
!!!     dh_svec(2) = -dh_svec(2)
!!!     ! print *, dh_svec
!!!     ! then lat around y
!!!     rad = sqrt(r_antgeo(1,ia)**2+r_antgeo(2,ia)**2+r_antgeo(3,ia)**2)
!!!     slat = asin(r_antgeo(3,ia)/rad)
!!!     clat = sqrt(1-slat**2)
!!!     dh_svec(1) =  slat * dh_svec(1) + clat * dh_svec(3)
!!!     dh_svec(3) = -slat * dh_svec(1) + slat * dh_svec(3)
!!!     ! print *, dh_svec
!!!   enddo
!!!   call sdmMessage(1,1,sdmTable ,'Read.')
!!!   return
!!!   !
!!! 99 error = .true.
!!! end
!---------------------------------------------------------------------
!---------------------------------------------------------------------
subroutine get_sdm_pointing(ndata, data, timeIntervalSubscan, &
     timeIntervalRecord, error)
  use gildas_def
  use gkernel_interfaces
  use sdm_pointing
  use sdm_types
  !---------------------------------------------------------------------
  !     Read data needed from the SDM table. 
  !     pRow is the row for the subscan...
  !---------------------------------------------------------------------
  ! Global variables:
  include 'clic_parameter.inc'
  include 'clic_par.inc'
  include 'clic_dheader.inc'
  include 'sdm_identifiers.inc'
  include 'gbl_pi.inc'
  ! Dummy
  logical :: error, isOutside
  integer :: ndata, data(ndata)
  type(ArrayTimeInterval) :: timeIntervalSubscan, splitTimeInterval
  type(ArrayTimeInterval) :: timeIntervalRecord(r_ndump)
  ! Local
  type(ArrayTimeInterval) :: tsplit 
  type (PointingRow) :: pRow
  type (PointingKey) :: pKey
  integer :: ia, ip, k, np, ip1, ip2, j, next, pSize, ir, ic, h_offset, ipm, i
  integer*8 :: t, tj, dt, adt, it
  character, parameter :: sdmTable*8 = 'Pointing'
  real*8 ::  x_2(3), x_6(3), s_2(2), s_6(2), trfm_26(3,3), psi, the,   &
    phi, radpersec, spdir(2), senc(2), soff(2), w, sw, minlam, maxlam, minbet, maxbet
  real*8::  target_Hack(2)
  logical:: first
  data first/.true./
  save target_Hack, first
  integer, parameter :: scan_lamb = 2, scan_beta = 3
  !---------------------------------------------------------------------
  call sdmMessage(1,1,sdmTable ,'starting...')
  pRow%numTerm = timeIntervalSubscan%interval / 48000000
  pRow%numSample = pRow%numTerm
  call allocPointingRow(pRow, error)
  if (error) return
  radpersec = pi/180d0/3600d0

  pKey%timeInterval = timeIntervalSubscan
  
  do ia = 1, r_nant
    pKey%antennaId = antenna_Id(ia)
    call getPointingRow(pKey, pRow, error)
    if (error) return
    ip = 1
    np = pRow%numSample
    minlam = 1e20
    minbet = 1e20
    maxlam = -1e20
    maxbet = -1e20
    do ir = 1, r_ndump
      k = 1 + h_offset(ir)
      call decode_header(data(k))
      r_mobil(ia) = .false.
      ip = mod(ip-1, np) + 1 
      ic = 1
      t = timeIntervalRecord(ir)%time
      do while (isOutside(t, splitTimeInterval(pKey%timeInterval, np, ip)) &
           .and. ic.le.np+1)
        ip = mod(ip, np) + 1
        ic = ic+1
      enddo
      ipm = 1
      if (ic.le.np+1) then
        if ( pKey%antennaId .eq. antenna_Id(ia)) then
          ipm = ip
        endif
      else
        
        call message(8,2,'Read_sdm','Times do not match')
      endif
      !
      ! interpolate with time neighbours
      !
      ip = ipm
      spdir = 0
      senc = 0
      soff = 0
      dt = pKey%timeInterval%interval/np
      !
      ! first try with nearest points
      next = 1
      do while (next.le.np .and. next.gt.0)
        sw = 0
        ip1 = max(1, ip-next)
        ip2 = min(ip+next, np)
        do j= ip1, ip2
          tsplit = splitTimeInterval(pKey%timeInterval, np, j)
          tj = tsplit%time
          adt = abs(t-tj)
          w = 0
          if (pRow%encoder(1,j).ne.0 .or. pRow%encoder(2,j).ne.0) then
            w = max(0,next*dt-adt)
            spdir(1) = spdir(1)+ pRow%pointingDirection(1,j)*w
            spdir(2) = spdir(2)+ pRow%pointingDirection(2,j)*w
            senc(1) = senc(1)+ pRow%encoder(1,j)*w
            senc(2) = senc(2)+ pRow%encoder(2,j)*w
            soff(1) = soff(1)+ pRow%offset(1,j)*w
            soff(2) = soff(2)+ pRow%offset(2,j)*w
          endif
          sw = sw+ w
        enddo
        if (sw.gt.0) then
          spdir(1) = spdir(1)/ sw
          spdir(2) = spdir(2)/ sw
          senc(1) = senc(1)/ sw
          senc(2) = senc(2)/ sw
          soff(1) = soff(1)/ sw
          soff(2) = soff(2)/ sw
          next = -1              ! done
        else
          next=next*2
        endif
        
      enddo
      it = (ip-1) * dt !
      ! T10 time in seconds in subscan
      dh_test1(1,ia) = 1d-9*it
      ! T11, T12: encoders (radians)
      dh_test1(2,ia) =pRow%encoder(1,ip)
      dh_test1(3,ia) =pRow%encoder(2,ip)
      ! T13, T14 : trackinf errors in arc seconds
      dh_test1(4,ia) =(pRow%encoder(1,ip)-pRow%pointingDirection(1,ip))   &
           /pi*180.*3600.
      dh_test1(5,ia) =(pRow%encoder(2,ip)-pRow%pointingDirection(2,ip))   &
           /pi*180.*3600.
      !
      !     This is the source direction as seen from antenna
      !     Keep for the CLIC Header
      r_az = pRow%target(1,1)
      r_el = pRow%target(2,1)
      !
      !     Compute offsets i.e. in the system of origin p%target.
      !
      psi = pi/2 + pRow%target(1,ip)
      the = - pRow%target(2,ip)
      phi = -pi/2.
      s_2 = senc
      call rect(s_2, x_2)
      call eulmat (psi, the, phi, trfm_26)
      call matvec (x_2, trfm_26, x_6)
      call spher(x_6, s_6)
      !dh_offlam(ia) = s_6(1)/ radpersec
      !dh_offbet(ia) = s_6(2)/ radpersec
      ! use the offset column 
      dh_offlam(ia) = soff(1)/ radpersec
      dh_offbet(ia) = soff(2)/ radpersec
      !
      !     These are the antenna tracking errors:
      do k=1, 2
        dh_rmspe(k,ia) = (senc(k)-spdir(k)) / radpersec
      enddo
      ! Do not read the pointingModelId for now.
      !         pointingModel_Id(ia) = p%pointingModelId
      !
      ! scanning stuff
!!!       minlam = min(minlam,dh_offlam(ia)*pi/180./3600.)
!!!       maxlam = max(maxlam,dh_offlam(ia)*pi/180./3600.)
!!!       minbet = min(minbet,dh_offbet(ia)*pi/180./3600.)
!!!       maxbet = max(maxbet,dh_offbet(ia)*pi/180./3600.)
      k = 1 + h_offset(ir)
      call encode_header(data(k))
    enddo

!    if (maxlam-minlam.gt.0.1*pi/180./3600.) then
!      r_mobil(ia) = .true.
!      if (r_scaty.le.3) r_scaty = scan_lamb
!    endif
!    if (maxbet-minbet.gt.0.1*pi/180./3600.) then
!      r_mobil(ia) = .true.
!      if (r_scaty.le.3) r_scaty = scan_beta
!    endif
    
  enddo
  call sdmMessage(1,1,sdmTable ,'Read.')
  return
  !
99 error = .true.
end subroutine get_sdm_pointing
!---------------------------------------------------------------------
subroutine get_sdm_pointingHoloData(ndata, data, timeIntervalSubscan, timeIntervalRecord, error)
  use gkernel_interfaces
  !---------------------------------------------------------------------
  !     Read data needed from the SDM table. 
  !     pRow is the row for the subscan...
  !---------------------------------------------------------------------
  use gildas_def
  use sdm_pointing
  use sdm_types 
  ! Global variables:
  include 'clic_parameter.inc'
  include 'clic_par.inc'
  include 'clic_dheader.inc'
  include 'sdm_identifiers.inc'
  include 'gbl_pi.inc'
  ! Dummy
  logical :: error, isOutside
  integer :: ndata, data(ndata)
  type(ArrayTimeInterval) :: timeIntervalSubscan, splitTimeInterval
  type(ArrayTimeInterval) :: timeIntervalRecord(r_ndump)
  ! Local
  type(ArrayTimeInterval) :: tsplit 
  type (PointingRow) :: pRow
  type (PointingKey) :: pKey
  integer :: ia, ip, k, np, ip1, ip2, j, next, pSize, ir, ic, h_offset, ipm, i
  integer*8 :: t, tj, dt, adt, it
  character, parameter :: sdmTable*8 = 'Pointing'
  real*8 ::  x_2(3), x_6(3), s_2(2), s_6(2), trfm_26(3,3), psi, the,   &
    phi, radpersec, spdir(2), senc(2), soff(2), w, sw, minlam, maxlam, minbet, maxbet
  real*8::  target_Hack(2)
  logical:: first
  data first/.true./
  save target_Hack, first
  integer, parameter :: scan_lamb = 2, scan_beta = 3
  !---------------------------------------------------------------------
  call sdmMessage(1,1,sdmTable ,'starting...')
  pRow%numTerm = timeIntervalSubscan%interval / 48000000
  pRow%numSample = pRow%numTerm
  !print *, 'pRow%numTerm ', pRow%numTerm
  call allocPointingRow(pRow, error)
  if (error) return
  radpersec = pi/180d0/3600d0

  !np = size(p%target,3)
  !t = time_interval(1)
  !      print *, 'np ',np
  pKey%timeInterval = timeIntervalSubscan
  
  do ia = 1, r_nant
    pKey%antennaId = antenna_Id(ia)
    !print *, 'pKey%antennaId, pKey%timeInterval ', pKey%antennaId, pKey%timeInterval
    ! TEMPORARY HOLO PATCH 
    !! REMOVE !! pKey%timeInterval%time = pKey%timeInterval%time+6000000
    !print *, 'pKey%antennaId, pKey%timeInterval ', pKey%antennaId, pKey%timeInterval
    call getPointingRow(pKey, pRow, error)
    if (error) return

    if (first) then
      target_Hack(1) = pRow%target(1,1)
      target_Hack(2) = pRow%target(2,1)
      first = .false.
    endif

    !! print *, 'pKey%antennaId, pKey%timeInterval ', pKey%antennaId, pKey%timeInterval
    ip = 1
    np = pRow%numSample
    !!print *, ' pRow%numSample ', pRow%numSample

!! REMOVE HACK !! 
!!    do  i =1, np
!!      pRow%target(1,i)=target_Hack(1)
!!      pRow%target(2,i)=target_Hack(2)
!!    enddo
!! REMOVE HACK !! 
      !!print *, '=== ', pRow%target

    minlam = 1e20
    minbet = 1e20
    maxlam = -1e20
    maxbet = -1e20
    do ir = 1, r_ndump
      k = 1 + h_offset(ir)
      call decode_header(data(k))
      r_mobil(ia) = .false.
      ip = mod(ip-1, np) + 1 
      ic = 1
      t = timeIntervalRecord(ir)%time
      !do while (isOutside(time, pRow%timeInterval(ip)) .and.   &
      !print *, 'ir, t, pKey%timeInterval%time'
      !print *, ir, t, pKey%timeInterval%time
      do while (isOutside(t, splitTimeInterval(pKey%timeInterval, np, ip)) .and.   &
           ic.le.np+1)
        ip = mod(ip, np) + 1
        ic = ic+1
      enddo
      ipm = 1
      if (ic.le.np+1) then
        if ( pKey%antennaId .eq. antenna_Id(ia)) then
          ipm = ip
          !print *, 'ir, time, split, ipm ', ir, time,  splitTimeInterval(pKey%timeInterval, np, ipm), ipm
        endif
      else
        !print *, 'ir, t, np, ip, ic'
        !print *, ir, t, np, ip, ic
        
        call message(8,2,'Read_sdm','Times do not match')
!!!       print *, ip, p%timeInterval(1)%time, p%timeInterval(np   &
!!!         )%time, p%timeInterval(1)%time + p%timeInterval(np   &
!!!         )%interval
      endif
      !
      ! interpolate with time neighbours
      !
      !print *, 'ir, ipm ',ir, ipm
      ip = ipm
      spdir = 0
      senc = 0
      soff = 0
      !dt = pRow%timeInterval(1)%interval
      dt = pKey%timeInterval%interval/np
      !if (ip.le.10) print *, '= ip, ip1, ip2, dt ', ip, ip1, ip2, dt
      !if (ip.le.30) print *, '= ip, encoder, pointingDir, target ', ip, pRow%encoder(1,ip), pRow%pointingDirection(1,ip), &
      !     pRow%target(1,ip)
      !if (ip.le.30) print *, '= ip, encoder, pointingDir, target ', ip, pRow%encoder(2,ip), pRow%pointingDirection(2,ip), &
      !     pRow%target(2,ip)
      
      ! first try with nearest points
      next = 1
      do while (next.le.np .and. next.gt.0)
        sw = 0
        ip1 = max(1, ip-next)
        ip2 = min(ip+next, np)
        do j= ip1, ip2
          !tj = pRow%timeInterval(j)%time
          tsplit = splitTimeInterval(pKey%timeInterval, np, j)
          tj = tsplit%time
          adt = abs(t-tj)
          w = 0
          if (pRow%encoder(1,j).ne.0 .or. pRow%encoder(2,j).ne.0) then
            w = max(0,next*dt-adt)
            spdir(1) = spdir(1)+ pRow%pointingDirection(1,j)*w
            spdir(2) = spdir(2)+ pRow%pointingDirection(2,j)*w
            senc(1) = senc(1)+ pRow%encoder(1,j)*w
            senc(2) = senc(2)+ pRow%encoder(2,j)*w
            soff(1) = soff(1)+ pRow%offset(1,j)*w
            soff(2) = soff(2)+ pRow%offset(2,j)*w
          endif
          sw = sw+ w
          !if (ip.le.10) print *, '==  j, adt, w ', j, adt, w
        enddo
        if (sw.gt.0) then
          spdir(1) = spdir(1)/ sw
          spdir(2) = spdir(2)/ sw
          senc(1) = senc(1)/ sw
          senc(2) = senc(2)/ sw
          soff(1) = soff(1)/ sw
          soff(2) = soff(2)/ sw
          next = -1              ! done
        else
          !c               next = next+1
          next=next*2
          ! if (ip.le.10) print *, 'ip, next ', ip, next
        endif
        
      enddo
      it = (ip-1) * dt ! pKey%timeInterval(ip)%time-pKey%timeInterval(1)%time
      ! T10 time in seconds in subscan
      dh_test1(1,ia) = 1d-9*it
      ! T11, T12: encoders (radians)
      dh_test1(2,ia) =pRow%encoder(1,ip)
      dh_test1(3,ia) =pRow%encoder(2,ip)
      !print *, dh_test1(1,ia), dh_test1(2,ia), dh_test1(3,ia)
      !print *, ip, pRow%encoder(1,ip), pRow%encoder(2,ip)
      ! T13, T14 : trackinf errors in arc seconds
      dh_test1(4,ia) =(pRow%encoder(1,ip)-pRow%pointingDirection(1,ip))   &
           /pi*180.*3600.
      dh_test1(5,ia) =(pRow%encoder(2,ip)-pRow%pointingDirection(2,ip))   &
           /pi*180.*3600.
      !
      ! print *, ip, pRow%target(1,ip), pRow%target(2,ip)
      ! + PATCH
      ! take the target to be the first PointingDirection !!!
      !pRow%target(1,1) = pRow%pointingDirection(1,1)
      !pRow%target(2,1) = pRow%pointingDirection(2,1)
      ! take  the first point assumed to be the reference position
      !pRow%target(1,ip) = pRow%target(1,1)
      !pRow%target(2,ip) = pRow%target(2,1)
      ! - PATCH
      !
      !     This is the source direction as seen from antenna
      !     Keep for the CLIC Header
      r_az = pRow%target(1,1)
      r_el = pRow%target(2,1)
      !if (ip.le.10) print *, ir, senc, spdir, r_az, r_el 
      !
      !     Compute offsets i.e. in the system of origin p%target.
      !
      psi = pi/2 + pRow%target(1,ip)
      the = - pRow%target(2,ip)
      phi = -pi/2.
      !         s_2 = (/ p%encoder(1,ip), p%encoder(2,ip)/)
      s_2 = senc
      call rect(s_2, x_2)
      call eulmat (psi, the, phi, trfm_26)
      call matvec (x_2, trfm_26, x_6)
      call spher(x_6, s_6)
      dh_offlam(ia) = s_6(1)/ radpersec
      dh_offbet(ia) = s_6(2)/ radpersec
      !! if (ip.le.10) print *, ir, dh_offlam(ia), dh_offbet(ia)
      ! use the offset column 
      !!dh_offlam(ia) = soff(1)/ radpersec
      !!dh_offbet(ia) = soff(2)/ radpersec
      !if (ip.le.10) print *, ir, senc, spdir, soff, dh_offlam(ia), dh_offbet(ia)
      !
      !     These are the antenna tracking errors:
      !$$$         dh_rmspe(1,ia) = (p%encoder(1,ip)-p%pointingDirection(1,1,ip))
      !$$$     &        / radpersec
      !$$$         dh_rmspe(2,ia) = (p%encoder(2,ip)-p%pointingDirection(2,1,ip))
      !$$$     &        / radpersec
      do k=1, 2
        dh_rmspe(k,ia) = (senc(k)-spdir(k)) / radpersec
      enddo
      ! Do not read the pointingModelId for now.
      !         pointingModel_Id(ia) = p%pointingModelId
      !
      ! scanning stuff
      minlam = min(minlam,dh_offlam(ia)*pi/180./3600.)
      maxlam = max(maxlam,dh_offlam(ia)*pi/180./3600.)
      minbet = min(minbet,dh_offbet(ia)*pi/180./3600.)
      maxbet = max(maxbet,dh_offbet(ia)*pi/180./3600.)
      k = 1 + h_offset(ir)
      call encode_header(data(k))
    enddo

    if (maxlam-minlam.gt.0.1*pi/180./3600.) then
      r_mobil(ia) = .true.
      if (r_scaty.le.3) r_scaty = scan_lamb
    endif
    if (maxbet-minbet.gt.0.1*pi/180./3600.) then
      r_mobil(ia) = .true.
      if (r_scaty.le.3) r_scaty = scan_beta
    endif
    
  enddo
  call sdmMessage(1,1,sdmTable ,'Read.')
  return
  !
99 error = .true.
end subroutine get_sdm_pointingHoloData
!--------------------------------------------------------------------
logical function isOutside(time, timeInterval)
  use sdm_types
  integer*8 :: time, t2
  type(ArrayTimeInterval) :: timeInterval
  !
  isOutside = .false.
  if (time.lt.timeInterval%time) then
    isOutside = .true.
    return
  !
  ! makes sure this work for the last interval (may be not always...)
  elseif (time.ge.timeInterval%time) then
    t2 = time - timeInterval%time
    !$$$         if (timeInterval%interval.gt.24000000) print *, t2,
    !$$$     &        timeInterval%interval
    if (t2.gt.timeInterval%interval) then
      isOutside = .true.
      return
    endif
  endif
end function isOutside
!
function splitTimeInterval(timeInterval, n, i)
  use sdm_types
  integer :: n, i
  type(ArrayTimeInterval) :: timeInterval, splitTimeInterval
  integer*8 :: time, interval
  !
  interval = timeInterval%interval / n
  time = timeInterval%time + (i-1)*interval 
  splitTimeInterval = ArrayTimeInterval(time, interval)
end function splitTimeInterval
