
;+
; Project     :	SOHO - CDS
;
; Name        :	CPT_FLAGS
;
; Purpose     :	Prepares the CDS command tables from the flags science plan.
;
; Explanation :	This routine interrogates the databases describing the flags plan
;               and produces the tables needed to implement the plan on the
;               CDS. It returns a structure array containing the relevant information
;               for each flag study.
;               The start and stop times of the flag studies in the sci_flags database 
;               correspond to those of detailed studies. The period defined by the start and stop 
;               times for a flag study may span a number of detailed studies. This period  
;               represents the period for which the flag study may be kicked off by a detailed
;               study. It is not related to the flag study duration.
;               This routine extracts the flag studies for the period of interest and makes sure 
;               the CDHS tables for these are loaded.
;               Flag studies must be of a fixed type so that the initial mirror and slit 
;               positions can be modified at run time and so that the calling series can insert 
;               an appropriate ID for a following study into the series table.
;
;               The values set up outside the series tables for normal studies will not
;               be changed for a flag study though special prevision is made for the
;               pointing.
;               The flag studies may have event, fixed or deferred pointing. 
;               The slit number used by the flag study should be the same as that 
;               of the calling study since the slit number will not be changed.
;               The flag study should use the same gsetid as the calling study
;               since the GIS lookup tables will not be changed.
;               Engineering or special studies cannot at present be used as flag studies.
;               The flag study should contain only a single raster which may be repeated
;               using the nrasters1 mechanism.
;               Flag studies do not at present jump back to the calling series.
;
; Use         :	<cpt_flags, ltb_unit, flags_list, range, flag_studies, cut_off_time> 
;
; Inputs      :	ltb_unit     : logical unit for LTB file.
;               flags_list   : structure array of studies from sci_flags database.
;               range        : integer giving acceptable range of mirror and slit movements.
;               flag_studies : initialized structure array of size nflags 
;                                 Tags :
;                                    cdhsid      : CDHS ID of flag study (0 if no flag study)
;                                    cdhsx       : CDHS index of flag study
;                                    repoint     : Integer tag indicating whether OPS 
;                                                  repointing allowed.
;                                    pointing    : String indicating type of pointing for flag study.
;                                    detector    : character indicating detector for flag study.
;               cut_off_time : DOUBLE TAI format time before which tables may be overwritten
;
; Opt. Inputs : None.
;
; Outputs     : Produces the various CVT files needed for the flag studies.
;               flag_studies : list of relevant information on flag series tables 
;
; Opt. Outputs:	None.
;
; Keywords    : None.
;
; Calls       :	get_study, get_raster, get_datawin,
;               chk_fund_series, get_series_info, get_raster_info,
;               get_dexwin_info, get_vdswin_info,
;               wr_vdswin_file, wr_dexwin_file, wr_raster_file, wr_series_file,
;               anytim2cal, wr_ltb.
;                
; Common      :	None.
;
; Restrictions:	None.
;
; Side effects:	None.
;
; Category    :	Command preparation.
;
; Prev. Hist. :	None.
;
; Written     :	Version 0.0, Martin Carter, RAL, 29/9/95
;                            Adapted from cpt_details.
;                            
; Modified    :	Version 0.1, 11/10/95, MKC
;                            Corrected bug dealing with GIS exposure time.
;                       0.2, 18/10/95, MKC
;                            Corrected addition of VDS_OFFSETS and vds_centre tag logic.
;                       0.3, 1/11/95, MKC
;                            Added check that full VDS window not required before adding in VDS offsets.
;                       0.4, 3/11/95, MKC
;                            Changed so that returns only the flag study array.
;                       0.5, 7/11/95,MKC
;                            Added checks on study.
;                            Removed .dur tag from series.
;                            Changed to hard fail on bad .repn
;                       0.6, 21/11/95
;                            Modified so that VDS_STATE is part of vdswin structure and vdswin_id
;                            database.
;                       0.7, 23/11/95
;                            Fixed bug in raster span calculation
;                       0.8, 5/12/95
;                            Changed to mirror and slit spans
;                            Added engineering studies.
;                            Added dsolx and dsoly tags to series structure.
;                            Added range to argument list.            
;                       0.9, 14/12/95
;                            Added reverse study processing.
;                       1.0, 3/1/96
;                            Added flag study tag to series structure.
;                       1.1, MKC, 19/2/96
;                            Replaced vds_offset calculation with update_dex .
;                            Removed vds_state from argument list.
;                            Modified vdswin_id database.      
;                       1.2, MKC, 15/3/96
;                            Modified use of update_dex to include the gsetid and to refer to GIS windows also.
;                       1.3, MKC, 3/10/96
;                            Added cut off time to allow previous tables to be overwritten.
;                            Put back a tag giving following study cdhs id and used instead of fseries where appropriate.
;
; Version     :	Version 1.3, 3/10/96
;-
;**********************************************************

PRO cpt_flags, ltb_unit, flags_list, range, flag_studies, cut_off_time

  ; set up initial dummy values for following series

  fseries = {SERIES_STRUCTURE}
  fseries.cdhsid = -1          ; set invalid CDHS ID
  fseries.tt     = 1           ; set next study time tagged

  ; set no. of flag studies 

  nflags = N_ELEMENTS(flags_list)

  ; loop through studies within next CDS period innormal order
  ; NB loop includes extra study added for emergency operation

  FOR stdyno = 0, nflags-1 DO BEGIN

    PRINT, ''
    PRINT, 'FLAG STUDY ', stdyno
    PRINT, ''

    ; extract flag study details

    get_flag, flags_list(stdyno).rcvr_start, flag_details

    ; print some study details

    PRINT, 'STUDY OBJECTIVE     : ', flag_details.sci_obj
    PRINT, 'TIME OF OBSERVATION : ', ANYTIM2CAL ( flag_details.rcvr_start )
    PRINT, ''
    
    ; extract study parameters

    get_study, flag_details.study_id, flag_details.studyvar, study_details

    ; perform any checks on study_details

    IF ( study_details.usable NE 'Y' ) THEN MESSAGE, 'Study not usable'

    ; check if special study

    IF study_details.n_raster_def EQ 0 THEN MESSAGE, 'Flag study cannot be special study'
      
    ; check no. of non-repeated rasters

    nrasters = N_ELEMENTS ( study_details.rasters )

    IF ( nrasters NE 1 ) THEN MESSAGE, 'Must have a single raster in a flag study'

    ; do raster

    ; get raster details

    get_raster, study_details.rasters(0).ras_id, $
                  study_details.rasters(0).ras_var, raster_details

    ; set up known raster table parameters

    raster = {RASTER_STRUCTURE}

    raster.id   = study_details.rasters(0).ras_id
    raster.var  = study_details.rasters(0).ras_var
    raster.time = flag_details.rcvr_start

    ; save detector  

    raster.detector = raster_details.detector

    ; set up exposure time and units

    set_exposure, raster_details.exptime, raster

    ; save slit number

    raster.slitn = raster_details.slit_num

    ; check slit number valid
    ; NB planning SW must ensure that the same slit number is used as in 
    ; the calling study ( ie slit no. will not be changed)

    IF (raster.slitn LT 1) OR (raster.slitn GT 6) THEN $
      MESSAGE, 'Invalid slit number used : ' + STRTRIM ( raster.slitn, 1)

    ; write mirror and slit spans to raster structure
    ; NB x/y steps from plannign database are in arcsecs rather than steps
    ;    spans are translated into steps

    raster.mirrorspan = ((raster_details.nx-1)*raster_details.xstep)/2

    raster.slitspan   = (raster_details.ny-1)*raster_details.ystep

    ; set up no. of times to execute raster

    raster.repn = study_details.rasters(0).n_repeat_r

    ; set repn to n_rasters1

    raster.repn = flag_details.n_rasters1

    ; check sensible no. of rasters

    IF raster.repn LE 0 THEN $
      MESSAGE, 'Invalid raster repeat number =' + STRTRIM ( raster.repn, 1)
      
    ; check if raster table already loaded for this study and get table info

    get_raster_info, raster, cut_off_time

    ; get data extraction window list details

    get_datawin, raster_details.dw_id, dexwin_details

    ; set up known dexwin table parameters

    dexwin = {DEXWIN_STRUCTURE}

    dexwin.id   = raster_details.dw_id
    dexwin.time = flag_details.rcvr_start

    ; modify dexwin values to reflect calibration
    ; get calibration version number
         
    dexwin_details.wins.win_def = update_dex ( dexwin_details.wins.win_def, GSET_ID=flags_list(stdyno).gset_id, VERSION = calibration_version ) 

    dexwin.version = calibration_version

    ; check if dexwin table already loaded for this study and get table info

    get_dexwin_info, dexwin, cut_off_time
   
    ; check if NIS detector

    IF dexwin_details.detector EQ 'N' THEN BEGIN

      ; check if vds windows loaded

      ; set up known vdswin table parameters

      vdswin = {VDSWIN_STRUCTURE}

      vdswin.id     = dexwin.id
      vdswin.time   = flag_details.rcvr_start
      vdswin.version = dexwin.version

      ; check if vdswin table already loaded for this study and 
      ; get table info

      get_vdswin_info, vdswin, cut_off_time
                    
      ; write out vdswin CVT file

      wr_vdswin_file, vdswin, dexwin_details

      ; set up vdswin list and increment current position

      IF N_ELEMENTS(vdswin_list) EQ 0 THEN vdswin_list = [ vdswin ] $
                                      ELSE vdswin_list = [ vdswin_list, vdswin ]

      ; set up more raster parameters

      raster.vdswid = vdswin.cdhsid

    ENDIF ELSE BEGIN

      ; GIS detector

      ; check which GIS detectors in use

      raster.gis ( dexwin_details.wins.win_def(0)/2048 ) = 1

    ENDELSE


    ; set up more raster parameters

    raster.dexwid = dexwin.cdhsid

    ; write out dexwin CVT file

    wr_dexwin_file, dexwin, dexwin_details

    ; set up dexwin list and increment current position

    IF N_ELEMENTS(dexwin_list) EQ 0 THEN dexwin_list = [ dexwin ] $
                                    ELSE dexwin_list = [ dexwin_list, dexwin ]

    ; write out raster CVT file

    wr_raster_file, raster, raster_details

    ; set up raster list and increment current position

    IF N_ELEMENTS(raster_list) EQ 0 THEN raster_list = [ raster ] $
                                    ELSE raster_list = [ raster_list, raster ]

    ; set up known series table parameters

    series = {SERIES_STRUCTURE}

    series.id     = flag_details.study_id
    series.var    = flag_details.studyvar  
    series.flagst = 'Y'
    series.range  = range
    series.time   = flag_details.rcvr_start
    series.rpt    = 'N'                        ; do not repeat study indefinitely   
    series.tt     =  0                         ; does not matter
    series.reus   = 'Y'                        ; flag studies may be re-used as flag studies

    ; set no. of times to repeat last raster and IEF flags

    series.repn = raster.repn

    ; check if solar feature tracking required

    IF flag_details.tracking THEN series.sft  = 'Y' ELSE series.sft  = 'N'

    ; set up initial state

    series.istate.slitn  = raster.slitn

    series.istate.gsetid = flags_list(stdyno).gset_id

    ; deal with pointing
    ; use pointing of first raster or of deferred pointing as label 

    IF flag_details.n_pointings EQ 0 THEN BEGIN

      ; fixed or event pointing

      series.istate.solarx = study_details.rasters(0).ins_x 
      series.istate.solary = study_details.rasters(0).ins_y

    ENDIF ELSE BEGIN

      ; deferred pointing

      series.istate.solarx = flag_details.pointings.ins_x 
      series.istate.solary = flag_details.pointings.ins_y

    ENDELSE

    ; set up following study id

    series.nextst = fseries.cdhsid

    ; check if series table already loaded for this study and 
    ; get table info 
    ; NB may return array of series structures

    get_series_info, series, cut_off_time

    ; write out series CVT file 
    ; NB may return array of series structures

    wr_series_file, series, fseries, flag_details, study_details, raster, cut_off_time

    ; set up series list and increment current position

    IF N_ELEMENTS(series_list) EQ 0 THEN series_list = [ series ] $
                                    ELSE series_list = [ series_list, series ]
  
    ; set up flag studies parameters

    flag_studies(stdyno).cdhsid      = series(0).cdhsid
    flag_studies(stdyno).cdhsx       = series(0).cdhsx
    flag_studies(stdyno).repoint     = flag_details.repoint
    flag_studies(stdyno).detector    = raster.detector

    ; If study_details.var_point=N then the fixed raster position is used for the flag study
    ; If study_details.var_point=Y then 
    ;    if flag_study_info.n_pointings = 0 use event position for flag study
    ;    if flag_study_info.n_pointings = 1 use deferred pointing

    IF study_details.var_point EQ 'N' THEN $
      flag_studies(stdyno).pointing  = 'FIXED' $
    ELSE IF flag_details.n_pointings EQ 0 THEN $
      flag_studies(stdyno).pointing  = 'EVENT' $
    ELSE $
      flag_studies(stdyno).pointing  = 'DEFERRED' 

  ENDFOR

  ; write out LTB file
  ; overwrites any existing file 

  PRINTF, ltb_unit, '# List of table indeces for sci_flags studies
  PRINTF, ltb_unit

  ; write out lists of tables used and to be loaded

  IF N_ELEMENTS ( series_list ) GT 0 THEN wr_ltb, ltb_unit, series_list, 'SERIES', 'NEWSERIES'
  IF N_ELEMENTS ( raster_list ) GT 0 THEN wr_ltb, ltb_unit, raster_list, 'RASTER', 'NEWRASTER'
  IF N_ELEMENTS ( dexwin_list ) GT 0 THEN wr_ltb, ltb_unit, dexwin_list, 'DEXWIN', 'NEWDEXWIN'
  IF N_ELEMENTS ( vdswin_list ) GT 0 THEN wr_ltb, ltb_unit, vdswin_list, 'VDSWIN', 'NEWVDSWIN'

  PRINTF, ltb_unit

END
