PRO FIX_TIME_JUMPS,fname,outname
;
;+
; NAME:
;	FIX_TIME_JUMP
;
; PURPOSE:
;	This procedure reads a file from CDROM and puts the packets in
;	order of the packets. If there is a gap, attempts to fill in 
;	with QL packets using GET_MISSING_PCKTS.
;
; CATEGORY:
;	LASCO PACKETS
;
; CALLING SEQUENCE:
;	FIX_TIME_JUMPS,fname
;
; INPUTS:
;	Fname:	Specifies the telemetry filename to read in.  If no
;		argument is present then all files are read in.
;
; OUTPUTS:
;       Outname:  Returns the temporary output file name
;
; SIDE EFFECTS:
;	A temporary file, fname, is generated in $TMOUT
;
; PROCEDURE:
;	The input files must reside in the current working directory.
;	It then finds missing or out of order packets in science stream by 
;	looking at the packet counter, which should increment by one.
;
; MODIFICATION HISTORY:
; 	Written by:	R.A. Howard, NRL, 3 Aug 1996
;	N. Rich 1/31/97	added tm_files variable
;	RAH     2/04/97	Corrected high rate packet sizes
;	N. Rich 3/29/97 added outdir variable
;	N. Rich 1/2000	Implement GET_MISSING_PCKTS
;	N. Rich 2/2000	Add ctrmin2 check
;
;
;	%H% %W% LASCO IDL LIBRARY
;-
;
;
common unpack_science,old,lusc,file_open,pno,sc,first,pkttype,lulog,src,filename

tm_files = getenv('TMFILES')
cd,tm_files,curr=old_dir
outdir = getenv('TMOUT')
outname = outdir+'/'+fname
OPENW,luout,outname,/get_lun
fn = fname
npkts = 0
OPENR,lu,fn,/get_lun
start_loc=48
;
;  Get the packet length
;
point_lun,lu,start_loc
;data = intarr(3)
;readu,lu,data
;pck_len = data(2) AND 'ffff'XL
;pck_len = pck_len+7
;
;  transfer the file header
;
a=ASSOC(lu,bytarr(start_loc))
aa = ASSOC (luout,bytarr(start_loc))
aa(0) = a(0)
;
;  associate the correct packet lengths
;
;a=ASSOC(lu,bytarr(pck_len),start_loc)
scp = READ_TM_PACKET(fn)		; Need to combine packets from two sources
help,scp
sz = size(scp)
numpckts = sz(2)
pck_len = sz(1)
numexp = 450000L		; A guess....
;numexp = numpckts+15000		; 93120101.d01 had 243005 packets; 93130101 had 415022 packets

; ** sort scp by tai because it sometimes is out of order ** NBR, 2/15/00
print,'Sorting tais...'
tais = obt2tai(scp(6:11,*))
tais0 = tais(0)
goodtais = where(tais GE tais0 and tais LT (tais0+86500),n_srtd1)
srtd1 = sort(tais(goodtais))


a = BYTARR(pck_len,numexp)
print,'Number of packets [actual, expected]:',numpckts,numexp
printf,lulog,'Number of packets [actual, expected]:',numpckts,numexp
a(0,0) = temporary(scp)

aa = ASSOC (luout,bytarr(pck_len),start_loc)
;
;  obtain the approximate number of
;  wrap arounds
;
q = fstat(lu)
;numpackets = q.size/pck_len
;counter=lonarr(long(1.1*numpackets))

counter = lonarr(numexp)
ctr0all = counter
ctrall = counter
badpckts = numpckts-n_srtd1
sec_missed = 0
pckts_missed = 0
;
;  Obtain the initial value of the packet counter
;
b = a(*,0)

ctr = (b(2) * 256L + b(3)) AND '3fff'XL
ctr = ctr-1
pno = 0L
wrap = 0L
numnew = 0L
counter(0) = ctr
lastctr = ctr - 1
;
;  Loop over all packets in the file
;
;stop

REPEAT BEGIN
      pno = pno+1
      ctrmin2= lastctr		; counter minus 2
      lastctr = ctr
      ctr0 = lastctr+1
      ;b = a(pno)
	b = a(*,srtd1(pno))
      ctr = (b(2) * 256L + b(3)) AND '3fff'XL
;
;  Test to see if the packet counter has wrapped around.
;  If the previous packet + 1 exceeds the maximum then it has wrapped.
;  Since the packet containing the greatest packet number might be missing
;  we need to check for a large decrease in the packet counter.
;  If the previous counter is greater than the current counter by
;  more than 55 then it has wrapped.
;
      IF (ctr0 GE '4000'XL) THEN BEGIN		; '4000'XL = 16384
         wrap = wrap+'4000'XL
	    date_str = utc2str(tai2utc(obt2tai(b(6:11))),/ecs)
            print,'Found a wrap at pno,ctr0= ',pno,ctr0, ' or ',date_str
	    printf,lulog,'Found a wrap at pno,ctr0= '+string(pno)+string(ctr0)+ ' or '+date_str
      ENDIF ELSE $
	IF (ctr0 GT ctr AND ctr0 LT ('4000'XL)-1 AND ctrmin2 NE ctr-1) $
	or (ctr0 LT ctr-1) THEN BEGIN
	   IF pno LT n_srtd1-1 THEN BEGIN
		   c = a(*,srtd1(pno+1))
		   nextctr = (c(2) * 256L + c(3)) AND '3fff'XL
	   ENDIF ELSE nextctr = ctr+1
	   IF ctr EQ ctrmin2+2 THEN BEGIN
		IF pno GT 16384 THEN testarr = ctrall(pno-16382:pno-1) $
			ELSE testarr = ctrall(0:pno-1)
		there = where(testarr EQ ctrmin2+1, nthere)
help,nthere,pno
	   ENDIF ELSE nthere=0
	   IF nextctr NE ctr0 and nthere EQ 0 THEN BEGIN
;stop
		;b0 = a(pno-1)
		tai0= obt2tai(a(6:11,srtd1(pno-1)))
		tai1= obt2tai(b(6:11))

		;; ** Search for next valid packet
		;IF tai1 LT tais0 OR tai1 GT tais0+87000L THEN $
		; REPEAT BEGIN
		;   IF badpckts(0) LT 0 THEN badpckts=pno $
		;	ELSE badpckts = [badpckts,pno]
      		;   counter(srtd1(pno))=ctr+wrap
		;   ctr0all(srtd1(pno))=ctr0
	 	;   ctrall(srtd1(pno))=ctr

		;   pno = pno + 1
	 	;   b = a(*,srtd1(pno))
     		;   ctr = (b(2) * 256L + b(3)) AND '3fff'XL
		;   tai1= obt2tai(a(6:11,srtd1(pno)))
		; ENDREP UNTIL (tai1 GT tais0 and tai1 LT tais0+87000L) or pno GE numpckts-1
		;IF pno GE numpckts-1 THEN tai1 = tais0+86400L

		IF nextctr NE ctr0+1 THEN begin
		   ;stop 
		   IF ctr0 LT ctr-1 THEN pckts_missed = pckts_missed + (ctr - lastctr -1) $
			ELSE IF tai1-tai0 GT 1 $
			THEN pckts_missed = pckts_missed +(16383-lastctr) + ctr
		endif

		print,'Found missing/bad packets at pno,ctr,time:  '+trim(string(pno))+'  '+trim(string(ctr))
		print,utc2str(tai2utc(tai0),/ecs)+' to ',utc2str(tai2utc(tai1),/ecs)
		printf,lulog,'Found missing/bad packets at pno,ctr,time:  '+trim(string(pno))+'  '+trim(string(ctr))+ '  '+utc2str(tai2utc(tai0),/ecs)+' to ',utc2str(tai2utc(tai1),/ecs)
		result=0
		;if tai1-tai0 GT 3000 then stop

		IF tai1-tai0 GT 1 THEN GET_MISSING_PCKTS,tai0,tai1,result ELSE BEGIN
			print,'Gap less than 1 second--continuing.'
			printf,lulog,'Gap less than 1 second--continuing.'
		ENDELSE
		; ** Ignore any gap less than 1 seconds
		sec_missed = sec_missed + (tai1-tai0)
;
; ** "result" is a BYTARR(numpkts,pck_len), where num_pckts is the number of missing packets 
;    found for the interval tai0 to tai1. If no packets are found, then result=0.
;
;stop
		ctra = lastctr
		IF result(0) NE 0 THEN BEGIN
		   help,result
		   szr = size(result)
		   totret = szr(2)
		   ret_tais = obt2tai(result(6:11,*))
		   FOR i=0,totret-1 DO BEGIN
			numnew = numnew+1
			ctr0a = ctra+1
			b = result(*,i)
      			ctra = (b(2) * 256L + b(3)) AND '3fff'XL
         		IF (ctr0a GE '4000'XL) THEN BEGIN
         		   wrap = wrap+'4000'XL
         		   print,'Found a wrap in retrieved QL packets at pno,ctr0a=',pno,ctr0a
         		   printf,lulog,'Found a wrap in retrieved QL packets at pno,ctr0a=',pno,ctr0a
        		ENDIF ELSE $
			IF (ctr0a GT ctra AND ctr0a LT ('4000'XL)-1 AND ctrmin2 NE ctra-1) THEN BEGIN
         		   wrap = wrap+'4000'XL
         		   print,'Found a wrap before retrieved QL packets at pno,ctr0a=',pno,ctr0a
         		   printf,lulog,'Found a wrap before retrieved QL packets at pno,ctr0a=',pno,ctr0a
			ENDIF
			counter(n_srtd1-1+numnew) = ctra+wrap
			;
			; ** puts packet number at the end of array 'counter' to match placement 
			;    of new packets at the end of array 'a'
			;
			a(*,n_srtd1-1+numnew) = b

		   ENDFOR
;stop
		ENDIF 
		ctr0a = ctra+1
		;IF (ctr0a GT (ctr+55)) THEN BEGIN
		IF  ctr0a GT (ctr+110)  and pno LT numpckts-2 and ABS(ctr-ctrmin2) GT 2 THEN BEGIN
         	   wrap = wrap+'4000'XL
         	   print,'Found a wrap in missing packets at pno,ctra=',pno,ctra
       	  	ENDIF		

	   ENDIF	;nextctr NE ctr0	
	ENDIF
;
;  Add the current packet number, corrected for the counter wrap, to
;  the array of all packet numbers
;
      counter(srtd1(pno))=ctr+wrap

	ctr0all(srtd1(pno))=ctr0
	ctrall(srtd1(pno))=ctr

;ENDREP UNTIL EOF(lu)
ENDREP UNTIL pno GE n_srtd1-1

totpckts = numpckts+numnew
counter = counter(0:totpckts-1)
;IF badpckts(0) GE 0 THEN BEGIN
;	counter(srtd1(badpckts))=-1
;	nbad = n_elements(badpckts)
;ENDIF ELSE nbad = 0
nbad = badpckts
good = WHERE(counter GT 0,ngood)

printf,lulog
missing_secs = 'Missing '+string(ceil(sec_missed),format='(i5)')+' seconds,  '+string(pckts_missed,format='(i6)')+' packets'
print,missing_secs
print,trim(string(numpckts))+' orig pckts    '+trim(string(numnew))+' new pckts    '+string(nbad,format='(i4)')+' bad pckts' 
IF datatype(date_str) EQ 'UND' THEN stop
printf,lulog,STRMID(date_str,0,10)+'   '+string(numpckts,format='(i6)')+' orig pckts    '+string(numnew,format='(i6)')+' new pckts    '+string(nbad,format='(i3)')+' bad pckts. '+missing_secs

;ctr0all=ctr0all(0:pno)
;ctrall2= (a(2,*) * 256L + a(3,*)) AND '3fff'XL
;tais2 = obt2tai(a(6:11,*))

print,'Sorting packet counters'
sorted = SORT(counter(good))		; Sort the array of packets
IF wrap GT pno+counter(0)+numnew THEN BEGIN
	help,wrap,pno
	stop
	ENDIF
;
;  Now write packets from CDROM and packets from REL/QKL out to
;  a magnetic disk file.
;
window,color=10,/free
plot,counter(sorted), title=fn
oplot,ctrall(sorted)*(pno/30000)+20000,color=6
;stop

print,'Creating sorted packet file'
FOR i=0L,ngood-1 DO aa(i) = a(*,good(sorted(i)))
FREE_LUN,lu
CLOSE,luout
FREE_LUN,luout
CD,old_dir
print,'Finished FIX_TIME_JUMPS'
RETURN
END
