;+
;NAME:
;	mk_bad_pix_map_load
;PURPOSE:
;	Take pixel coordinates for bad pixels in the sun rotated IDL
;	images and make the DHC memory load for on-board masking for
;	both amplifiers and all 4 summations			      (2/99 RWN)
;SAMPLE CALLING SEQUENCE:
;	mk_bad_pix_map_load, ss_array, extra, outdir=outdir
;	mk_bad_pix_map_load, [59683, 59684, 199360, 814825, 815849, $
;		815850, 816873, 987881, 1039996], '_tst_299'
;INPUTS:
;	ss_array - The IDL 1-D "where" array of the bad pixels.  It has
;		   to be for an amplifier A at this time, and must be
;		   from a 1024x1024 image (no summing/binning)
;	extra	 - The extra piece of information to add to the filename
;		   series.  Output file names are "bpXX" + extra + '.cld'  where
;		   XX is ['a1', 'a2', 'a4', 'a8', 'b1', 'b2', 'b4', 'b8']
;		   for amplifier a sum 1x2, 2x2, 4x4, 8x8 and then amp b.
;OPTIONAL KEYWORD INPUT:
;	outdir   - The directory where to put the output
;HISTORY:
;V2.0	Written 22-Jan-99 by M.Morrison	(version for TOPSDB_GEN_IP_CLD)
;V2.1	 8-Feb-99 (RWN) - Correct bad pixel triplet and pointer for last column 
;			  Correct bad pixel triplet and pointer for 2 & 3 pixels
;			    in a row
;			  Add dummy bad pixel triplet every 64 rows
;V2.2	13-Apr-99 (RWN) - Add vector offsets for column (252) and row (1) to pixel map
;			  Update output file header for pixel triplet code = 32 text
;			  Add 252 to rowdatastart and add 2 print columns for image x,y
;-
;-----------------------------------------------------------------
function do_strupcase, in
;
; see if really have to do conversion
; Like because the frames and sequences have the same name "STD.amplifierA"
; when the case is removed
;
return, in
end
;-----------------------------------------------------------------
;-----------------------------------------------------------------
function topsdb_init_cld_fil, file, qwrite=qwrite, $
        segment=segment, offset=offset, $
        iptable_len=iptable_len, ipaddr=ipaddr
;
break_file, file, dsk_log, dir, filnam, ext
;
if (n_elements(offset) eq 0) then offset = 0
if (n_elements(segment) eq 0) then begin
    if (keyword_set(ipaddr)) then segment = '2000'x $
                                else segment = '1000'x
end
;
tarr = anytim2ex(ut_time())
doy = anytim2doy(tarr)
v1 = 1
v2 = filnam
v3 = 38
v4 = 'UI'
line4 = '/NOCOMMIT'
if (keyword_set(ipaddr)) then begin            
    low = ipaddr and 'ffff'x
    hi  = ishft(ipaddr, -16)
    ; Table type 5 = general buffer to table 64K max, done in transfers of 8K
    ; Table type 4 = buffer to dat
    ;fmt4 = '("/ICDHTBL type=5,lowaddr=0x", z4.4, ",highaddr=0x", z4.4,",version=1,tbllength=",i6)'
    fmt4 = '("/ICDHTBL w1=5,w2=0x", z4.4, ",w3=0x", z4.4, ",w4=0x", z4.4, ",w5=", i6)'
    line4 = string(low, hi, offset, iptable_len, format=fmt4)
end
;
fmt1 = '("TRACE,INSCC,", i2.2, "-", i3.3, ":", i2.2, ":", i2.2, ":", i2.2, ",",' + $
                'i3.3, ",", a, ",", i4.4, ",", a)'
fmt2 = '("/ICDPML SEG=0x", z4.4, ",OFFSET=0x", z4.4)'
;;out = ['; FILE:' + file, $
;;      ';', $
out = ['FILE:' + file, $
        string(tarr(6), doy, tarr(0:2), v1, v2, v3, v4, format=fmt1), $
        '/NOSELECT', $
        string(segment, offset, format=fmt2), $
        line4]

if (keyword_set(qwrite)) then begin
    file_delete, file            
    file_append, file, out
end
;
return, out
end
;-----------------------------------------------------------------
pro topsdb_bad_pix_tab, infil,outdir=outdir, arr=arr, extra=extra
;
;
;
if (n_elements(infil) eq 0) then infil = 'NONE (manually entered)'
;
topsdb_table2cld, 'BAD_PIX', infil, 1, outdir=outdir, sum=1, extra=extra, arr=arr
topsdb_table2cld, 'BAD_PIX', infil, 2, outdir=outdir, sum=2, extra=extra, arr=arr
topsdb_table2cld, 'BAD_PIX', infil, 3, outdir=outdir, sum=4, extra=extra, arr=arr
topsdb_table2cld, 'BAD_PIX', infil, 4, outdir=outdir, sum=8, extra=extra, arr=arr
topsdb_table2cld, 'BAD_PIX', infil, 5, outdir=outdir, sum=1, extra=extra, arr=arr, /ampb
topsdb_table2cld, 'BAD_PIX', infil, 6, outdir=outdir, sum=2, extra=extra, arr=arr, /ampb
topsdb_table2cld, 'BAD_PIX', infil, 7, outdir=outdir, sum=4, extra=extra, arr=arr, /ampb
topsdb_table2cld, 'BAD_PIX', infil, 8, outdir=outdir, sum=8, extra=extra, arr=arr, /ampb
;
end
;-----------------------------------------------------------------
pro topsdb_bad_col_tab, infil, outdir=outdir, arr=arr, extra=extra
;
;
;
if (n_elements(infil) eq 0) then infil = 'NONE'
;
topsdb_table2cld, 'BAD_COL', infil,  1, outdir=outdir, sum=1, extra=extra
topsdb_table2cld, 'BAD_COL', infil,  2, outdir=outdir, sum=2, extra=extra
topsdb_table2cld, 'BAD_COL', infil,  3, outdir=outdir, sum=4, extra=extra
topsdb_table2cld, 'BAD_COL', infil,  4, outdir=outdir, sum=8, extra=extra
topsdb_table2cld, 'BAD_COL', infil,  5, outdir=outdir, sum=1, extra=extra, /ampb
topsdb_table2cld, 'BAD_COL', infil,  6, outdir=outdir, sum=2, extra=extra, /ampb
topsdb_table2cld, 'BAD_COL', infil,  7, outdir=outdir, sum=4, extra=extra, /ampb
topsdb_table2cld, 'BAD_COL', infil,  8, outdir=outdir, sum=8, extra=extra, /ampb
;
end
;-----------------------------------------------------------------
pro topsdb_table2cld, type, infil, entry, subentry, outfil=outfil, outdir=outdir, $
		sum=sum, ampb=ampb, extra=extra, infil2=infil2, nwords=nwords, $
		arr=arr0
;
;
;
if (n_elements(outdir) eq 0) then outdir = ''
if (n_elements(extra) eq 0) then extra = ''
if (keyword_set(arr0)) then arr = arr0
;
if (not keyword_set(arr)) and (not file_exist(infil)) then begin
    print, 'TABLE2CLD: Input file does not exist: ' + infil
    return
end
;
break_file, infil, dsk_log, dir00, filnam
;
bad_list = ['a1', 'a2', 'a4', 'a8', 'b1', 'b2', 'b4', 'b8']
case strupcase(type) of
    'LOOKUP': begin
		outfilnam = 'lut' + strtrim(entry,2) + extra + '.cld'
		dest = '18050000'x + 4096L*(entry)		;segment 5
		qip = 1
	      end
    'BAD_COL': begin
		outfilnam = 'bc' + bad_list(entry-1) + extra + '.cld'
		dest = '18060000'x + 4096L*(entry-1)		;segment 6
		qip = 1
		opcode = '1b6'x
	      end
    'BAD_PIX': begin
		outfilnam = 'bp' + bad_list(entry-1) + extra + '.cld'  
		dest = '18070000'x + '8000'x*(entry-1)
		qip = 1
		opcode = '1d2'x
	      end
    'JPEG': begin
		rd_jpeg_table, infil, q, dc, dcl, ac, acl, qdct, dcts
		outfilnam = 'huff' + strtrim(entry,2) + extra + '.cld'
		dest = '18030000'x + 544*(entry-1)
		qip = 1
		for i=0,n_elements(dcl)-1 do dc(i) = ishft(dc(i), 16-dcl(i))
		for i=0,n_elements(acl)-1 do ac(i) = ishft(ac(i), 16-acl(i))
		arr = [ac, acl, dc, dcl]
	      end
    'JPEG_Q': begin
		rd_jpeg_table, infil, q, dc, dcl, ac, acl, qdct, dcts
		outfilnam = 'jpegq' + strtrim(entry,2) + extra + '.cld'
		;dest = '18040000'x + 64*((entry-1)*16 + j)
		dest = '18040000'x + 64*(entry-1)*16
		qip = 1
		q = reform(q, n_elements(q))	;make one D
		arr = q
		for i=1,15 do arr=[arr, q]	;TEMPORARY
	      end
    'JPEG_Q2': begin
		outfilnam = 'jpegq_' + string(entry, format='(i2.2)') + extra + '.cld'
		dest = '18040000'x + 64*(entry)
		qip = 1
	      end
    'PZT': begin
		outfilnam = 'pzt_off.cld'
		dest = '1000F4D0'x
		qip = 0
		arr = rd_tfile(infil, 5, nocomment=';')
		arr = byte(fix(arr(2:4,*)))
		arr = fix(arr, 0, n_elements(arr)/2)
		dec2sun, arr		;swap hi/low bytes
	  end
    'PNT': begin
		outfilnam = 'point.cld'
		dest = '1000F600'x
		qip = 0
		;
		topsdb_mk_pnt_ld, infil, arr, infil2=infil2
		;;dec2sun, arr		;swap hi/low bytes
	   end
    'AEC': begin
		outfilnam = 'aec.cld'
		dest = '1000F000'x
		qip = 0
		;
		topsdb_mk_aec_ld, infil, arr
		dec2sun, arr		;swap hi/low bytes
	   end
    'WAVE': begin
		outfilnam = 'wave.cld'
		dest = '1000F500'x
		qip = 0

		stop
	   end
    else: begin
		print, 'Unrecognized Type: ', type
		stop
	  end
end
;
if (n_elements(outfil) eq 0) then outfil = concat_dir(outdir, outfilnam)
;
if (n_elements(arr) eq 0) then begin
    mat = rd_tfile(infil, nocomment=';')
    remtab, mat, mat
    qhex = max(strpos(mat, '0x')) ne -1
    if (qhex) then mat = str_replace(mat, '0x', ' ')
    mat = strtrim(strcompress(mat), 2)
    ss = where(mat ne '', nss)
    if (nss eq 0) then begin	;null file
	arr = [0, 0, 0, 0]
    end else begin
	mat = mat(where(mat ne ''))
	v = arr2str(mat, delim=' ')
	v = str2arr(v, delim=' ')
	;
	n = n_elements(v)
	arr = lonarr(n)
	if (qhex) then reads, v, arr, format='(z)' $
		else reads, v, arr
    end
end
;
if (keyword_set(opcode)) then begin
    if (max(arr) eq 0) then begin			;no bad pixels
	rowlen = 1024 / sum + 16
	arr = [opcode, 0, rowlen, arr]
    end else begin
	if (opcode eq '1d2'x) then nvpe = 2 $		;number of values per entry in the input table
			else nvpe = 3
	n = n_elements(arr)/nvpe
	arr = reform(arr, nvpe, n)
	arr2 = arr

	if (keyword_set(ampb)) then arr2 = 1023 - arr2	;flip lines top/bottom and columns left/right
;	if (keyword_set(ampb)) then arr2 = 1024 - arr2	;flip lines top/bottom and columns left/right
	arr2 = arr2 / sum				;convert to summed pixels

	avec = lonarr(n)				;define and make a vector of arr2 (2/99 RWN)
	avec(*) = (1024L/sum)*arr2(1,*) + arr2(0,*)
;	avec = avec + 252				;offset for 252 column header (4/99 RWN)
	svec = avec(reverse(sort(avec)))		;desending sort of bad pixels by row/column (2/99(1/99 RWN) RWN)
	arr2(0,*) = svec mod (1024/sum)	+ 252		;remake arr2 with column header offset (4/99 RWN) 
	arr2(1,*) = (svec / (1024/sum)) + 1		;offset for 1 row used for readout (4/99 RWN)

	arr2(0,*) = arr2(0,*) + 8 			;needed for column shift by BLS
	rowlen = 1024 / sum + 16
	nm = 0
	if (opcode eq '1d2'x) then begin
	    n = n + 16					;add null (dummy) bad pixels (2/99 RWN)
	    nm = 2					;add 2 columns to tab for image x,y (4/99 RWN)
	endif
	tab = intarr(nvpe+nm+1, n)			; (4/99 RWN)

	;pixel coordinate in the table is that of the bad pixel, so it should be replaced.  The
	;other two pixels are ok, so normally the corrected bit pattern is  10 01 01   (2/99 RWN)
	;                                             			Pix 2  1  0
	;fixed for bad pixel when it is in last data column (1023 of 1024 x 1024)      (2/99 RWN)
	;or column 1031 of larger ccd size; 8 extra pixels at beginning and end of each row  (2/99 RWN)
	;TODO - allow user to choose substitution pixel
	;
	tab(0:1, 0:n-17) = arr2(0:1, *)			;(2/99 RWN)
	if (opcode eq '1d2'x) then begin		;bad pixel
	    tab(2,0:n-17) = '25'x			;replace by following pixel (2/99 RWN)				
;;  off	  goto, bypass					;debug special skip new bad pixel corrections
	    rowdatastart = 8 + 252	; = 260		;first column of data in row (4/99 RWN)
	    rowdataend = rowlen	+ rowdatastart - 17	;last column of data in row (2/99 RWN)
	    ss = where (tab(0,*) eq rowdataend, cnt)  	;index for when at last data column (2/99 RWN)
	    null = 0			;note bad pixel list sorted so column values decreasing for same row
	    for i = 0, n-18 do begin	;fix for 2 or 3 adjacent bad pixels in same row (2/99 RWN)
	      if (null eq 0) then begin 		;else loop
		if (((tab(1,i)) eq tab(1,i+1)) and ((tab(0,i)-1) eq tab(0,i+1))) then begin 
		  if (i lt n-18) then begin		;2 bad pixels in a row in same row
		    if (((tab(1,i)) eq tab(1,i+1)) and ((tab(0,i)-2) eq tab(0,i+2))) then begin 
		      null = 2				;3 bad pixels in a row in same row
		      if (tab(0,i) lt rowdataend) then begin 	;if third pixel is not last column
			if (tab(0,i+2) gt rowdatastart) then begin  ;and if first one not in first
		          tab(0,i+2) = tab(0,i+2) - 1 	;set first pixel to pixel before bad triplet
			  tab(2,i+2) = '20'x   	;replace first bad pixel by previous one, rest already replaced by following one
			endif				;else OK as is
		      endif else begin
;		        tab(0,i+2) = tab(0,i+2) - 1 	;set first pixel to pixel before bad triplet
			tab(2,i+2) = '0'x   		;replace last 2 bad pixels by previous one
			tab(0,i+1) = tab(0,i+1) - 2 	;set to second previous pixel
			tab(2,i+1) = '0'x   		;replace first 2 bad pixels by previous one
		      end
		    endif	
		  endif 
		  if (null lt 2) then begin		;not 3 bad pixels in a row
		    null = 1				;2 bad pixels in a row in same row
		    if (tab(0,i) eq rowdataend) then begin 
		      tab(0,i+1) = tab(0,i+1) - 1		;set to previous pixel
		      tab(2,i+1) = '0'x   		;replace bad pixels by previous one
		    endif else if (tab(0,i+1) gt rowdatastart) then begin
		      tab(0,i+1) = tab(0,i+1) - 1		;set to previous pixel
		      tab(2,i+1) = '20'x 			;replace bad pixel by previous one
		    end					;else OK as is
		  endif
		endif
	      endif  else null = null - 1
	    endfor
	    if (cnt ge 1) then begin
	      tab(0,ss) = rowdataend - 1		;set to previous pixel
	      tab(2,ss) = '20'x	        		;replace bad pixel by previous one
	    endif
bypass:
	    axdum = intarr(16)
	    axdum = 64*(15 - indgen(16)) + 32
	    tab(0, n-16:n-1) = 292		;so bad pixel routine works for all subsets(4/99 RWN)
	    tab(1, n-16:n-1) = axdum(*)/sum	;input null (dummy) bad pixels (2/99 RWN)
	    tab(2, n-16:n-1) = '24'x		;use current values in triplet
	    tab(3,*) = tab(0,*) - 260		;image x (column)  (4/99 RWN)
	    tab(4,*) = tab(1,*) - 1		;image y (row)     (4/99 RWN)
	    arr2 = [opcode, n, rowlen, reform(tab, (nvpe+nm+1)*n)] 	;(4/99 RWN)
	    itt = 0
	end else begin				;bad col
	    tab(2,*) = 1	;take the next column - works except for column 1023
	    tab(3,*) = arr2(2,*)
	    itt = 1
	end
	itab = intarr(nvpe+1, n)
	itab(0,*) = tab(0,*)
	itab(1,*) = tab(1,*)
	itab(2,*) = tab(2,*)
	if (itt eq 1) then  itab(3,*) = tab(3,*)
	arr = [opcode, n, rowlen, reform(itab, (nvpe+1)*n)]
	comm = ['Summation: ' + strtrim(sum,2), $
			'Amp: ' + (['A','B'])(keyword_set(ampb)), $
			' Header 3 words', $
			string(arr(0:2), format='(3i6)'), $
			'  Values (decimal)', $
			' ccd x   y triplet image x   y', $
			string(arr2(3:*), format='(' + strtrim(nvpe+nm+1,2) + 'i6)')]

    end
end
;
topsdb_gen_ip_cld, dest, arr, outfil, qip, infil=infil, entry=entry, comm=comm
nwords = n_elements(arr)
;
end
;-----------------------------------------------------------------
pro topsdb_gen_ip_cld, dest, arr, outfil, qip, infil=infil, entry=entry, comm=comm
;
;
;
;
if (qip) then begin
    out = topsdb_init_cld_fil(outfil, ipaddr=dest, iptable_len=n_elements(arr))
end else begin
    out = topsdb_init_cld_fil(outfil, segment=(ishft(dest, -16) and 'ffff'x), offset=dest and 'ffff'x)
end
;
out = [out, $
	';', $
	'; TOPSDB_GEN_IP_CLD  Ver 2.2  Program Run: ' + !stime, $
	';   pixel triplet (third value) coding:', $					;(2/99 RWN)
	';	37 (="25"x): bad pixel replaced by following one (default)', $
	';	36 (="24"x): null (dummy, no change) bad pixels needed every 64 rows', $
	';	32 (="20"x): bad pixel, at end of row or 1st of 2or3, replaced by previous one', $
	';	 0 (="0"x) : 2 bad pixels at end replaced by previous good one']
;
if (keyword_set(infil)) then out = [out, '; Input File: ' + infil]
if (keyword_set(entry)) then out = [out, '; Entry: ' + strtrim(entry,2)]
if (keyword_set(comm))  then out = [out, ';', ';' + comm]
;
out = [out, ';', $
	"X" + string( arr and 'ffff'x, format='(8(z4.4, 1x))') + ";"]
;
print, 'Writing: ' + outfil
file_delete, outfil
prstr, out, file=outfil
;
end
;-----------------------------------------------------------------
pro mk_bad_pix_map_load, ss_array, extra, outdir=outdir

x0 = ss_array mod 1024
y0 = ss_array / 1024

x1 = 1023 - y0
y1 = 1023 - x0
n = n_elements(x1)
arr = intarr(2,n)
arr(0,*) = x1
arr(1,*) = y1
;
topsdb_bad_pix_tab, arr=arr, extra=extra, outdir=outdir

end