;+
; Project     : SOHO - CDS     
;                   
; Name        : CHK_CHKSUM
;               
; Purpose     : Checks CDS tm file for bad chksums.
;               
; Explanation : Reads a specified CDS telemetry file(s) packet by packet
;               and reports if any packets contain bad check sums.  HK packets
;               are excluded from this.
;               
; Use         : IDL> chk_chksum, files [, various keywords]
;    
; Inputs      : files - A valid CDS telemetry file name or array of names.  
;                       Directory $CDS_TM_DATA is assumed unless specified.
;                       Can also be a DOY number, in which case all available
;                       files for that day will be processed.
;
; Opt. Inputs : None
;               
; Outputs     : None
;               
; Opt. Outputs: None
;               
; Keywords    :  PACKS    - specify the packet at which to start the search
;                PACKE    - specify the packet at which to end the search
;                HARD     - produce hardcopy of report
;                QUIET    - suppress output to screen
;                KEEP     - keep output file (defaults to tlm_check.lis in HOME
;                           directory unless keyword OUTFILE is used.
;                OUTFILE  - specify the output file in which to keep the report.
;                MORE     - if present, screen output has the Unix 'more'
;                           paging option set.
;                NOTIME   - suppress listing of time for each packet
;
; Calls       :
;
; Common      : None
;               
; Restrictions: None
;               
; Side effects: None
;               
; Category    : Telemetry
;               
; Prev. Hist. : None
;
; Written     : C D Pike, RAL, 14-Dec-95
;               
; Modified    : Remove debugging code and catch all HK.  CDP, 17-Jan-96
;               Added DOY interpretation of input and fix HK chksum error.
;                                                        CDP, 23-Jan-96
;		Version 4, William Thompson, GSFC, 19 March 1996
;			Add irregular checksum messages to output file, as well
;			as putting on screen.
;
; Version     : Version 4, 19 March 1996
;-            
pro chk_chksum, file, packs=packs, packe=packe, $
                hard=hard, keep=keep, outfile=outfile, quiet=quiet,$
                more=more, notime=notime


;
;  check has the file parameter
;
if n_params() eq 0 then begin
   print,'Use: chk_chksum, tmfile_name (or DOY) [, keywords]'
   return
endif

;
;  allow input parameter to be DOY in which case we want all files for that day
;
if datatype(file,1) eq 'Integer' or datatype(file,1) eq 'Long' then begin
   cdoy = strmid(string(file+1000,form='(i4)'),1,3)
   date = anytim2cal(doy2utc(file))
   year = strmid(date,7,2)
   infile = findfile(concat_dir('$CDS_TM_DATA',$
                 'tm.'+year+'_'+cdoy+'*'),count=count)
   if count eq 0 then begin
      print,'No telemetry files found for DOY ',file
      return
   endif
endif  else infile = file
 
print,infile
;
;  to terminal?
;
if keyword_set(quiet) then to_screen = 0 else to_screen = 1
if to_screen then begin
   if keyword_set(more) then begin
      openw, screen, filepath(/terminal), /get_lun ,/more
   endif else begin
      openw, screen, filepath(/terminal), /get_lun
   endelse
endif

;
;  create filename (in home directory) for hardcopy or use user-supplied
;
vms=(!version.os eq 'VMS')
if not keyword_set(outfile) then begin
   hfile = 'tlm_check.lis'
   if vms then home='sys$login' else home=getenv('HOME')
   hfile=concat_dir(home,hfile)
endif else begin
   hfile = outfile
endelse

;
;  attempt to open output file
;
openw,lun,hfile,/get_lun,error=err
if err ne 0 then begin
   print,'Error opening output file ',hfile
   return
endif



;
;  loop in case the input filename was an array
;
for file_num = 0,n_elements(infile)-1 do begin

;
;  set flag to indicate if anything bad seen
;
   bad = 0



;
;  check each file exists
;
   badfile = 0
   if file_exist(infile(file_num)) then begin
      usefile = infile(file_num)
   endif else begin
      break_file, infile(file_num),disk,dir,file,ext
      if dir ne '' then begin
         badfile = 1
      endif else begin
         usefile = concat_dir('$CDS_TM_DATA',infile(file_num))
         if not file_exist(usefile) then badfile = 1
      endelse
   endelse

;
;  is this file OK?
;
   if badfile then begin   
      if to_screen then begin
         printf,screen,'**************''
         printf,screen,'File '+infile(file_num)+' does not exist.'
         printf,screen,'**************''
      endif
      printf,lun,'**************''
      printf,lun,'File '+infile(file_num)+' does not exist.'
      printf,lun,'**************''
   endif else begin

;
;  try to open telemetry file
;
      openr,tmlun,usefile,/get_lun,error=err
      if err ne 0 then begin
         if to_screen then begin
            printf,screen,'**************''
            printf,screen,'Error opening tm file '+usefile
            printf,screen,'**************''
         endif
         printf,lun,'**************''
         printf,lun,'Error opening tm file '+usefile
         printf,lun,'**************''
      endif else begin

;
;  print header
;
         if to_screen then begin
            printf,screen,'**********************'
            printf,screen,'Checking chksum in telemetry file '+usefile
            printf,screen,'**********************'
         endif
         printf,lun,'**********************'
         printf,lun,'Checking chksum in telemetry file '+usefile
         printf,lun,'**********************'

;
;  all OK so begin reading file
;
         b = bytarr(306)
         pack_cnt = 0

;
;  jump to first packet requested
;
         if keyword_set(packs) then point_lun,tmlun,packs*306L else packs = 0
         pack_cnt = pack_cnt + packs
 
;
;  for premature end of file
;
         on_ioerror, premature_end

;
;  initialise accumulator
;
         total_bad_s = 0
         total_bad_hk = 0

;
;  ... and counters
;     
         last_hk   = -2
         last_enga = -2
         last_engb = -2
         last_sci  = -2
         last_pmd  = -2
         last_smd  = -2



;
;  set last packet wanted
;
         if keyword_set(packe) then last = packe else last = 100000L


         while (pack_cnt le last) and not eof(tmlun) do begin

;
;  read a packet 
;
            readu,tmlun,b


;
;  check pkt counter (different for each type - science, EngA/B, HK)
;
            n = where([16,32,64,80,96,128,144,224] eq b(18),count)
            if count gt 0 then bid = 16 else bid = b(18)
            case 1 of
               bid eq '10'x: begin
                                 if last_hk eq -2  then begin
                                    last_hk = b(19)
                                 endif else begin
                                    if b(19) eq 0 then last_hk = 1
                                    if (b(19) - last_hk) ne 1 then begin
                                       ptime = anytim2cal(tai2utc(obt2tai(b(12:17))))
                                       ptime = '#'+trim(pack_cnt)+'  '+ptime
                                       print,ptime+' --> '+$
                                             'Irregular (HK) packet counter.'+$
                                              fmt_vect([last_hk,b(19)])
                                       printf,lun,ptime+' --> '+$
                                             'Irregular (HK) packet counter.'+$
                                              fmt_vect([last_hk,b(19)])
                                    endif
                                    last_hk = b(19)
                                 endelse
                               end

               bid eq '0a'x: begin
                                 if last_enga eq -2 then begin
                                    last_enga = b(19)
                                 endif else begin
                                    if b(19) eq 0 then last_enga = -1
                                    if (b(19) - last_enga) ne 1 then begin
                                       ptime = anytim2cal(tai2utc(obt2tai(b(12:17))))
                                       ptime = '#'+trim(pack_cnt)+'  '+ptime
                                       print,ptime+' --> '+$
                                            'Irregular (EngA) packet counter.'+$
                                             fmt_vect([last_enga,b(19)])
                                       printf,lun,ptime+' --> '+$
                                            'Irregular (EngA) packet counter.'+$
                                             fmt_vect([last_enga,b(19)])
                                    endif
                                    last_enga = b(19)
                                 endelse
                               end
 

               bid eq '0b'x: begin
                                 if last_engb eq -2 then begin
                                    last_engb = b(19)
                                 endif else begin
                                    if b(19) eq 0 then last_engb = -1
                                    if (b(19) - last_engb) ne 1 then begin
                                       ptime = anytim2cal(tai2utc(obt2tai(b(12:17))))
                                       ptime = '#'+trim(pack_cnt)+'  '+ptime
                                       print,ptime+' --> '+$
                                              'Irregular (EngB) packet counter.'+$
                                              fmt_vect([last_engb,b(19)])
                                       printf,lun,ptime+' --> '+$
                                              'Irregular (EngB) packet counter.'+$
                                              fmt_vect([last_engb,b(19)])
                                    endif
                                    last_engb = b(19)
                                 endelse
                               end
 
               bid eq '04'x: begin
                                 if last_pmd eq -2 then begin
                                    last_pmd = b(19)
                                 endif else begin
                                    if b(19) eq 0 then last_pmd = -1
                                    if (b(19) - last_pmd) ne 1 then begin
                                       ptime = anytim2cal(tai2utc(obt2tai(b(12:17))))
                                       ptime = '#'+trim(pack_cnt)+'  '+ptime
                                       print,ptime+' --> '+$
                                              'Irregular (Primary Mem dump) packet counter.'+$
                                              fmt_vect([last_pmd,b(19)])
                                       printf,lun,ptime+' --> '+$
                                              'Irregular (Primary Mem dump) packet counter.'+$
                                              fmt_vect([last_pmd,b(19)])
                                    endif
                                    last_pmd = b(19)
                                 endelse
                               end
 
               bid eq '05'x: begin
                                 if last_smd eq -2 then begin
                                    last_smd = b(19)
                                 endif else begin
                                    if b(19) eq 0 then last_smd = -1
                                    if (b(19) - last_smd) ne 1 then begin
                                       ptime = anytim2cal(tai2utc(obt2tai(b(12:17))))
                                       ptime = '#'+trim(pack_cnt)+'  '+ptime
                                       print,ptime+' --> '+$
                                              'Irregular (Primary Mem dump) packet counter.'+$
                                              fmt_vect([last_smd,b(19)])
                                       printf,lun,ptime+' --> '+$
                                              'Irregular (Primary Mem dump) packet counter.'+$
                                              fmt_vect([last_smd,b(19)])
                                    endif
                                    last_smd = b(19)
                                 endelse
                               end
 
                         else: begin
                                 if last_sci eq -2 then begin
                                    last_sci = b(19)
                                 endif else begin
                                    if b(19) eq 0 then last_sci = -1
                                    if (b(19) - last_sci) ne 1 then begin
                                       ptime = anytim2cal(tai2utc(obt2tai(b(12:17))))
                                       ptime = '#'+trim(pack_cnt)+'  '+ptime
                                       print,ptime+' --> '+$
                                              'Irregular (Sci) packet counter.'+$
                                              fmt_vect([last_sci,b(19)])
                                       printf,lun,ptime+' --> '+$
                                              'Irregular (Sci) packet counter.'+$
                                              fmt_vect([last_sci,b(19)])
                                    endif
                                    last_sci = b(19)
                                 endelse
                               end
            endcase

;
;  set time output format
;
            if not keyword_set(notime) then begin
               ptime = '                       '
            endif else begin
               ptime = ''
            endelse


;
;  test the checksum (different for HK or Eng/science - '10'x = HK ID)
;
            if bid eq '10'x then begin
               chksum_ok = check_sum(b,9,101) eq (byteswap(fix(b,204,1)))(0)
            endif else begin
               chksum_ok = check_sum(b,6,151) eq (byteswap(fix(b,304,1)))(0)
            endelse
            if not chksum_ok then begin
               pc = strcompress(string('#',pack_cnt,form='(a,i5)'),/rem)
               pc = strpad(pc,6,/after)
               if bid eq '10'x then begin
                  total_bad_hk = total_bad_hk + 1
                  type = '(HK)'
               endif else begin
                  total_bad_s = total_bad_s + 1
                  type = '(Sci/Eng)'
               endelse
               if not keyword_set(notime) then begin
                  ptime = anytim2cal(tai2utc(obt2tai(b(12:17))))
                  ptime = ptime + ' --> '
               endif 
               if to_screen then begin
                  printf,screen,ptime+'Packet '+pc+' ......bad CHKSUM '+type
               endif
               printf,lun,ptime+'Packet '+pc+' ......bad CHKSUM '+type
            endif
            pack_cnt = pack_cnt + 1
         endwhile
         premature_end:
         free_lun,tmlun
         if total_bad_hk gt 0 then begin
            print,'  Total of ',trim(total_bad_hk),' Bad HK chksums found.'
            printf,lun,'  Total of ',trim(total_bad_hk),' Bad HK chksums found.'
         endif
         if total_bad_s gt 0 then begin
            print,'  Total of ',trim(total_bad_s),' Bad Science/Eng chksums found.'
            printf,lun,'  Total of ',trim(total_bad_s),' Bad Science/Eng chksums found.'
         endif
      endelse
   endelse
endfor

;
;  release auxiliary units
;
free_lun,lun
if to_screen then free_lun,screen


;
;  print hard copy
;
if keyword_set(hardcopy) then begin
   if vms then com = 'print '+hfile else com = 'lpr '+hfile
   spawn,com
   bell
   print,'Hard copy sent to printer'
endif
if (not keyword_set(keep)) and (not keyword_set(outfile)) then begin
   status = delete_file(hfile,/noconfirm)
endif


end
