;+
; Project     : SOHO - CDS     
;                   
; Name        : EMON_ERROR
;               
; Purpose     : To detect any CDS error in the telemetry.
;               
; Explanation : Acts as a extra error trapping mode for CDS telemetry. Note
;               there is no way of stopping this program unless
;               a) it reaches end of file
;               b) it reaches the maximum no. of packets specified
;               c) it reaches the time limit specified
;
;               So use the MAXPACK or MINUTES keywords to limit it, 
;               otherwise try CTRL/C!
;               
; Use         : IDL> emon_error [,doy, hours, year=year, hardcopy=hardcopy,$
;                                 maxpack=maxpack, minutes=minutes, $
;                                 /rt, /quiet]
;
;               eg.  IDL> emon_error,244,[13,14],year=94,/hard
;
;                    would check data for 2 hrs (13:00 to 15:00) on 1/Sep/94
;
;                    IDL> emon_error,/rt
;
;                    would check data from the current realtime session.
;
;    
; Inputs      : One of DOY or /rt must be supplied.
;               
; Opt. Inputs : DOY   - day of year for file name.  Only one day at a time is
;                       allowed.
;
;               HOUR  - scalar or vector giving the UT hours required (as in
;                       file names). If not realtime and not given then 
;                       0-23 (inc.) is assumed.
;         
;               
; Outputs     : Procedure writes messages to screen and to hardcopy file if
;               requested.
;               
; Opt. Outputs: None.
;
;               
; Keywords    : YEAR     - specify the year IF NOT current year.
;
;               RT       - if want to pick up only current realtime session.
;                          Note this will only read the current file to the end.
;                          It will not sit and wait for more data to come in
;                          as STM does in realtime mode.
;
;               HARDCOPY - prints error messages to file specified by this
;                          keyword. Defaulted to 'emon_error_log'.
;
;               MAXPACK  - maximum number of Eng A or B packets to read.
;                          Default is 50.
;
;               MINUTES  - approx. number of minutes to run for. This takes
;                          precedence over MAXPACK.
;
;               QUIET    - of present, errors are not written to screen
;                          (they may still be sent to hardcopy)
; Calls       :
;
; Common      : None
;               
; Restrictions: Data files must be in $CDS_TM_DATA directory.
;               String time specifications are assumed in European format
;               ie day,month,year order.
;               
; Side effects: None
;               
; Category    : Util, telemetry
;               
; Prev. Hist. : None
;
; Written     : C D Pike, RAL, 8-Mar-95
;               
; Modified    : Replaced call to LOOK_4_ERROR by RD_ENG_PKT
;
; Version     : Version 1, 22-Aug-95
;-            

pro emon_error, doy, hour, year=year, hardcopy=hardcopy, rt=rt, $
                           maxpack=maxpack, quiet=quiet, minutes=minutes

;
;  common for variables
;
@emon_err.com

;
;  check input
;
if n_params() eq 0 then begin
   if not keyword_set(rt) then begin
      print,'Use:  IDL> emon_error, [doy, hour, /hardcopy, /rt]'
      print,' '
      print,'NB either doy OR /rt must be set.'
      print,' ' 
      return
   endif
endif
   
;
;  setup data structure
;
eng_struct, enga, engb

;
;  either old file or current realtime
;
if n_params() eq 1 and keyword_set(rt) then begin
   print,'Cannot specify doy AND /rt.'
   return
endif

;
;  only one day allowed
;
if n_elements(doy) gt 1 then begin
   print,'Only one day at a time please!'
   return
endif

;
;  if want realtime session...
;
if keyword_set(rt) then begin
   tmfiles = concat_dir('$CDS_TM_DATA',gt_rt_file())
   if not file_exist(tmfiles) then begin
      bell
      print,'No REALTIME session in progress'
      return
   endif else begin
      pskip = tm_get_size(tmfiles)/306L
      openr, eng_lun, tmfiles, /get_lun, error=err
      if err ne 0 then begin
         bell
         print,'Unable to open current telemetry file.'
         return
      endif else begin
         point_lun, eng_lun, pskip*306L
         print,'Skipped ',pskip,' packets.'
      endelse
      start_pack = pskip
      skip_pack = 0
   endelse

endif else begin

;
;  else select old TM files
;

;
;  format day number
;
   cday = strmid(string(doy+1000,form='(i4)'),1,3)

;
;  if not current year...
;
   if keyword_set(year) then begin
      if year gt 1000 then yr = year - 1900 else yr = year
      yr = string(yr,form='(i2)')
   endif else begin
      yr = strmid(systime(),22,2)
   endelse

;
;  depending on how many hours requested, form file names
;
   if n_params() eq 1 then hour = indgen(24)
   nf = n_elements(hour)
   tmfiles = strarr(nf)
   for i=0,nf-1 do begin
      chr = strmid(string(hour(i)+100,form='(i3)'),1,2)
      fdum = 'tm.'+yr+'_'+cday+'_'+chr
      tmfiles(i) = concat_dir('$CDS_TM_DATA',fdum)
   endfor
;
;  open the first file
;
   file_seq_no = 0
   num_data_files = n_elements(tmfiles)
   openr, eng_lun, tmfiles(file_seq_no), /get_lun, error=err
   if err ne 0 then begin
      bell
      print,'Error opening data file ', tmfiles(file_seq_no)
      return
   endif

endelse

print,'Using data files.....'
print_str,tmfiles

;
;  read details of the parameters
;
get_mask_etc, mask


;
;  After those parameters that can indicate errors
;

pname = ['ASCWDERR',$
         'ASCPUERR',$
         'ASCEXTTO',$
         'ASCIMIFE',$
         'ASCPARE0',$
         'ASCPARE1',$
         'ASCPARE2',$
         'ASCPARE3',$
         'ASCIADDE',$
         'ASCVERR',$
         'ASCLOBT',$
         'AK5ES',$
         'AK5EC',$
         'ASEIRXE',$
         'ASVCOMER',$
         'ASVIVR',$
         'ASVIEP',$
         'ASVIWSQ',$
         'ASVIWR',$
         'ASVSERR',$
         'ASVVIS',$
         'ASVRGAF',$
         'ASVRGBF',$
         'ASVMALF',$
         'ASVMODR',$
         'ASVRSTE',$
         'BSMSLITV',$
         'BSGWD',$
         'BS6REP',$
         'BS6SIZE',$
         'BS6UNAV',$
         'BS6INUSE',$
         'BS6OVL',$
         'BS6OVF',$
         'BS6ORPH',$
         'BS6CHK',$
         'BSPFULL',$
         'BS2ICMDI',$
         'BS2IUNK',$
         'BS2VDMPF',$
         'BS2GPREI',$
         'BS2MCMDI',$
         'BS2MUNK',$
         'BS2MCHK',$
         'BS2MECW',$
         'BS2MECER',$
         'BS2MECI',$
         'BS2PPOSI',$
         'BS2FTI',$
         'BS4OVF',$
         'BS4CMDI',$
         'BS4TIMI',$
         'BS4UNK',$
         'BS7CMDI',$
         'BS7UNK',$
         'BS7WRI',$
         'BS8CMDI',$
         'BS8UNK',$
         'BS8WRI',$
         'BS9CMDNA',$
         'BS9BTIMO',$
         'BS9WTIMO',$
         'BS9RTIMO',$
         'BS9CHK',$
         'BS9FAIL',$
         'BS9PLNKR',$
         'BS9CMDI',$
         'BS9UNK',$
         'BSDOOL',$
         'BSDIS',$
         'BSDTII',$
         'BSDSOI',$
         'BSDLLF',$
         'BSDLTF',$
         'BSDCMDI',$
         'BSBWDERR',$
         'BSBPUERR',$
         'BSBEXTTO',$
         'BSBIMIFE',$
         'BSBPARE0',$
         'BSBPARE1',$
         'BSBPARE2',$
         'BSBPARE3',$
         'BSBIADDE',$
         'BSBVERR',$
         'BSITABLE',$
         'BSIOVF']

;
;  load supplementary data for these names only
;
emask = strarr(18,n_elements(pname))
for i=0,n_elements(pname)-1 do begin
   n = where(mask(0,*) eq pname(i))
   if n(0) ge 0 then emask(*,i) = mask(*,n(0))
endfor
         
;
;  these are the ones for which data value 1 means 'ERROR'
;
nerror1 = where(emask(10,*) eq 'ERROR')

;
;  these are the ones for which data value 0 means 'ERROR'
;
nerror0 = where(emask(9,*) eq 'ERROR')

;
;  these are the specials which are normally calibrated by files
;
nerror7 = where(emask(0,*) eq 'AK5ES')
nerror7 = nerror7(0)

nerror8 = where(emask(0,*) eq 'AK5EC')
nerror8 = nerror8(0)


;
;  call low level routine to read data
;
wanted_parms = strupcase(pname)
wanted_packets = strupcase(strmid(wanted_parms(0),0,1))

;
;    set up hardcopy if needed
;

if keyword_set(hardcopy) then begin
   if datatype(hardcopy,1) eq 'Integer' then begin
      hcfile = 'emon_error_log'
   endif else begin
      hcfile = hardcopy
   endelse
   print,'Dumping hardcopy to file: ',hcfile
   
   openw,hclun,hcfile,/get_lun,error=err
   if err ne 0 then begin
      print,'Error opening Hardcopy file.'
      return
   endif
endif

;
;  call data gatherer.
;
status = ' '
packet_no = 0L
engcount = 0L

;
;  time limited?
;
if keyword_set(minutes) then maxpack = long(minutes*60.*2./8.)+2

;
;  maximum number of packets?
;
if not keyword_set(maxpack) then maxpack = 50L



while (status ne '') and (engcount le maxpack) do begin
   data = 0
   rd_eng_pkt, status, time, data, rt=rt
   packet_no = packet_no + 1
   if (packet_no mod 500) eq 0 and not keyword_set(quiet) then begin
      print,'Reading packet ',packet_no,form='(a,i7)'
   endif
;
;  have read Eng A/B packet
;
   if n_elements(data) gt 1 then begin
;
;  adjust max pack according to timing of eng packets
;  allow for 3 packets received as might have ABA or BAB and since
;  AB pairs have more or less same time
;
      if engcount eq 0 then t0 = time
      if engcount eq 1 then t1 = time
      if engcount eq 2 then begin
         t2 = time
         t0 = utc2tai(str2utc(t0,/dmy))
         t1 = utc2tai(str2utc(t1,/dmy))
         t2 = utc2tai(str2utc(t2,/dmy))
         tint = fix(max([t1-t0,t2-t1]))
         if tint gt 10 and keyword_set(minutes) then begin
            maxpack = maxpack/2
         endif else begin
             if tint le 3  and keyword_set(minutes) then begin
                maxpack = maxpack*4
             endif else begin
                if tint lt 6  and keyword_set(minutes) then begin
                   maxpack = maxpack*2 
                endif
             endelse
         endelse
      endif

      engcount = engcount + 1
 
      if not keyword_set(quiet) then print,' '
      if keyword_set(hardcopy) then printf,hclun,' '

;
;  check for value=1 errors
;
      savetime = time
      if total(data(nerror1)) ne 0 then begin
          tempd = data(nerror1)
          tempm = emask(*,nerror1)
          n = where(tempd gt 0)
          nel = n_elements(n)
          for i=0,nel-1 do begin
             if status eq strmid(tempm(0,n(i)),0,1) then begin
                if not keyword_set(quiet) then begin
                   print,time,'  Error: ',tempm(0,n(i)),tempm(17,n(i))
                endif
                if keyword_set(hardcopy) then begin
                   printf,hclun,time,'  Error: ',tempm(0,n(i)),tempm(17,n(i))
                endif
                time = '                  '
             endif
          endfor
       endif

;
;  check for value=0 errors
;
      time = savetime
      if total(data(nerror0))  ne n_elements(nerror0) then begin
         tempd = data(nerror0)
         tempm = emask(*,nerror0)
         n = where(tempd eq 0)
         nel = n_elements(n)
         for i=0,nel-1 do begin
             if status eq strmid(tempm(0,n(i)),0,1) then begin
                if not keyword_set(quiet) then begin
                   print,time,'  Error: ',tempm(0,n(i)),tempm(17,n(i))
                endif
                if keyword_set(hardcopy) then begin
                   printf,hclun,time,'  Error: ',tempm(0,n(i)),tempm(17,n(i))
                endif
                time = '                  '
             endif
         endfor
      endif

;
;  check specials
;
      time = savetime
      if status eq 'A' then begin
         if data(nerror7) ne 0 then begin
            d = tm_calib(pname(nerror7),data(nerror7),words)
            print,time,' Error: ',pname(nerror7),' Macro error source: ',words(1)
         endif
      endif
   
      if status eq 'A' then begin
         if data(nerror8) ne 0 then begin
            d = tm_calib(pname(nerror8),data(nerror8),words)
            print,time,'  Error: ',pname(nerror8),' Macro error code: ',words(1)
         endif
      endif
   endif
endwhile

;
;  free data file and hardcopy
;
free_lun, eng_lun
if keyword_set(hardcopy) then free_lun, hclun

end
