;+
; NAME:
;	bcs_dtfac
; PURPOSE:
;	to compute BSC deadtime correction factors
; CALLING SEQUENCE:
;	dt_fac=bcs_dtfac(bda_index,dp_sync,type,interp=interp)
; INPUTS:
;	dp_sync      - DP synchronous data
;	bda_index    - BDA index structures
;       type         - method of computing correction
; OUTPUTS:
;       dt_fac(4,n)  - deadtime factors by which to multiply spectral counts. 
; KEYWORDS:
;       interp       - 1 set zero deadtime factors to unity
;                    - 2 keep zero deadtime factors as zero
;                    - 3 interpolate out zero deadtime factors
; PROCEDURE          
;       Assumes the correction factor is LIM/ACC (type = 1) 
;       or SUM(LIM)/SUM(ACC) (type = 2) where the summation 
;       is taken over channels 1 & 2 or 3 & 4. The counts are corrected 
;       for their own deadtime before use. 
; RESTRICTIONS:
;       Must have dp_sync data 
; HISTORY:
;       Written by D. Zarro (ARC) Oct'92   -- based on D. Pike's DT_FACTOR
;-

function bcs_dtfac,bda_index,dp_sync,type,stime,etime,interp=interp

on_error,1

;-- check inputs

if (datatype(bda_index) ne 'STC') then $
 message,'usage --> DT_FAC=BCS_DTFAC(BDA_INDEX,DP_SYNC,TYPE,INTERP=INTERP)'

if datatype(dp_sync) ne 'STC' then begin
 message,'DP_SYNC data not entered; deadtime corrections not applied',/continue
 return,0
endif 

;-- check that DP_SYNC and BDA_INDEX times overlap

dok=bcs_dp_check(dp_sync,bda_index) 
if not dok then begin
 message,'DP_SYNC and BDA_INDEX times do not overlap; correction not applied',/contin
 return,0
endif

;
;  was method supplied?
;

if n_elements(type) eq 0 then type=1 
type=  (type < 2) & type=(type > 1)

;
;  set default limited events counter deadtime
;

lim_microsecs = 3.7
;
;  were times supplied? if not use all file, if yes then find indices
;  in index array
;

bdagen=bda_index.gen
stet=(n_elements(stime) eq 0) or (n_elements(etime) eq 0)
if stet then begin
   n1 = 0
   n2 = n_elements(bdagen.time) - 1
endif else begin
   ttime = bdagen.time/3600./1000. + (bdagen.day - bdagen(0).day)*24.
   ss = where( (ttime ge stime) and (ttime le etime) )
   if n_elements(ss) ge 2 then begin
      n1 = ss(0)
      n2 = ss(n_elements(ss)-1)
   endif else begin
      message,'No datasets found in that time range, returning.',/cont
      print,'PS. time range in this file is ',ttime(0),' to ',$
                   ttime(n_elements(bdagen.time)-1),$
                   ' Hrs UT',format='(a,f6.3,a,f6.3,a)'
      return,dt_fac
   endelse
endelse

;
;  and the same in the dp_sync arrays
;

if stet then begin
   d1 = 0
   d2 = n_elements(dp_sync.time) - 1
endif else begin
   ttime = dp_sync.time +(dp_sync.day - dp_sync(0).day)*86400L*1000L
   ttime = ttime/3600./1000. 
;
; compensate for different start days
;

if bdagen(0).day lt dp_sync(0).day then ttime = ttime + 24.0
if bdagen(0).day gt dp_sync(0).day then ttime = ttime - 24.0

   ss = where( (ttime ge stime) and (ttime le etime) )
   d1 = ss(0)
   d2 = ss(n_elements(ss)-1)
endelse

;
;  use chekov to correct overflows in LIM and ACC counts in all channels
;  and form mean of both counts
;
print,'Checking for counter overflows...'
chekov,3,2,dp_sync,lim4,dum
lim4 = (lim4 + dum)/2
chekov,3,3,dp_sync,acc4,dum
acc4 = (acc4 + dum)/2
chekov,2,2,dp_sync,lim3,dum
lim3 = (lim3 + dum)/2
chekov,2,3,dp_sync,acc3,dum
acc3 = (acc3 + dum)/2
chekov,1,2,dp_sync,lim2,dum
lim2 = (lim2 + dum)/2
chekov,1,3,dp_sync,acc2,dum
acc2 = (acc2 + dum)/2
chekov,0,2,dp_sync,lim1,dum
lim1 = (lim1 + dum)/2
chekov,0,3,dp_sync,acc1,dum
acc1 = (acc1 + dum)/2

;
;  correct for their own deadtime, using only the data requested to save time
;
print,'Correcting LIMited counts for counter deadtime...'
dt_corr,lim_microsecs,lim4(d1:d2),dum
lim4_dt = fltarr(n_elements(lim4))
lim4_dt(d1:d2) = dum

dt_corr,lim_microsecs,lim3(d1:d2),dum
lim3_dt = fltarr(n_elements(lim3))
lim3_dt(d1:d2) = dum

dt_corr,lim_microsecs,lim2(d1:d2),dum
lim2_dt = fltarr(n_elements(lim2))
lim2_dt(d1:d2) = dum

dt_corr,lim_microsecs,lim1(d1:d2),dum
lim1_dt = fltarr(n_elements(lim1))
lim1_dt(d1:d2) = dum

;
;  form the search index array
;

rm_idx = indgen(n2-n1+1) + n1

;
;  call routine to correlate INDEX and dp_sync times
;

bcs_dp_sync,dp_sync,bda_index,rm_idx,dp_idx

;
;  create the output factor array
;
dt_fac = fltarr(4,n_elements(bdagen.time))
;
;  set all to a safe value of 1.0
;

;-- default is to interpolate

if n_elements(interp) eq 0 then interp=3
if interp eq 1 then safe_val=1 else safe_val=0
dt_fac(*,*) = safe_val

if safe_val eq 1 then $
 message,'setting zero deadtime correction factors to unity',/contin

;
;  average the counts and form the ratios
;

case type of
   1: print,'Forming type 1 deadtime correction ratios in dt_fac(4,*)...'
   2: print,'Forming type 2 deadtime correction ratios in dt_fac(4,*)...'
endcase
for i=n1,n2 do begin
   if dp_idx(i,0) ge 0 and dp_idx(i,1) ge 0 then begin
      case type of
      1: begin

         d4=total(acc4(dp_idx(i,0):dp_idx(i,1)))
         if d4 eq 0. then dt_fac(3,i)=safe_val else $
          dt_fac(3,i)=total(lim4_dt(dp_idx(i,0):dp_idx(i,1)))/d4

         d3=total(acc3(dp_idx(i,0):dp_idx(i,1)))
         if d3 eq 0. then dt_fac(2,i) = safe_val else $
          dt_fac(2,i)=total(lim3_dt(dp_idx(i,0):dp_idx(i,1)))/d3

         d2=total(acc2(dp_idx(i,0):dp_idx(i,1)))
         if d2 eq 0. then dt_fac(1,i) =safe_val else $
          dt_fac(1,i)=total(lim2_dt(dp_idx(i,0):dp_idx(i,1)))/d2

         d1=total(acc1(dp_idx(i,0):dp_idx(i,1)))
         if d1 eq 0. then dt_fac(0,i) =safe_val else $
          dt_fac(0,i)=total(lim1_dt(dp_idx(i,0):dp_idx(i,1)))/d1

            end
      2: begin

         d3= (total(acc4(dp_idx(i,0):dp_idx(i,1)))+$
              total(acc3(dp_idx(i,0):dp_idx(i,1)))) 
         if d3 eq 0. then dt_fac(3,i) = safe_val else $
          dt_fac(3,i)=(total(lim4_dt(dp_idx(i,0):dp_idx(i,1)))+$
                       total(lim3_dt(dp_idx(i,0):dp_idx(i,1))))/d3

         dt_fac(2,i) = dt_fac(3,i)


         d1=(total(acc2(dp_idx(i,0):dp_idx(i,1)))+$
             total(acc1(dp_idx(i,0):dp_idx(i,1)))) 
         if d1 eq 0. then dt_fac(1,i) = safe_val else $
          dt_fac(1,i)=(total(lim2_dt(dp_idx(i,0):dp_idx(i,1)))+$
                       total(lim1_dt(dp_idx(i,0):dp_idx(i,1))))/d1

         dt_fac(0,i) = dt_fac(1,i)
         end
      endcase
   endif else begin
      dt_fac(*,i) = safe_val
   endelse
endfor

;-- interpolate out zero factors

if interp eq 3 then dt_fac=bcs_dt_interp(dt_fac,bda_index)
 
return,dt_fac & end
              
