	PRO GETCDSTIMES, RASTER, TIMES
;+
; Project     :	SOHO - CDS
;
; Name        :	GETCDSTIMES
;
; Purpose     :	Get the times for the FITS files from the telemetry.
;
; Explanation :	Extract the start and end date/times from the telemetry.  If
;		available, the exact date and times are used.  Otherwise, if
;		the relevant exposure header is missing, then a linear fit is
;		made to the available time stamps to extrapolate the start
;		and/or end time.  Also optionally calculates the delta times.
;
; Use         :	GETCDSTIMES, RASTER, TIMES
;
; Inputs      :	RASTER = Structure variable from READ_RASTER, containing all
;			 the metadata extracted from the science telemetry
;			 stream pertaining to the raster.
;
; Opt. Inputs :	None.
;
; Outputs     :	TIMES  = Structure variable containing the following tags:
;
;			DATE_OBS = The date and time of the start of the
;				   raster, taking into account the time delay
;				   between the spacecraft and the earth, in
;				   CCSDS format.
;			DATE_END = The date and time of the end of the raster,
;				   taking into account the exposure duration,
;				   in CCSDS format.
;			DEL_TIME = The delta times for each exposure, starting
;				   from the start time.  Any missing values are
;				   signalled by -1.
;			OBT_TIME = The on-board time corresponding to DATE_OBS.
;			OBT_END  = The on-board time corresponding to DATE_END.
;			PARAM	 = A linear fit to the exposure start times.
;				   Used for the TRVAL and TDELT keywords in the
;				   FITS header.
;
; Opt. Outputs:	None.
;
; Keywords    :	None.
;
; Calls       :	None.
;
; Common      :	None.
;
; Restrictions:	None.
;
; Side effects:	None.
;
; Category    :	Data_handling, Telemetry, I/O, FITS, CDS.
;
; Prev. Hist. :	None.
;
; Written     :	William Thompson, GSFC, 20 October 1994
;
; Modified    :	Version 1, William Thompson, GSFC, 4 January 1995
;		Version 2, William Thompson, GSFC, 1 March 1995
;			Added PARAM to output structure.
;			Fixed calculation of DATE_END.
;		Version 3, William Thompson, GSFC, 7 March 1995
;			Changed way PARAM is calculated to make it more
;			accurate.
;		Version 4, William Thompson, GSFC, 10 March 1995
;			Added test for a single exposure header when calling
;			POLY_FIT.
;		Version 5, William Thompson, GSFC, 4 December 1995
;			Added calculation of time delay.
;		Version 6, William Thompson, GSFC, 10 April 1996
;			Better handle case where no exposure headers were
;			found.
;		Version 7, William Thompson, GSFC, 2 May 1996
;			Use /BELL instead of /ATTENTION
;		Version 8, William Thompson, GSFC, 9 Dec 1997
;			Handle better when only one exposure was seen.
;		Version 9, William Thompson, GSFC, 5 Jan 1998
;			Use keyword NOZ in call to TAI2UTC to follow new FITS
;			convention.
;
; Version     :	Version 9, 5 Jan 1998
;-
;
	ON_ERROR, 2
;
;  Check the number of parameters.
;
	IF N_PARAMS() NE 2 THEN MESSAGE, 'Syntax:  GETCDSTIMES, RASTER, TIMES'
;
;  Extract the number of exposures, and the exposure start times.
;
	N_EXPOSURES = (RASTER.HEADER.SCI.NUMMIRRORPOS > 1) *	$
		(RASTER.HEADER.SCI.NUMSLITPOS > 1)
	EXPSTARTTIME = OBT2TAI(RASTER.STARTTIME)
;
;  Do a linear fit to the available start times.
;
	W = WHERE(RASTER.HEADERFOUND EQ 1, COUNT)
;
;  That is, assuming that there are any available start times.  If there isn't,
;  then use the last packet time.
;
	IF COUNT EQ 0 THEN BEGIN
		EXPSTARTTIME(0) = DEFCDSTIME()
		W = 0
	ENDIF
;
;  Do the fit in a coordinate system where the times are clustered around zero.
;  This leads to a more accurate result.
;
	X = DINDGEN(N_ELEMENTS(EXPSTARTTIME))
	Y = EXPSTARTTIME
	Y_AVG = AVERAGE(Y(W))
	IF N_ELEMENTS(W) GT 1 THEN BEGIN
		PARAM = POLY_FIT(X(W),Y(W)-Y_AVG,1)
		PARAM(0) = PARAM(0) + Y_AVG
;
;  If there's only one start time, then assume that the exposures are separated
;  by the exposure time.  To avoid placing a study out of place, assume that
;  the exposure time is given in units of 0.01 seconds.
;
	END ELSE BEGIN
		EXPOSURETIME = RASTER.HEADER.SCI.EXPOSURETIME / 100.D0
		PARAM = [Y(W) - W*EXPOSURETIME, EXPOSURETIME]
	ENDELSE
;
;  Get the start time.
;
	IF RASTER.HEADERFOUND(0) THEN BEGIN
		OBT_TIME = EXPSTARTTIME(0)
	END ELSE BEGIN
		OBT_TIME = PARAM(0)
	ENDELSE
;
;  Get the time delay between the spacecraft and the Earth.  This will be added
;  to DATE_OBS and DATE_END.
;
	MESSAGE = ''
	DELAY = GET_TIME_DELAY(OBT_TIME, ERRMSG=MESSAGE)
	IF DELAY LT 0 THEN BEGIN
		DELAY = 0
		CDS_MESSAGE, MESSAGE, /CONTINUE, /BELL
	ENDIF
	DATE_OBS = TAI2UTC(OBT_TIME + DELAY, /CCSDS, /NOZ)
;
;  Get the end time, taking into account the exposure time.  Assume that the
;  last start time found is the true end of the raster.  Note that the units of
;  the exposure time for the VDS detector may be different than this.  If so,
;  it will be corrected later.
;
	LAST_START_TIME = EXPSTARTTIME(MAX(W))
	OBT_END = LAST_START_TIME + RASTER.HEADER.SCI.EXPOSURETIME/10.D0
	DATE_END = TAI2UTC(OBT_END + DELAY, /CCSDS, /NOZ)
;
;  Get the delta times.
;
	DEL_TIME = EXPSTARTTIME - OBT_TIME
	W = WHERE(RASTER.HEADERFOUND EQ 0, COUNT)
	IF COUNT NE 0 THEN DEL_TIME(W) = -1
;
;  Store the information in the output structure and return.
;
FINISH:
	TIMES = {DATE_OBS: DATE_OBS,	$
		 DATE_END: DATE_END,	$
		 DEL_TIME: DEL_TIME,	$
		 OBT_TIME: OBT_TIME,	$
		 OBT_END:  OBT_END,	$
		 PARAM:	   PARAM}
	RETURN
	END
