; $Id: dcs_bitflipcorrectrawdatafile.pro,v 1.2 2004/08/16 13:00:29 john Exp $
; Written by J.R.D. Copley.
;************************************************************************************************
pro dcs_bitflipcorrectrawdatafile,event
;************************************************************************************************
;
compile_opt strictarr
;
; This is a procedure that reads one or more DCS raw data files. It looks for bitflips and
; corrects them. The modified data are written to new files with the first character
; "C" (or some other character) rather than "2". If no bitflip is detected no new file is
;	written.
;
if (n_elements(event) eq 0) then begin
	group_leader=0
endif else begin
	widget_control,event.top,sensitive=0
	group_leader=event.top
	if (widget_info(event.id,find_by_uname="help") ne 0) then begin
		res=dialog_message([$
			'Bitflip-correct one or more raw data files','',$
			'This is a procedure that reads one or more DCS raw',$
			'data files. It looks for bitflips and corrects them.',$
			'The modified data are written to new files with the first',$
			'character "C" (or some other character) rather than "2".',$
			'If no bitflip is detected no new file is written.',$
			'','Do you wish to proceed?'],$
			/question)
		if (res eq "No") then goto,sensitize
	endif
endelse
;
; Define the types of some variables
nlgth=0l
dldocgf=bytarr(5)
dt=0b
padding=0b
scalar=0.0d
n1=0l
n2=0l
nstrgs=0l
nchars=0l
;
files=dialog_pickfile(path="C:\DCS data\testdata\",$
	title="Select one or more raw data files",filter="*.dcs*",get_path=gpath,/multiple_files)
if (files[0] eq "") then goto,sensitize
files=files[sort(files)]
;
; Read each file, modify it, and write a new file.
nfiles=n_elements(files)
print,"There are ",nfiles," files to be processed."
;
firstletter="C"
for k=0,nfiles-1 do begin
	inputfilename=files[k]
;
	outputfilename=gpath+firstletter+strmid(inputfilename,strlen(gpath)+1)
	cancel=1
	while (file_test(outputfilename)) do begin
		res=dialog_message(["The proposed output file,",outputfilename,"already exists.",$
			"You must specify a different first letter."],/error)
		repeat begin
			dave_get_values,"Enter first letter of file","First letter",firstletter,$
				cancel=cancel,group_leader=group_leader
			if (cancel) then goto,sensitize
			if (strlen(firstletter) ne 1) then res=dialog_message("Specify a single letter.",/error)
		endrep until (strlen(firstletter) eq 1)
		outputfilename=gpath+firstletter+strmid(inputfilename,strlen(gpath)+1)
	endwhile
;
	print,"Reading "+inputfilename
;
; Determine whether or not input file is compressed.
	ending=strmid(inputfilename,2,3,/reverse_offset)
	compressed=(ending eq ".gz")
;
; Read header to determine byte ordering ("endianness")
	openr,unit,inputfilename,compress=compressed,/get_lun
	header=bytarr(11)
	readu,unit,header
	free_lun,unit
;
; When opening the file take into account the endianness of the computer that is reading
; the file and writing the modified file.
	case string(header[9]) of
		"B": begin
			openr,unitr,inputfilename,/swap_if_little_endian,compress=compressed,/get_lun
			openw,unitw,outputfilename,/swap_if_little_endian,compress=compressed,/get_lun
		end
		"L": begin
			openr,unitr,inputfilename,/swap_if_big_endian,compress=compressed,/get_lun
			openw,unitw,outputfilename,/swap_if_big_endian,compress=compressed,/get_lun
		end
		else: begin
			error="Cannot determine byte ordering of file named "+inputfilename
			goto,sensitize
		end
	endcase
;
; Start reading the file. Since "histohigh" and "histodata" are at
;	the end, the whole file must be read before we can determine
; whether there are any bitflips.
	readu,unitr,header
	writeu,unitw,header
;
	msg="You may need to clean up files created during this session."
	while (not eof(unitr)) do begin
		readu,unitr,nlgth; read name_length
		name=bytarr(nlgth)
		readu,unitr,name; read name
		readu,unitr,dldocgf; read 5 bytes of doc_length, doc, and global flag
		readu,unitr,dt; read data type
		stringname=string(name)
;
;	In general we read and then write, but once we reach "histodata" we
;	instead save (buffer) the lines between the name variable and the
;	data itself, since we cannot write "histohigh" until after we
; have called the bitflip correction routine.
		if (stringname ne "histodata") then begin
			writeu,unitw,nlgth
			writeu,unitw,name
			writeu,unitw,dldocgf
			writeu,unitw,dt
		endif else begin
			saved_nlgth=nlgth
			saved_name=name
			saved_dldocgf=dldocgf
			saved_dt=dt
		endelse
		name=stringname
		case dt of
			1: begin; read scalar
				readu,unitr,padding
				writeu,unitw,padding
				readu,unitr,scalar
				writeu,unitw,scalar
			end
			2: begin; read matrix
				readu,unitr,n1,n2
				readu,unitr,padding
;
;	Here again we save some lines immediately preceding the "histodata"
;	data.
				if (stringname ne "histodata") then begin
					writeu,unitw,n1,n2
					writeu,unitw,padding
				endif else begin
					saved_n1=n1
					saved_n2=n2
					saved_padding=padding
				endelse
				nhi=n1>n2
				nlo=n1<n2
				if (nlo eq 1) then data=dblarr(nhi) else data=dblarr(n1,n2)
				readu,unitr,data
				writedata=1
				case name of
					"detsum": begin
						detsum=data
					end
					"timsum": begin
						timsum=data
					end
					"histohigh": begin
						histohigh=data
						writedata=0
					end
					"histodata": begin
						histodata=data
						writedata=0
						result=dcs_bitflip_correct(histodata,histohigh,detsum,timsum,maxbf=10,$
							inputfilename=inputfilename,onlydetect=0,printlevel=2)
;
;	If there were bitflips we now write out histohigh, the lines preceding
;	histodata, and finally histodata itself.
						if (result gt 0) then begin
							writeu,unitw,histohigh
							writeu,unitw,saved_nlgth
							writeu,unitw,saved_name
							writeu,unitw,saved_dldocgf
							writeu,unitw,saved_dt
							writeu,unitw,saved_n1
							writeu,unitw,saved_n2
							writeu,unitw,saved_padding
							writeu,unitw,histodata
						endif
					end
					else:
				endcase
				if (writedata) then writeu,unitw,data
			end
			5: begin; read string
				readu,unitr,nchars; read number of characters in string element
				writeu,unitw,nchars
				if (nchars gt 0) then begin
					str=bytarr(nchars)
					readu,unitr,str; read string element
					writeu,unitw,str
				endif
			end
			7: begin; read string array
				readu,unitr,nstrgs; read number of strings in array
				writeu,unitw,nstrgs
				strarray=strarr(nstrgs)
				for j=1,nstrgs do begin
					readu,unitr,nchars; read number of characters in string element
					writeu,unitw,nchars
					str=bytarr(nchars)
					readu,unitr,str; read string element
					writeu,unitw,str
				endfor
			end
			else:
		endcase
	endwhile
	free_lun,unitw
;
;	If there were no bitflips we delete the output file.
	if (result gt 0) then begin
		print,"File "+outputfilename+" written."
		print,""
	endif else begin
		file_delete,outputfilename
	endelse
endfor
;
res=dialog_message(["Normal exit"],/information)
;
sensitize:
if (n_elements(event) gt 0) then widget_control,event.top,sensitive=1
close,/all
;
end