subroutine write_sdm_scan(error)
  !---------------------------------------------------------------------
  !     Write the  Scan & Subscan  table.
  !
  !---------------------------------------------------------------------
  use gildas_def
  use sdm_Scan
  ! 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 (ScanRow) :: sRow
  type (ScanKey) :: sKey
  type (ScanOpt) :: sOpt
  character, parameter :: sdmTable*4 = 'Scan'
  !---------------------------------------------------------------------
  call sdmMessage(1,1,sdmTable ,'starting...')
  !
  ! now allocate
  sRow%numIntent = 1
  call allocScanRow(sRow, error)
  if (error) return
  !
  sRow%flagRow = .false.
  !     *TBD* Why fieldName???
  !CC SS2 Now its SourceName ...
  !CC SourceName now optional (2006-11-22)
  !      sRow%sourceName = r_sourc //char(0)
  !     Write the PREVIOUS scan and reset startTime, numSubScan:
  sRow%startTime = scan_startTime
  sRow%endTime = scan_endTime
  sKey%execBlockId = execBlock_Id
  sKey%scanNumber = scan_Number
  sRow%numSubScan = num_SubScan
  sRow%scanIntent(1) = scan_Intent
  sRow%calDataType(1) = data_type
  sRow%calibrationOnLine = .true.
  call addScanRow(sKey, sRow, error)
  if (error) return
  !
  ! one field for each scan...
  sOpt%numField = 1
  call allocScanOpt(sRow, sOpt, error)
  !     add source name,( not agreed on long term solution)
  sOpt%sourceName = r_sourc //char(0)
  call addscanSourceName(sKey, sOpt, error)
  if (error) return
  sOpt%fieldName(1) = field_name//char(0)
  call addscanFieldName(sKey, sOpt, error)
  if (error) return
  !
  !     Note: should possibly add the fieldName ( a vector).
  call sdmMessage(1,1,sdmTable ,'Written.')
  return
end subroutine write_sdm_scan
!
subroutine write_sdm_subscan(holodata, error)
  !---------------------------------------------------------------------
  !     Write the  Scan & Subscan  table.
  !
  !---------------------------------------------------------------------
  use gildas_def
  use sdm_Subscan
  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, holodata
  ! Local
  type (SubscanRow) :: ssRow
  type (SubscanKey) :: ssKey
  character, parameter :: sdmTable*16 = 'Scan & Subscan'
  !---------------------------------------------------------------------
  call sdmMessage(1,1,sdmTable ,'starting...')
  !
  ssRow%StartTime = time_Interval(1)
  ssRow%EndTime = time_Interval(1)+time_Interval(2)
  ! SS2 NOW OPTIONAL...      ssRow%subscanMode = '*TBD*'
  if (holodata) then
    ssRow%numberIntegration = r_ndump
  else
    ssRow%numberIntegration = 1
  endif
  call allocSubScanRow(ssRow, error)
  if (error) return
  if (holodata) then
    ssRow%numberSubintegration = 0
  else
    if (r_nswitch.gt.0) then
      ssRow%numberSubintegration = r_ndump/r_nswitch
    else
      ssRow%numberSubintegration = r_ndump
    endif
  endif
  ssRow%flagRow = .false.
  ssRow%fieldName = field_name //char(0)
  ssKey%execBlockId = execBlock_Id
  ssKey%scanNumber = scan_Number
  ssKey%subScanNumber = subscan_Number
  ssRow%subscanintent = subscan_Intent
  call addSubScanRow(ssKey, ssRow, error)
  if (error) return
  call sdmMessage(1,1,sdmTable ,'Written.')
  return
end subroutine write_sdm_subscan
!---------------------------------------------------------------------
subroutine get_sdm_scan(error)
  use gkernel_interfaces
  !---------------------------------------------------------------------
  !     Read the Source Scan  table.
  !
  !     Key: (execBlockId, scanNumber)
  !
  !---------------------------------------------------------------------
  use gildas_def
  use sdm_Scan
  use sdm_Subscan
  use sdm_State
  ! 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 (ScanRow) :: sRow
  type (ScanKey) :: sKey
  type (SubscanRow) :: ssRow
  type (SubscanKey) :: ssKey
  type (StateRow) :: stRow
  type (StateKey) :: stKey
  integer, parameter :: mIntegration=256   !?
  integer lenz, maxIntent
  character, parameter :: sdmTable*16 = 'Scan & Subscan'
  !---------------------------------------------------------------------
  call sdmMessage(1,1,sdmTable ,'starting...')
  !
  ! now allocate
  !!maxIntent = 10
  sRow%numIntent = 10
  !!call allocScanRow(sRow, maxIntent, error)
  call allocScanRow(sRow, error)
  if (error) return
  sRow%flagRow = .false.
  ! *TBD* Why fieldName???
  !$$$      print *, 'execBlock_Id ', execBlock_Id
  sKey%execBlockId = execBlock_Id
  sKey%scanNumber = scan_Number
  call getScanRow(sKey, sRow, error)
  if (error) then
    print *, 'sKey ', sKey
  endif
  if (error) return
  num_SubScan = sRow%numSubScan
  r_scan = scan_Number
  ssRow%numberIntegration = mIntegration
  !call allocSubScanRow(ssRow, mIntegration, error)
  call allocSubScanRow(ssRow, error)
  if (error) return
  !
  ssKey%execBlockId = execBlock_Id
  ssKey%scanNumber = scan_Number
  ssKey%subScanNumber = subscan_Number
  !
  call getSubScanRow(ssKey, ssRow, error)
  if (error) return
  r_ndump  = ssRow%numberSubintegration(1)
  !
  ! NEED to get the STATE row
  call get_intent(srow%numIntent, srow%scanIntent,   &
    ssRow%subScanIntent, stRow%calDeviceName)
  call sdmMessage(1,1,sdmTable ,'Read.')
  return
  !
99 error = .true.
end subroutine get_sdm_scan
!---------------------------------------------------------------------
integer function lenz(c)
  character*(*) c
  integer i
  lenz = len(c)
  i = index(c,char(0))
  if (i.gt.0) lenz = min(lenz,i-1)
end function lenz
!---------------------------------------------------------------------
subroutine set_intent(scanIntent, subScanIntent, deviceName, calDataType, holodata)
  use sdm_Types
  use sdm_Enumerations
  include 'clic_parameter.inc'
  include 'clic_par.inc'
  integer :: scanIntent, subScanIntent, deviceName, calDataType
  logical :: holodata
  ! CALIBRATION
  subscanIntent = SubscanIntent_UNSPECIFIED    
  scanIntent = ScanIntent_UNSPECIFIED  
  calDataType = CalDataOrigin_CHANNEL_AVERAGE_CROSS 
  deviceName = CalibrationDevice_NONE
  if (r_cproc.eq.'CALI') then
    scanIntent = ScanIntent_CALIBRATE_ATMOSPHERE 
    calDataType = CalDataOrigin_TOTAL_POWER 
    ! put in State ...
    if (r_scaty.eq.5) then
      deviceName = CalibrationDevice_NONE
    elseif (r_scaty.eq.7) then
      deviceName = CalibrationDevice_COLD_LOAD
    elseif (r_scaty.eq.4) then
      deviceName = CalibrationDevice_AMBIENT_LOAD
    endif
  elseif (r_cproc.eq.'SKYD') then
    scanIntent = scanintent_DO_SKYDIP 
    calDataType = CalDataOrigin_TOTAL_POWER 
    ! put in State ...
    if (r_scaty.eq.5) then
      deviceName = CalibrationDevice_NONE
    elseif (r_scaty.eq.4) then
      deviceName = CalibrationDevice_AMBIENT_LOAD
    endif
  elseif (r_cproc.eq.'FOCU') then
    scanIntent = scanintent_CALIBRATE_FOCUS 
    calDataType = CalDataOrigin_CHANNEL_AVERAGE_CROSS 
    if (r_scaty.eq.1) then
      scanIntent = scanintent_CALIBRATE_Focus    
    elseif (r_scaty.eq.11) then
      scanIntent = scanintent_CALIBRATE_Focus_X  
    elseif (r_scaty.eq.12) then
      scanIntent = scanintent_CALIBRATE_Focus_Y  
    endif
  elseif (r_cproc.eq.'POIN' .or. r_cproc.eq.'FIVE' ) then
    scanIntent = scanintent_CALIBRATE_POINTING   ! 
    calDataType = CalDataOrigin_CHANNEL_AVERAGE_CROSS 
  elseif (r_cproc.eq.'CORR') then
    calDataType = CalDataOrigin_CHANNEL_AVERAGE_CROSS 
    if (r_itype.eq.1) then
      scanIntent =  scanintent_OBSERVE_TARGET  ! 
    elseif (r_itype.eq.2) then
      scanIntent = scanintent_CALIBRATE_PHASE  ! 'Phase, Amplitude'
    endif
  end if
  !
  ! Holography (from ATF/OSF)
  if (holodata) then
    scanIntent = scanintent_MAP_ANTENNA_SURFACE 
    calDataType = CalDataOrigin_HOLOGRAPHY
    if (r_cproc.eq.'HOLO') then
      subscanIntent= subscanintent_SCANNING   
    elseif (r_cproc.eq.'CORR') then
      subscanIntent=  subscanintent_REFERENCE   
    elseif (r_cproc.eq.'POIN') then
      subscanIntent= subscanintent_SCANNING     
    endif
  endif
  return
end subroutine set_intent
!---------------------------------------------------------------------
subroutine get_intent(numIntent, scanIntent, subscanIntent,   &
    deviceName)
  use sdm_Types
  use sdm_Enumerations
  include 'clic_parameter.inc'
  include 'clic_par.inc'
  integer :: scanIntent(numIntent), subScanIntent, deviceName
  logical :: isIntent
  integer :: numIntent, lenz, ls, lss
  character :: procname*4
  !
  ! TBD : this is not 100% full proof and tested...
  !     Calibration scans
  !
  if (isIntent(numIntent,scanIntent,scanintent_CALIBRATE_ATMOSPHERE)) then
    if (deviceName .eq. CalibrationDevice_NONE) then
      r_scaty = 5
    elseif (deviceName .eq. CalibrationDevice_COLD_LOAD) then
      r_scaty = 7
    elseif (deviceName .eq. CalibrationDevice_AMBIENT_LOAD) then
      r_scaty = 4
    endif
    r_cproc = 'CALI'
  elseif (isIntent(numIntent,scanIntent,scanintent_DO_SKYDIP)) then
    if (deviceName .eq. CalibrationDevice_NONE) then
      r_scaty = 5
    elseif (deviceName .eq. CalibrationDevice_AMBIENT_LOAD) then
      r_scaty = 4
    endif
    r_cproc = 'SKYD'
    r_itype = 2
  elseif (isIntent(numIntent,scanIntent,scanintent_CALIBRATE_FOCUS)) then
    r_scaty = 1
    r_cproc = 'FOCU'
    r_itype = 2
  elseif (isIntent(numIntent,scanIntent,scanintent_CALIBRATE_FOCUS_X)) then
    r_scaty = 11
    r_cproc = 'FOCU'
    r_itype = 2
  elseif (isIntent(numIntent,scanIntent,scanintent_CALIBRATE_FOCUS_Y)) then
    r_scaty = 12
    r_cproc = 'FOCU'
    r_itype = 2
  elseif (isIntent(numIntent,scanIntent,scanintent_CALIBRATE_POINTING))  then
    r_cproc = 'POIN'
    r_itype = 2
  elseif (isIntent(numIntent,scanIntent,scanintent_CALIBRATE_PHASE) .or.   &
    isIntent(numIntent,scanIntent,scanintent_CALIBRATE_ampli)) then
    if (r_lmode.ne.2) then
      r_cproc = 'CORR'
    else
      r_cproc = 'AUTO'
    endif
    r_itype = 2
  elseif (isIntent(numIntent,scanIntent,scanintent_MAP_ANTENNA_SURFACE)   &
       .or. isIntent(numIntent,scanIntent,scanintent_OBSERVE_TARGET)) &
       then
    if (subscanIntent .eq. subscanintent_SCANNING) then
       if (r_lmode.ne.2) then
          r_cproc = 'HOLO'
       else
          r_cproc = 'AUTO'
       endif
       r_itype = 2
    elseif  (subscanIntent.eq.  subscanintent_REFERENCE)   &
      then
       if (r_lmode.ne.2) then
          r_cproc = 'CORR'
       else
          r_cproc = 'AUTO'
       endif
       r_itype = 2
       !
       ! Dummy flux for calibration
       r_flux = 1.0
    endif
  else
    !
    !     source scans
    !
    r_itype = 1
    if (r_lmode.ne.2) then
      r_cproc = 'CORR'
    else
      r_cproc = 'AUTO'
    endif
  endif
  !
  r_proc = 23
  do while (r_proc.gt.0 .and. procname(r_proc).ne.r_cproc)
    r_proc = r_proc-1
  enddo
  return
end subroutine get_intent
!
logical*4 function isIntent(numIntent, scanIntent, intent)
  integer numIntent, i, scanIntent(numIntent), intent
  !
  isIntent = .false.
  do i=1, numIntent
    !         
    isIntent = isIntent .or. scanIntent(i).eq.intent
  enddo
  return
end function isIntent
