
;+
; $Id: daily_apid_seqprt.pro,v 1.36 2020/02/27 12:18:10 secchia Exp $
;
; Project   : STEREO SECCHI
;                   
; Name      :daily_apid_seqprt.pro
;               
; Purpose   : checks sci apid's for sequence errors and missing packets
;               
; Explanation: Automatically finds files in $sccb or $scca directory based on lzpb input
;               
; Use       : IDL> daily_apid_seqprt,'a',2011,75,'lz',savedir=sdir,apid='454'
;    
; Inputs    : 	sc = spacecraft A or B, yr = four digit year , day = DOY , lzpb = 'lz' , 'pb'  or 'mon'
;
; Outputs   : - report of images with sequence errors and missing packets image_pckt_errors_X_YYYY_DDD.rpt
;	    	in input directory
;   	      - saveset in $HOME or SAVEDIR called ssrpbrates.sav, which contains array of structures of format:
;   	    	    	    RATE            FLOAT           11.7684
;   	    	    	    GRT             STRUCT    -> CDS_INT_TIME Array[1]
;   	    	    	where RATE is in units of Packets/second
;
; Optional Outputs:	daily_serrors	total number of sequence errors for all ApIDs
;					daily_misspckt	total number of missing packets for all ApIDs
;					daily_packets	total number of received packets for all ApIDs
;					biggestgap		total number of largest total gap in seconds per day of all ApIDs
;
; Keywords  : 
;   	    	APID=	string Apid for which to do report (default is all)
;   	    	SAVEDIR=    Where to save output report and archive savefile (default is input dir)
;		ERR=	 returns 0 if populated file found for any apid
;					1 if file not found       for all apids
;					2 if file is empty        for all apids
;   	    	/OVERWRITE  Overwrite, not append, output report file.
;   	    	/NOREPORT   Do not generate summary report file of gaps.
;   	    	/PIPELINE   Append results to ssrpbrates.sav in $sccx
;   	    	IMAGES= Returns array of following structure, 1 element per image or group of images close together:
;   	    	    	.onbt0	STRUCT	-> CDS_INT_TIME onboard packet time of first packet of image
;   	    	    	.npkts	LONG	Number of packets in image or group of images
;   	    	    	.dt  	FLOAT	Duration of interval of npkts, seconds
;
; Calls from LASCO : 
;
; Common    :
;               
; Restrictions: 
;               
; Side effects: 
;               
; Category    : database sci apid's
;               
; Prev. Hist. : None.
;
; Written     : Lynn McNutt, NRL/I2, Apr 06
;               
; $Log: daily_apid_seqprt.pro,v $
; Revision 1.36  2020/02/27 12:18:10  secchia
; changed findfile to file_search
;
; Revision 1.35  2020/02/27 11:45:44  mcnutt
; change outpdir2 after calliope swap
;
; Revision 1.34  2012/12/27 18:03:35  mcnutt
; changed output and input directory
;
; Revision 1.33  2012/05/22 22:09:30  secchia
; nr - by default do IO in $HOME not $sccx
;
; Revision 1.32  2012/05/22 20:44:55  secchia
; nr - by default do IO in $HOME not $sccx
;
; Revision 1.31  2011/05/27 18:34:51  secchia
; nr - skipit, not return if no packets found
;
; Revision 1.30  2011/05/26 21:38:11  secchib
; nr - typo
;
; Revision 1.29  2011/05/26 21:31:24  secchib
; nr - change firstbad; exit if no packets found in day
;
; Revision 1.28  2011/05/26 20:43:08  secchib
; check n_elements strtime
;
; Revision 1.27  2011/04/19 19:22:55  nathan
; catch gaps that cross day boundary
;
; Revision 1.26  2011/03/30 19:02:28  nathan
; plot PKTIME vs. GRT
;
; Revision 1.25  2010/06/08 11:29:44  secchib
; set t1 for day in loop only
;
; Revision 1.24  2010/06/07 16:55:26  secchia
; removed stop
;
; Revision 1.23  2010/06/07 16:51:10  mcnutt
; changed to read in next day if day boundary not crossed
;
; Revision 1.22  2010/06/02 18:33:30  secchib
; added nextdayfound to check for end of day record
;
; Revision 1.21  2009/09/22 18:00:26  secchia
; delete previous allseqerror report files, creates png not pdf output and hardcode outpdir
;
; Revision 1.20  2009/09/14 21:43:23  secchia
; nr - fix case where grates are all missing
;
; Revision 1.19  2009/09/09 19:48:55  secchib
; Increased size of allgrates array because h450lz2009248Bz.txt had
; 13.0 hours of packets.
;
; Revision 1.18  2009/09/08 22:52:42  secchib
; nr - removed automatically do two days for day boundary because day boundary
; is in seqprt files; renamed ptim; changed a bun c
; f things so it works with full-time ssr2 images
;
; Revision 1.17  2009/09/04 11:40:29  secchia
; opens window 2 before plot on line 334
;
; Revision 1.16  2009/09/03 20:33:27  nathan
; removed stop; added IMAGES= output
;
; Revision 1.15  2009/09/03 15:49:23  nathan
; add /pipeline to save ssrpbrates.sav in $sccx
;
; Revision 1.14  2009/06/10 15:44:27  secchia
; nr - fixed error in pbrfile check
;
; Revision 1.13  2009/06/09 11:44:50  secchia
; corrected pbsavdir varialbe
;
; Revision 1.12  2009/06/05 19:13:45  secchib
; nr - added wait before fstat
;
; Revision 1.11  2009/06/05 18:53:52  nathan
; check for error saving sav file
;
; Revision 1.10  2009/01/14 19:10:41  nathan
; update comments
;
; Revision 1.9  2008/04/11 18:52:55  secchia
; nr - fix typo in line 654
;
; Revision 1.8  2008/04/09 14:43:27  nathan
; add pbrfile check
;
; Revision 1.7  2008/01/30 22:23:27  nathan
; check ssr2 every 15 min onbtime
;
; Revision 1.6  2008/01/17 17:20:05  secchib
; nr -reform allgrates before saving
;
; Revision 1.5  2008/01/17 16:28:22  secchib
; nr - check for too few grates
;
; Revision 1.4  2008/01/16 17:58:37  nathan
; implement ssr playback rate statistics, saved in $sccx/ssrpbrates.sav
;
; Revision 1.3  2007/08/09 15:16:41  mcnutt
; corrected last change
;
; Revision 1.2  2007/08/09 13:46:20  mcnutt
; commented out monthly report file dailysequence errors
;
; Revision 1.1  2007/08/08 16:39:39  mcnutt
; moved from dev/packets
;
;
pro daily_apid_seqprt, sc,yr,doday,lzpb, savedir=savedir, apid=apid, $
	daily_serrors,daily_misspckt,daily_packets, biggestgap, ERR=err, $
	OVERWRITE=overwrite, NOREPORT=noreport, PIPELINE=pipeline, $
	IMAGES=images, USEDIR=usedir

;!p.multi=[0,0,2,0,0]
;clr=['FFFFFF'x,'000000'x,'0000FF'x,'00FF00'x,'FF0000'x,'8888FF'x]
device,decomposed=0
device,retain=2
tek_color
clr=[0,1,2,3,4,5]
;help,yr

day=[doday]

if (n_params() LT 4) THEN BEGIN
	sc=''
	yr=''
	day=''
	lzpb=''
ENDIF


if(sc EQ '' OR yr EQ '' OR day[0] EQ '') then begin
  read,'Enter spacecraft A or B:',sc
  read,'Enter ground receipt year: yyyy ',yr
  read,'Enter ground receipt doy: ddd ',day
endif
IF not (lzpb EQ 'lz' OR lzpb EQ 'pb' OR lzpb EQ 'mon') THEN BEGIN
	read,'Fourth argument must be "lz","pb", or "mon":[mon]',lzpb
	IF lzpb EQ '' THEN lzpb='mon'
ENDIF

IF keyword_set(USEDIR) THEN inpdir=usedir ELSE $
inpdir=getenv('scc'+strlowcase(sc))+'/nrl/'+lzpb+'/outputs/prints/' 

IF keyword_set(SAVEDIR) THEN outpdir=savedir ELSE outpdir='/net/earth/secchi/data/'+strlowcase(sc)+'/lzsci/pcktcnt/daily/'
IF keyword_set(OVERWRITE) THEN app4=0 ELSE app4=1
IF keyword_set(PIPELINE) THEN cutoff=87000 ELSE cutoff=86401	; whether to include day boundary
pipeline=keyword_set(pipeline)
close,4
close,5
close,1
err=0
nferrs=0
zferrs=0

sc=strupcase(sc)
IF keyword_set(APID) THEN apids=apid ELSE apids=['440','441','442','443','444','450','451','454','470','471','474']

daily_serrors=long(0)
daily_misspckt=long(0)
daily_packets=long(0)
biggestgap=0.
napids=n_Elements(apids)
ap1=strmid(apids,1,1)
uap1=uniq(ap1)
ndays=n_elements(day)
ndays0=ndays
help,yr

; Discontinue reading in 2 days to get day boundary; seqprt files should already include day boundary from playback
; will read 2 days if day boundary is missing

utc=doy2utc(day[0],yr)
t0=utc2unixtai(utc)
d2=utc & d2.mjd=d2.mjd+1
day=[day,utc2doy(d2)]
ndays=n_elements(day)
ndays0=ndays
help,yr

yeardoy=string(yr,'(i4.4)')+'_'+string(day[0],'(i3.3)')
ymd=utc2yymmdd(utc,/yyyy)
yyyymm=strmid(ymd,0,6)

; only write sequence error info if there is an error
file5='allsequenceerrors_'+sc+'_'+yeardoy+'_'+lzpb+'.rpt'
tfile5=file_search(concat_dir(outpdir,file5))
if tfile5(0) ne '' and keyword_set(overwrite) then begin  ;erase previous sequenceerrors file 
  syscmd='/bin/rm -f '+tfile5(0)
  spawn,syscmd
  wait,2
endif
newfile=1
pauset=0.5
help,pauset
print,'Doing days ',day
wait,2

; array for GRT rates and times
; check every 2 hours onbtime, EUVI only; value is for period following grt
; check every 15 min. onbtime, EUVI SSR2 only - 12 hours  max/day
allgrates=replicate({ ssrpbstruct, rate:0., grt:str2utc('1970-01-01') },3,64*ndays)

; array for onboard times and packet counts
; 1 element per image, or could be more than 1 if images run together
pktstc= { pktstruct, onbt0:str2utc('1970-01-01'), dt:0., npkts:0d }

compugaps=[1,2,10]  	; these are for onboard time gaps for x444, x454, x474
resetgaps=[10,30,100]

for na=0,napids-1 do begin
  	apid=apids[na]
	help,apid
	; gsub for grtime stats
	type=fix(strmid(apid,1,1))
	IF type EQ 4 THEN gsub=0 ELSE $     ;ssr1
	IF type EQ 5 THEN gsub=1 ELSE $     ;ssr2
	IF type EQ 7 THEN gsub=2 ELSE $     ;spwx
	    	    	  gsub=3
	IF type EQ 5 THEN nchk=15*60. ELSE nchk=2*3600.
	junk=where(apid EQ ['450','451','452','453','454'], is_ssr2)
	d=0L
	g0=0
	grates=0
        endofday='notok'
	IF gsub LT 3 THEN window,4,xsiz=400,ysiz=300
	window,2,xsiz=600,ysiz=400
    	;window,2

        nextdayfound=0
	; ndays is ALWAYS 2
    	FOR fi=0,ndays-1 DO BEGIN
           if (nextdayfound eq 0) then begin
                utc=doy2utc(day[fi],yr)
                if fi eq 0 then t1=utc2unixtai(utc) ;set t1 for first day only
		;file1=file_search(inpdir+'/h'+apid+'*'+strmid(string(yr,'(i4.4)'),2,2)+string(day,'(i3.3)')+'*'+sc+'*.txt')
		help,yr
		targfile=inpdir+'h'+apid+'*'+string(yr,'(i4.4)')+'*'+string(day[fi],'(i3.3)')+'*.txt'
                if (fi gt 0 and day[fi] eq 1)then targfile=inpdir+'h'+apid+'*'+string(yr+1,'(i4.4)')+'*'+string(day[fi],'(i3.3)')+'*.txt'
		print,'Reading ',targfile
		file1=file_search(targfile)
		file1=file1(0)  ; uses "redo" files, if any
		IF file1 EQ '' THEN BEGIN
			print,'File not found !!! ... skipping.'
			print
			wait,1
			nferrs=nferrs+1
			goto, skipfile
		ENDIF
		openr,1,file1
		line=''
		fst=fstat(1)
                s0=-1
		hr=-1
		IF fst.size GT 0 THEN BEGIN
			nrows=(fst.size-208)/100
			help,nrows
    		  ; help,grtime
	    		readf,1,line
	    		if(strmid(line,0,3) eq 'Grd') then begin
	    		    readf,1,line
	    		    readf,1,line
	    		endif
    	    	    	close,1

			pcktime=double(strmid(line,48,15))
                        IF pcktime-t1 GT 2.*86401 or pcktime-t1 LT 0 THEN begin
			; Do not skip next day so we catch gaps that cross day boundary.
			    message,'No valid packets in '+file1, /info
			    wait,5
			    goto, skipfile
			ENDIF			
			openr,1,file1
			; start at beginning again    
			IF fi EQ 0 or n_elements(strtime) LT 2 THEN BEGIN
				grtime= dblarr(nrows)
				pktim=	dblarr(nrows)
				strtime=strarr(nrows)
				pcnt=	lonarr(nrows)
				ptot=	lonarr(nrows)
				seqerr= intarr(nrows)
				s0=0d
				n2h=nchk
                                ptotl=0l
			ENDIF ELSE BEGIN
                                d2=d
                                ptotl=long(max(ptot))
				grtime= [grtime,dblarr(nrows)]
				pktim=	[pktim,dblarr(nrows)]
				strtime=[strtime,strarr(nrows)]
				pcnt=	[pcnt,lonarr(nrows)]
				ptot=	[ptot,lonarr(nrows)]
				seqerr= [seqerr,intarr(nrows)]
				if (s0 eq -1) then s0=0d
				if (datatype(n2h) eq 'UND') then n2h=nchk
       			ENDELSE
  			while (not eof(1)) do begin
	    		    readf,1,line
	    		    if(strmid(line,0,3) eq 'Grd') then begin
	    		    	readf,1,line
	    		    	readf,1,line
	    		    endif
			    charcnt=strlen(strcompress(line))
	    		    IF charcnt LT 70 or charcnt GT 90 THEN firstbad=1 ELSE firstbad=0
			    ; weed out bad rows
			    pcktime=double(strmid(line,48,15))
			    
                           IF nextdayfound eq 0 and pcktime-t1 GT 0 THEN begin
				; t1 is start of current day; if time from packet is not for today+10 min., skip this line
                                    IF pcktime-t1 gt cutoff then nextdayfound=1
				    ; SO... if we encounter 1 packet from next day, we are done!
				    grtime[d]	=double(strmid(line,16,15))
				    pktim[d]	=pcktime-t0
				    ; t0 is start of first day in days
				    ;IF pktim[d] GT ndays*86400 THEN message,'pktim is too big.'
				    ; start at time zero
                	    	    strtime[d]	=strmid(line,32,15)
				    pcnt[d]	=strmid(line,66,5)
				    ptot[d]	=long(strmid(line,80,7)) +ptotl
				    seqerr[d]	=strmid(line,90,5)
				    ; compute rate of pkts being written to SSR AND rate of playback 
				    ; while reading in lines
    	    	    	    	    IF gsub LT 3 THEN BEGIN
				    	wrgap=pktim[d]-pktim[(d-1)>0]
					IF wrgap GT compugaps[gsub] THEN BEGIN
					    ;help,s0,g0,d
					    ; compute downlink rate for previous image
					    ntrvl=grtime[g0:d-1]
					    sorted=sort(ntrvl)
					    bm=linfit(ntrvl[sorted]-grtime[g0],ptot[g0:d-1])
					    grate=bm[1]
					    ; get values for packet stats
					    pktstc.onbt0=unixtai2utc(pktim[g0]+t1)
					    pktstc.dt   =pktim[d-1]-pktim[g0]
					    pktstc.npkts=d-g0
					    IF datatype(images) EQ 'UND' THEN images=pktstc ELSE images=[images,pktstc]
					    IF grates[0] EQ 0 or is_missing(grates[0]) THEN BEGIN
					    	grates=grate 
						gtimes=grtime[g0]
					    ENDIF ELSE BEGIN
					    	grates=[grates,grate]
						gtimes=[gtimes,grtime[g0]]
					    ENDELSE
					    g0=d
					ENDIF
					;IF wrgap GT resetgaps[gsub] THEN g0=d
				    ENDIF

				    ; every [nchk] seconds of onboard time
				    ; OR if ground receipt time gap GT 2 hours
				    ; AND GT 40 packets in interval
				    IF ( (pktim[d] GT n2h) or (grtime[d]-grtime[(d-1)>0] GT 7200)) $
				    	 and d-s0 GT 40 THEN BEGIN
	    				
					;--SSR write rate for current APID
					ab=linfit(pktim[s0:d],ptot[s0:d])
					IF s0 EQ 0 THEN BEGIN
					    rates=ab[1]
					    b=ab[0]
					ENDIF
					rates=[rates,ab[1]]
					print,rates
					w=where_missing(rates)
					;IF w[0] NE -1 THEN stop
					
				    ;--Compute playback/downlink rate. Note that GRT is not monotonically increasing; it may
				    ;  go back by 1 sec or so. Also, rate is for single Apid, so there will be gaps, probably
				    ;  > 10 sec. 
				    	wnm=where_not_missing(grates)
					IF  	gsub LT 3 $
					    and ~(pipeline and fi EQ 1) $
					    and grates[0] NE 0 $
					    and n_elements(wnm) GT 1 THEN BEGIN
					    ;--SSR playback rates
					    maxmin,grates
					    print,utc2str(unixtai2utc(grtime[s0]))
					    wset,4
					    plot,(gtimes-grtime[0])/3600.,grates,psym=1,title='Playback rates for APID='+apid,ytitle='Pkt/sec',xtitle='hours'
					    wset,2
					    plot,(grtime[s0:d-1]-grtime[0])/3600.,ptot[s0:d-1],psym=3,titl='Write rate to SSR',ytitle='Pktctr',xtitle='GRT (hours)'
					    ;IF d-g0 GT 40 THEN BEGIN
					    	hr=hr+1
						allgrates[gsub,hr]={rate:float(median(grates)),grt:unixtai2utc(grtime[s0])}
					    	wait,1
					    ;ENDIF ELSE print,'Npts ',d-g0,' too small.'
					ENDIF ; gsub

 					; compute next check-point; last value must be LT 86401
					; account for large data gaps:
					n2h=(n2h+nchk-2)>((ceil(pktim[d] / nchk) * nchk)-5)
					print,'Next slope check at ',string(n2h/3600.,'(f5.2)'),' hours'
					wait,pauset
				    	s0=d
					grates=0
  	    	    	    	    ENDIF
				    
				    ; Check for gaps between consecutive packets by using the packet time
				    ; Only check after 0400 onboard time
				    ; gap is if tdif gt 10*avg rate
				    IF n_elements(rates) GE 1 THEN BEGIN
				    	IF n_elements(rates) EQ 1 THEN onbrate=rates ELSE onbrate=avg(rates)
				    ENDIF ELSE onbrate=1./3600
				    IF d GT 0 THEN tdif=pktim[d]-pktim[d-1] ELSE tdif=0
				    IF tdif GT 20./onbrate THEN BEGIN
				    ENDIF
				    
				    d=d+1
    				;ENDIF 
				    if pcktime-t0 gt 86400 then endofday='ok'
				    if type EQ 5 then endofday='ok'
				    
     	    		    ENDIF else $
			    IF firstbad THEN BEGIN
			    	message,'Bad row after '+strtime[d-1]+' at d='+trim(d),/info
				firstbad=0
			    ENDIF
  			endwhile    ; reading in packet details from file for current day and apid
    	    	    	close,1
			
    		;nz=where(sgrt GT 0)
    		;sgrt=sgrt[nz]
			IF d GT 0 THEN IF n_elements(rates) LT 3 THEN BEGIN
			; need at least 2 rates to get a slope 
				ab=linfit(pktim[0:d-1],ptot[0:d-1])
				rates=[ab[1],ab[1]]
				b=ab[0]
			ENDIF
			rate=median(rates)  	    ; pkts/sec

                        ;if (fi eq ndays-1) then begin
			;	grtime= grtime(0:d2+20)
			;	pktim=	pktim(0:d2+20)
			;	strtime=strtime(0:d2+20)
			;	pcnt=	pcnt(0:d2+20)
			;	ptot=	ptot(0:d2+20)
			;	seqerr= seqerr(0:d2+20)
                         ;       d=d2+21
    	    	        ;endif
    			;ratet=sgrt[50]	    	    ; GRT (sec)
    			subs=50
    			gaps=0
    			newslope=0
    			maxgap=16383./rate   	    ;seconds
				;stop

    			; only include last day read for ground rates

    	    	ENDIF $ ; size GT 0
		ELSE IF (fi eq 0) then BEGIN
			grtime= 0
			pktim=	0
			strtime=0
			pcnt=	0
			ptot=	0
			seqerr= 0
			zferrs=zferrs+1
	    	ENDif	
		close,1

	
        endif
        if type eq 5 then endofday='ok'  ;only look for gaps which cross day boundaries if not space weather
	skipfile:
    ENDFOR 	; days, read in packet reports for current apid

    ;--If today's file is empty, then exit
    IF d LT 3 THEN BEGIN
    	print,'No packets found for DOY '+trim(day[0])
	message,'Skipping apid',/info
	wait,5
	goto, skipit
    ENDIF
    ;--Remove zeros
    if(d gt 0)then begin
		dz=where(strmid(strtime,0,2) ne '')
		;stop
		grtime=grtime[dz]
		pktim=pktim(dz)
		pcnt=pcnt(dz)
		ptot=ptot(dz)
		seqerr=seqerr(dz)
		;check for twice appended h4*.log files
		dzcheck=where(pktim eq pktim(0) and pcnt eq pcnt(0))
		if(n_elements(dzcheck) gt 1) then begin
		  dz=dz(dzcheck(n_Elements(dzcheck)-1):dz(n_elements(dz)-1))
		  grtime=grtime[dz]
		  pktim=pktim(dz)
		  pcnt=pcnt(dz)
		  ptot=ptot(dz)
		  seqerr=seqerr(dz)
		endif
                d=n_elements(dz)

		;    pktim2= UTC2TAI( TAI2UTC( pktim + 378691200d0, /NOCORRECT) )
		;    pktime=string(pktim2,format='(f15.4)')
		serrors=where(shift(pcnt,-1)-pcnt ne 1 and shift(pcnt,-1)-pcnt ne -16383)
		if(n_Elements(serrors) ne 1)then serrors=serrors(0:n_Elements(serrors)-2) else serrors=[-1]
		;remove last seq error wrap around from shift
    endif else serrors=[-1]

    grt=grtime-grtime[0]

  ;if(d eq 0)then serrors=[-1]
	if(serrors(0) eq -1)then seqer2=0 else seqer2=n_Elements(serrors)
  
	if(max(ptot) le 0)then tpckts=0 else tpckts=n_elements(pcnt)
;  if(serrors(0) ne -1)then for np=0L,n_Elements(serrors)-1 do $
;  printf,5,' ',apid,'  ',strtime(serrors(np)),'  ',string(pktim(serrors(np)),'(f15.4)'),string(pcnt(serrors(np)),'(i6)')

;  z=where(pcnt eq 0)
	if(d gt 0)then begin
    	shpt=shift(pcnt,1)-pcnt
    	shpt[0]=shpt[1]-1		; account for begin and end
    	z=where(shpt gt 0, nz)
	;stop  
		;--get rid of wrap from counter rollover
	
    	if(nz GT 0)then begin
    			; at least 1 wraparound
			zt=where(z-shift(z,1) gt 0)
			if(zt(0) ne -1)then zt=[0,zt] else zt=[0]
			z2=[0,z(zt),n_Elements(pcnt)-1]
			pckt_adj=lonarr(d)
			nz2=n_Elements(z2)
			z2[nz2-2]=z2[nz2-2]-1
			for nv=0L,nz2-2 do pckt_adj(z2(nv):z2(nv+1))=long(16384)*long(nv)
			pcnt2=pcnt+pckt_adj

			plot,pcnt2,color=clr(1)	;,background=clr(0)
			; check for contiguity of wraps
			wait,pauset

			repeat begin
			   adjerr=where(shift(pcnt2,-1)-pcnt2 gt 16383)
			   if(adjerr(0) ne -1)then pcnt2(adjerr+1)=pcnt2(adjerr+1)-long(16384)
			   z2=adjerr(0)
			   print,z2
			endrep until (z2 eq -1)

			oplot,pcnt2,color=clr(2)
			;IF keyword_set(NOREPORT) THEN message,'.cont to exit.'
			;stop

		endif else pcnt2=pcnt

	   shtim=shift(pktim,1)-pktim
	   shtim[0]=0			; account for begin and end
	   
	   
	   zt=where(shtim lt -3600, nzt) ;find 1 hour or more gaps and check for repeated pcnts
	;   if nzt LT 1 THEN stop
    	    if(nzt GE 1)then begin
    	    	for zt1=0L,n_elements(zt)-1 do begin
        	    zt2=where(pcnt2(0:zt(zt1)-1) eq pcnt2(zt(zt1)))
        	    if(zt2(0) ne -1) then pcnt2(zt(zt1):d-1)=pcnt2(zt(zt1):d-1)+long(16384)
    	    	endfor
	    endif
	;   stop
		IF nz GT 0 THEN oplot,pcnt2,color=clr(3) ELSE plot, pcnt2,color=3
		wait,pauset
	   misspckts=(max(pcnt2)-min(pcnt2)+1)-n_Elements(pcnt2)
	   missptot=(max(ptot)-min(ptot)+1)-n_Elements(ptot)
	   zps=sort(pcnt2)
	   spckts=pcnt2(zps)  & strtimes=strtime(zps) & pktims=pktim(zps) & spckt_uc=pcnt(zps)
	   mpt=where(shift(spckts,-1)-spckts ne 1)
	
	   if(n_Elements(mpt) ne 1)then mpt=mpt(0:n_Elements(mpt)-2) else mpt=[-1]
	   ;remove last seq error wrap around from shift
	   rebooted=strarr(n_Elements(mpt)) &  nmps=0
	   if(mpt(0) ne -1)then begin
			nmps=spckts(mpt+1)-(spckts(mpt)+1)
			restarts=spckt_uc(mpt+1)
			mpt1=mpt+1
			zb=where(restarts eq 1)
			if(zb(0) ne -1)then begin 
				rebooted(zb)='rebooted'
				nmps(zb)=0
			endif
			gapsdur=pktim[mpt+1] - pktim[mpt]							; seconds
			print,'Gaps (min): ',gapsdur/60.
			grtgaps=grtime[mpt+1] - grtime[mpt]
			print,'GRT Gaps:   ',grtgaps/60.
		endif else BEGIN
	   		gapsdur=0
			grtgaps=0
		ENDELSE
	   misspckt_check=total(nmps)
	   missper=((misspckt_check*1.0)/((tpckts+misspckt_check)*1.0))*100.0
		print,misspckt_check,missptot,missper,n_Elements(spckts),n_Elements(pcnt)
		;plot,shift(spckts,-1)-spckts,yrange=[-100,100],ystyle=1,color=clr(1)	;,background=clr(0)



		;--confirm adequacy of computed slope
		print,rates
		print
		print,'Median rate to SSR (pkt/sec):',rate
		print,'Time for Pktctr to wrap around (min):   ',maxgap/60.
		print

		inp=''
		gapdurmax=max(gapsdur,ms)
		;--for SSR2, only stop if gap is during a track
		ssr2test=0
		IF (is_ssr2) and grtgaps[ms] LT 7200 THEN ssr2test=1 
		repeat begin
			window,2
			plot,pktim,ptot,psym=3,xrang=[0,ndays0*86400], ystyle=8, xmargin=[9,8], $
				xtitle='seconds of day '+yeardoy,ytitle='Total Packets',title='APID '+apid
			oplot,findgen(ndays0*86400),findgen(ndays0*86400)*rate,color=2
			mingrt=grtime[0]
			maxgrt=(grtime[d-1]-mingrt)/3600.
			axis, yaxis=1, yrange=[-0.1,maxgrt+0.1],ytitle='GRT HOURS starting at '+utc2str(unixtai2utc(mingrt),/ecs),/save
			oplot,pktim,(grtime-grtime[0])/3600.,psym=3,color=3
			IF seqer2 GT 0 and gapdurmax GT maxgap and (ssr2test) THEN BEGIN
				print,string(7B)		; ring bell
				print,'Green is Ground Receipt Time.'
				print,'If the slope of the red line looks OK, then Return'
		;		read, 'otherwise, enter start second for 4 hour interval to use:',inp
		inp=''
				IF inp NE '' THEN BEGIN
					tx=long(inp)
					tt=where(pktim GT tx and pktim LT tx+4*3600, ntt)
					IF ntt GT 1 THEN BEGIN
						ab=linfit(pktim[tt],ptot[tt])
						rate=ab[1]
						maxgap=16383./rate   	    ;seconds
					ENDIF
				ENDIF
				print
				print,'Median write rate to SSR (pkt/sec):',rate
				print,'Time for Pktctr to wrap around (min):   ',maxgap/60.
				print
				wait,pauset

			ENDIF else BEGIN
				print,'No significant gaps detected.'
			ENDELSE
		endrep UNTIL (inp EQ '')
		wait,pauset
   
	endif
	if(d eq 0)then begin 
		serrors=[-1]
		misspckts=0
		misspckt_check=0
		missper=0.0
	endif

	if(strmid(lzpb,0,2) eq 'pb' and ~keyword_set(NOREPORT))then printf,5,'APID ',apid,' ',yeardoy,' # of missing packets due to ITOS pb bug ',string(missptot,'(i7)'),' Difference = ',string(missptot-misspckt_check,'(i7)')
	tgapdur=0
	tpgapseq=0
	tpgapslp=0
	tpgapcor=0
	;--report on individual gaps
	if ( d gt 0) then if (mpt(0) ne -1) then $
	FOR np=0L,n_Elements(mpt)-1 do BEGIN
		gapdur=gapsdur[np]>0.6							; seconds; min. 0.01 min. (so no zeroes in denom)
		sgapdur=string(gapdur/60.,'(F7.2)')
		subsec=strmid(string(pktims(mpt(np)),'(f15.4)'),10,5)
		statim=utc2str(doy2utc(day[0],yr),/date_only)+' '+strmid(strtimes[mpt[np]],7,8)+subsec
		pctr0=spckt_uc[mpt[np]]
		spctr0=string(pctr0,'(I5)')
		pctr1=spckt_uc[mpt[np]+1]
		spctr1=string(pctr1,'(I5)')
		pgapseq=nmps[np]
		spgapseq=string(pgapseq,'(I7)')
		pgapslp=gapdur*rate
		spgapslp=string(pgapslp,'(I7)')
		IF fix(pctr1) EQ 0 OR fix(pctr1) EQ 1 THEN 	BEGIN
			pgapcor=0 
			print
			print,'SEB Reboot detected at ',strtimes[mpt[np]]
			print
			wait,2
		ENDIF ELSE $
		IF (is_ssr2) and grtgaps[np] GT 7200 THEN BEGIN
			pgapcor=0 
			print
			grtgapdur=(grtime[mpt[np]+1]-grtime[mpt[np]])/3600.
			print,'SSR2 Gap at ',utc2str(unixtai2utc(grtime[mpt[np]]),/ecs),' of ',string(grtgapdur,'(f5.2)'),'h probably between tracks '
			print
			wait,2
		ENDIF ELSE $
		IF gapdur GT maxgap THEN BEGIN
			pgapcor=pgapslp 
			print
			print,'Gap',gapdur/60.,' min. >',maxgap/60.,': using',pgapcor,' for num missing packets'
			print
			wait,2
		ENDIF ELSE BEGIN
			pgapcor=pgapseq
			;print
			print,'Gap encountered; using packet counter.'
			print
		ENDELSE
		spgapcor=string(pgapcor,'(I7)')		
		IF (newfile) and ~keyword_set(NOREPORT) THEN BEGIN
			openw,5,concat_dir(outpdir,file5),width=120,append=app4
			printf,5,'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'
			printf,5,'APID        Timeoflastpacket     Pktctr   Pktctr Numpktsmsng NumPktsMsng NumPktsMsng  Duration   '
			printf,5,' +                 beforegap  beforegap aftergap   byseqcntr     byslope   corrected  ofGap(min) '
			printf,5,'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'
			;         hhh  YYYY-MM-DD hh:mm:ss.ssss     12345    12345     1234567     1234567     1234567    1234.67  
		ENDIF
		newfile=0
		
		IF ~keyword_set(NOREPORT) THEN $
		printf,5,   apid,'  ',statim,'     ',spctr0,'     ',spctr1,'     ',spgapseq,'     ',spgapslp,'     ',spgapcor,'    ',sgapdur
		tgapdur=tgapdur+gapdur
		tpgapseq=tpgapseq+pgapseq
		tpgapslp=tpgapslp+pgapslp
		tpgapcor=tpgapcor+pgapcor
	ENDFOR	; gaps
	biggestgap= biggestgap>tgapdur

	;--Daily summary
	;          hhh YYYY_DDD  1234567  123456  1234.67   1234567  12.45   1234567   1234567
	IF d GT 0 then denom=(tpckts+tpgapcor) else denom=1.
	daily_serrors=daily_serrors+long(seqer2)
	IF tpgapseq NE misspckt_check THEN stop
	daily_misspckt=daily_misspckt+long(tpgapcor)
	daily_packets=daily_packets+long(tpckts)
	;stop
	IF napids LT 11 THEN BEGIN
	; same as keyword_set(APID)
	    window
	    utgrt=unixtai2utc(grtime)
	    utpkt=unixtai2utc(pktim+t0) 
	    mti='Ground Receipt Time of 0x'+apid+' for '+strupcase(sc)+' '+ymd
	    yti='PKTTIME hour of '+ymd
	    utplot,utgrt,utpkt.time/3600000.,psym=1,title=mti,ytitl=yti
	    print,'Waiting 10 before continuing.'
	    wait,10
	ENDIF
	skipit:
endfor	; One ApID

help,daily_serrors,daily_misspckt,daily_packets, biggestgap, nferrs,zferrs
IF napids-zferrs EQ 0 THEN err=2
IF napids-nferrs EQ 0 THEN err=1

denom=(daily_packets+daily_misspckt)>1.

case ap1[0] of
	'4': apt='SSR1'
	'5': apt='SSR2'
	'7': apt='SPWX'
	ELSE: apt='Err'
endcase

close,5

!p.multi=0

IF keyword_set(PIPELINE) THEN pbsavdir=getenv('scc'+strlowcase(sc)) ELSE $
IF keyword_set(SAVEDIR) THEN pbsavdir=savedir ELSE pbsavdir=getenv('HOME')
pbrfile=concat_dir(pbsavdir,'ssrpbrates.sav')

nz0=where(allgrates[0,*].rate,n0)
nz1=where(allgrates[1,*].rate,n1)
nz2=where(allgrates[2,*].rate,n2)

n0s=0
IF file_exist(pbrfile) THEN BEGIN
    restore, pbrfile
    n0s=n_elements(ssr1pb)
    IF n0 GT 0 THEN ssr1pb=[ssr1pb,reform(allgrates[0,where(allgrates[0,*].rate)])]
    IF n1 GT 0 THEN ssr2pb=[ssr2pb,reform(allgrates[1,where(allgrates[1,*].rate)])]
    IF n2 GT 0 THEN spwxpb=[spwxpb,reform(allgrates[2,where(allgrates[2,*].rate)])]
ENDIF ELSE BEGIN
    IF n0 GT 0 THEN ssr1pb=reform(allgrates[0,nz0] )
    IF n1 GT 0 THEN ssr2pb=reform(allgrates[1,nz1])
    IF n2 GT 0 THEN spwxpb=reform(allgrates[2,nz2])
ENDELSE

help,ssr1pb,ssr2pb,spwxpb
wait,pauset*2

dosave=1
IF n_elements(ssr1pb) LE n0s and keyword_set(PIPELINE) THEN dosave=0
IF dosave THEN save, ssr1pb,ssr2pb,spwxpb,filename=pbrfile

wait,2
openr,1,pbrfile
sfs=fstat(1)
close,1

IF sfs.size LT 16 and keyword_set(PIPELINE) THEN BEGIN
    save, ssr1pb,ssr2pb,spwxpb,filename='~/ssrpbrates.sav'
    message,'Unable to save ssrpbrates in '+pbsavdir,/info
    message,'Temporarily saved in ~'
ENDIF


end
