; $Id: dcs_rotaterawdatafile.pro,v 1.7 2003/11/11 16:57:02 john Exp $
; Written by J.R.D. Copley.
;************************************************************************************************
pro dcs_rotaterawdatafile,event
;************************************************************************************************
;
compile_opt strictarr
;
; This is a procedure that reads a set of DCS raw data files, rotates the
; files, and writes new ones with the first character "R" (or some other character if
; a file with first character "R" already exists), rather than "2".
;
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([$
			'Rotate one or more DCS raw data files','',$
			'This is a procedure that reads a set of DCS raw data',$
			'files, rotates the files, and writes new ones with',$
			'the first character "R" (or some other character if a',$
			'file with first character "R" already exists), rather',$
			'than "2".',$
			'','Do you wish to proceed?'],$
			/question)
		if (res eq "No") then goto,sensitize
	endif
endelse
;
; STEP ONE. Get files to be processed.
inputfilenames=dialog_pickfile(path="C:\DCS data\Angell\Raw data\Various\",$
	title="Select one or more files",filter="*.dcs*",get_path=gpath,/multiple_files)
if (inputfilenames[0] eq "") then goto,sensitize
inputfilenames=inputfilenames[sort(inputfilenames)]
;
; STEP TWO. Read information from first file: ch_wl,ch_ms,ch_srdenom,tsdmin,tchanlook
;
inputfilename=inputfilenames[0]
;
; 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": openr,unitr,inputfilename,/swap_if_little_endian,compress=compressed,/get_lun
	"L": openr,unitr,inputfilename,/swap_if_big_endian,compress=compressed,/get_lun
	else: begin
		error="Cannot determine byte ordering of file named "+inputfilename
		goto,sensitize
	end
endcase
;
readu,unitr,header
;
; 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
;
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
	name=string(name)
	case dt of
		1: begin; read scalar
			readu,unitr,padding
			readu,unitr,scalar
			case name of
				"ch_wl": ch_wl0=scalar
				"ch_ms": ch_ms0=scalar
				"ch_srdenom": ch_srdenom0=scalar
				"tsdmin": tsdmin0=scalar
				else:
			endcase
		end
		2: begin; read matrix
			readu,unitr,n1,n2
			readu,unitr,padding
			nhi=n1>n2
			nlo=n1<n2
			if (nlo eq 1) then data=dblarr(nhi) else data=dblarr(n1,n2)
			readu,unitr,data
			case name of
				"tchanlook": tchanlook0=data
				else:
			endcase
			end
		5: begin; read string
			readu,unitr,nchars; read number of characters in string element
			if (nchars gt 0) then begin
				str=bytarr(nchars)
				readu,unitr,str; read string element
			endif
		end
		7: begin; read string array
			readu,unitr,nstrgs; read number of strings in array
			strarray=strarr(nstrgs)
			for j=1,nstrgs do begin
				readu,unitr,nchars; read number of characters in string element
				str=bytarr(nchars)
				readu,unitr,str; read string element
			endfor
		end
		else:
	endcase
endwhile
free_lun,unitr
;
res=dialog_message(["The following information was extracted from the first file:",$
	"Wavelength ="+strcompress(string(ch_wl0,format='(f10.1)')),$
	"Master speed ="+strcompress(string(ch_ms0,format='(f10.1)')),$
	"SR Denominator ="+strcompress(string(ch_srdenom0,format='(f10.1)')),$
	"tsdmin ="+strcompress(string(tsdmin0,format='(f10.1)'))],/information)
;
; STEP THREE. Get desired channel shift.
;	Create an explanatory message.
helpmsg=[$
	"You are asked to enter the channel shift "+$
	"''nshift'', which is the number of time channels to be added at short times.",$
	"For example if you want to move the elastic channel to the right, from channel ''n'' to "+$
	"channel ''n+100'' enter 100.",$
	"If you want to move the elastic channel to the left, from channel ''n'' to "+$
	"channel ''n-100'' enter -100 (or 900).",$
	"",$
	"It is assumed that exactly 1000 time channels are active.",$
	"Each file must have identical low and high end time channel tables,"+$
	" and the time channel tables must be identical for all files.",$
	"Furthermore wavelengths, master speeds, speed ratios and initial values of "+$
	"''tsdmin'' must be identical."$
	]
;
cancel=1
nshift=0
while (nshift eq 0) do begin
	text="Channel shift"
	values='0'
	dave_get_values,"Enter shift information...",text,values,cancel=cancel,help=helpmsg,$
		group_leader=group_leader
	if (cancel) then goto,sensitize
	nshift=fix(values[0])
	while (nshift lt 0) do nshift=nshift+1000
	while (nshift ge 1000) do nshift=nshift-1000
	if (nshift eq 0) then res=dialog_message("Shift must be nonzero and not a multiple of 1000.")
endwhile
;
; STEP FOUR. Determine new tsdmin value.
tsdmin_new=tsdmin0-total(tchanlook0[0,0:nshift-1])/20
speriod=6e7/ch_ms0*ch_srdenom0
while (tsdmin_new le 0.0) do tsdmin_new=tsdmin_new+speriod
while (tsdmin_new gt speriod) do tsdmin_new=tsdmin_new-speriod
result="Yes"
while (result eq "Yes") do begin
	result=dialog_message(["The modified ''tsdmin'' is"+strcompress(string(tsdmin_new,format='(f10.1)')),$
		"Do you wish to add one or more periods of"+strcompress(string(speriod,format='(f10.1)'))+"?"],$
		/question,/default_no)
	if (result eq "Yes") then tsdmin_new=tsdmin_new+speriod
endwhile
;
; STEP FIVE. Read each file, modify it, and write a new file.
nfiles=n_elements(inputfilenames)
print,"There are ",nfiles," files to be processed."
;
firstletter="R"
for k=0,nfiles-1 do begin
	inputfilename=inputfilenames[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
;
	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
		writeu,unitw,nlgth
		writeu,unitw,name
		writeu,unitw,dldocgf
		writeu,unitw,dt
		name=string(name)
		case dt of
			1: begin; read scalar
				readu,unitr,padding
				writeu,unitw,padding
				readu,unitr,scalar
				case name of
					"ch_wl": begin
						if (abs(scalar-ch_wl0) gt 0.01) then begin
							result=dialog_message(["Error: inconsistent ch_wl.",msg],/error)
							free_lun,unitr
							free_lun,unitw
							goto,sensitize
						endif
					end
					"ch_ms": begin
						if (scalar ne ch_ms0) then begin
							result=dialog_message(["Error: inconsistent ch_ms.",msg],/error)
							free_lun,unitr
							free_lun,unitw
							goto,sensitize
						endif
					end
					"ch_srdenom": begin
						if (scalar ne ch_srdenom0) then begin
							result=dialog_message(["Error: inconsistent ch_srdenom.",msg],/error)
							free_lun,unitr
							free_lun,unitw
							goto,sensitize
						endif
					end
					"tsdmin": begin
						if (scalar ne tsdmin0) then begin
							result=dialog_message(["Error: inconsistent tsdmin.",msg],/error)
							free_lun,unitr
							free_lun,unitw
							goto,sensitize
						endif
						scalar=double(tsdmin_new)
					end
					else:
				endcase
				writeu,unitw,scalar
			end
			2: begin; read matrix
				readu,unitr,n1,n2
				writeu,unitw,n1,n2
				readu,unitr,padding
				writeu,unitw,padding
				nhi=n1>n2
				nlo=n1<n2
				if (nlo eq 1) then data=dblarr(nhi) else data=dblarr(n1,n2)
				readu,unitr,data
				case name of
					"histodata": begin
						data=[shift(data[0:999,*],nshift,0),data[1000:1023,*]]
					end
					"histohigh": begin
						data=[shift(data[0:999,*],nshift,0),data[1000:1023,*]]
					end
					"tchanlook": begin
						ind=where(data[0,*] ne data[1,*],count)
						if (count gt 0) then begin
							result=dialog_message(["Error: inconsistent low and high end time channel tables.",msg],/error)
							free_lun,unitr
							free_lun,unitw
							goto,sensitize
						endif
						ind=where(tchanlook0 ne data,count)
						if (count gt 0) then begin
							result=dialog_message(["Error: inconsistent time channel tables.",msg],/error)
							free_lun,unitr
							free_lun,unitw
							goto,sensitize
						endif
						data=[[shift(data[*,0:999],0,nshift)],[data[*,1000:1023]]]
					end
					"timsum": begin
						data=[shift(data[0:999],nshift),data[1000:1023]]
					end
					else:
				endcase
				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
	print,"File "+outputfilename+" written."
	print,""
endfor
;
res=dialog_message(["Normal exit"],/information)
;
sensitize:
if (n_elements(event) gt 0) then widget_control,event.top,sensitive=1
close,/all
;
end