; $Id: dcs_make_summ_ascii.pro,v 1.23 2007/07/18 17:54:48 kneller Exp $
; Written by J.R.D. Copley.
;************************************************************************************************
;###############################################################################
;
; LICENSE:
;  The software in this file is written by an employee of
;  National Institute of Standards and Technology
;  as part of the DAVE software project.
;
;  The DAVE software package is not subject to copyright protection
;  and is in the public domain. It should be considered as an
;  experimental neutron scattering data reduction, visualization, and
;  analysis system. As such, the authors assume no responsibility
;  whatsoever for its use, and make no guarantees, expressed or
;  implied, about its quality, reliability, or any other
;  characteristic. The use of certain trade names or commercial
;  products does not imply any endorsement of a particular product,
;  nor does it imply that the named product is necessarily the best
;  product for the stated purpose. We would appreciate acknowledgment
;  if the DAVE software is used or if the code in this file is
;  included in another product.
;
;###############################################################################
pro dcs_make_summ_ascii_getdqs_cleanup,tlb
;************************************************************************************************
;
compile_opt strictarr
;
;
widget_control,tlb,get_uvalue=pstate
if (ptr_valid(pstate)) then ptr_free,pstate
end


;************************************************************************************************
pro dcs_make_summ_ascii_getdqs_handler,event
;************************************************************************************************
;
compile_opt strictarr
;
widget_control,event.top,get_uvalue=pstate
if (event.id eq (*pstate).done) then begin
	widget_control,event.top,/destroy
	return
endif
;
for k=0,(*pstate).ndq-1 do begin
	if (event.id eq (*pstate).buts[k]) then (*(*pstate).answers_ptr)[k]=event.select
endfor
widget_control,event.top,set_uvalue=pstate

end


;************************************************************************************************
pro dcs_make_summ_ascii_getdqs,ndq,ndq2,long_tits,answers,group_leader=group_leader
;************************************************************************************************
;
compile_opt strictarr
;
title="Choose derived quantities."
tlb=widget_base(title=title,/col,group_leader=group_leader,/modal,xsize=!screensize[0]/3)
title="Choose derived quantities to be included in summary file."
tbase=widget_label(tlb,value=title)
buts=intarr(ndq)
ndq1=ndq-ndq2
if (ndq1 gt 0) then begin
	bbase=widget_base(tlb,/col,/nonexclusive)
	for k=0,ndq1-1 do begin
		buts[k]=widget_button(bbase,value=long_tits[k])
	endfor
endif
if (ndq2 gt 0) then begin
	title='Choose any additional derived quantities to be included.'
	void=widget_label(tlb,value=title)
	bbase2=widget_base(tlb,/col,/nonexclusive)
	for k=ndq1,ndq-1 do begin
		buts[k]=widget_button(bbase2,value=long_tits[k])
	endfor
endif
dbase=widget_base(tlb)
done=widget_button(dbase,value="Proceed")
widget_control,tlb,/realize
answers_ptr=ptr_new(intarr(ndq))
state={ndq:ndq,buts:buts,answers_ptr:answers_ptr,done:done}
pstate=ptr_new(state)
widget_control,tlb,set_uvalue=pstate
xmanager,'dcs_make_summ_ascii_getdqs',tlb,$
	event_handler='dcs_make_summ_ascii_getdqs_handler',$
	cleanup='dcs_make_summ_ascii_getdqs_cleanup'
answers=*answers_ptr
ptr_free,answers_ptr
end


;************************************************************************************************
pro dcs_make_summ_ascii,action,filetype,statePtr,$
			group_leader = group_leader,$
			notify_ids = notify_ids,$
			register_name = register_name
;************************************************************************************************
;	If action="make":
;		If filetype="dcs" this procedure converts DCS data files to Octave ascii format.
; 	The input and output files may be compressed or uncompressed.
; 	The user chooses which variables to place in the output files.
; 	It will also process DAVE files if filetype="dave".
;
; Alternatively, if action="summ",
;		the procedure creates a summary file (in ascii),
;		listing the values of selected variables for each of several files.
;
compile_opt strictarr
;
if (n_params() eq 0) then return
;
;;;;;;;added following 4 lines for non-modal widget action
if n_elements(group_leader) eq 0 then group_leader = 0L
if n_elements(notify_ids) eq 0 then notify_ids = [0L,0L]
if n_elements(register_name) eq 0 then register_name = 'dcs_make_summ_ascii'
if xregistered(register_name) then return
;
davePtr=(*statePtr).davePtr
dcs_sysvars,davePtr=davePtr
;
case filetype of
	"dcs": begin
		filter=["*.dcs","*.dcs.gz"]
		path=!dcs_data_directory
	end
	"dave": begin
		filter="*.dave"
		path=""
	end
	else: begin
		result=dialog_message(["Invalid file type.","Exiting ..."])
		(*statePtr).davePtr=davePtr
		return
	end
endcase
;
if (filetype eq "dave") then begin
	x=dialog_message(["This procedure will only work if the DAVE files",$
		"are identically structured.","",$
		"Do you wish to proceed?"],/question)
	if (x ne "Yes") then begin
		(*statePtr).davePtr=davePtr
		return
	endif
endif
;
; Get a list of files.
files=dialog_pickfile(filter=filter,path=path,/multiple_files,$
	title="Select one or more files",dialog_parent=group_leader)
files=files[sort(files)]
filesize=size(files)
nfiles=filesize[1]
;
if (files[0] eq "") then begin
	result=dialog_message(["No files selected.","Exiting ..."])
	(*statePtr).davePtr=davePtr
	return
endif
;
if (filetype eq "dcs") then dcs_definedavestructure,davePtr=davePtr
;
; START OF LOOP OVER ALL FILES.
for ifile=0,nfiles-1 do begin
	file_path=files[ifile]
	compressed=(strmid(file_path,2,3,/reverse_offset) eq ".gz")
	if (compressed) then rootlength=strlen(file_path)-7 else rootlength=strlen(file_path)-4
	file_root=strmid(file_path,0,rootlength)
;
	if (filetype eq "dcs") then begin
		nofirstline=0
		if (ifile eq 0) then omithisto=0; first time around, read everything.
		printinfo=0
		dcs_read_binaryOctavefile,file_path,nofirstline,omithisto,variables_read,$
			unknowns,error,davePtr=davePtr
		if (strlen(error) gt 0) then begin
			result=dialog_message(["Error reading binary file.","Exiting ..."])
			(*statePtr).davePtr=davePtr
			return
		endif
	endif
;
	if (filetype eq "dave") then begin
		free_all_ptrs,davePtr
		restore,file_path
	endif
;
; THIS SECTION EXECUTED FOR FIRST FILE ONLY.
	if (ifile eq 0) then begin
		lines=""
		flags=0
		bptrs=ptr_new()
;
		dave_beast_ops,"get_ptrs",davePtr,bpointers=dummy
;
		dave_analyze_beast,davePtr,"davePtr",lines,flags,bptrs,analysis=0
;
		nlines=n_elements(lines)-1
		lines=lines[1:nlines]
		flags=flags[1:nlines]
;
		tagnames=""
;
		for j=0,nlines-1 do	$
			if (flags[j] eq 0) then tagnames=[tagnames,lines[j]]
;
		ntags=n_elements(tagnames)-1
		tagnames=tagnames[1:ntags]
		sns=strarr(ntags)
;
; Generate corresponding descriptions.
		idl_type=[" Undefined",$
			" Byte",$
			" Int",$
			" Longint",$
			" Float",$
			" DP float",$
			" Complex float",$
			" String",$
			" Structure",$
			" DP complex",$
			" Pointer",$
			" Object reference",$
			" U Int",$
			" U Longint",$
			" 64-bit Integer",$
			" Unsigned 64-bit Integer"]
;
		datasize=strarr(ntags)
		descriptor=strarr(ntags)
		datanels=strarr(ntags)
		totel=0l
		for j=0,ntags-1 do begin
			com="sz=size("+tagnames[j]+")"
			result=execute(com)
			sns[j]=strmid(tagnames[j],strpos(tagnames[j],'.',/reverse_search)+1)
			lsns=strlen(sns[j])
			if (lsns gt 4 and strpos(strupcase(sns[j]),"PTR)")+4 eq lsns) then $
				sns[j]=strmid(sns[j],0,lsns-4)
			lsz=n_elements(sz)
			dim=sz[0]
			typ=sz[lsz-2]
			nel=sz[lsz-1]
			totel=totel+long(nel)
			if (dim gt 0) then $
				datasize[j]=strcompress(strjoin(sz[1:lsz-3],"*"),/remove_all)$
			else datasize[j]=strcompress(1,/remove_all)
			descriptor[j]=idl_type[typ]
			datanels[j]=sz[lsz-1]
		endfor
		defined=where(descriptor ne " Undefined" and $
			descriptor ne " Pointer" and $
			descriptor ne " Object reference",ntags)
		tagnames=tagnames[defined]
		sns=sns[defined]
		datasize=datasize[defined]
		descriptor=descriptor[defined]
		datanels=datanels[defined]
;
; Find out which variables are to be written to the output file(s),
; whether to create ascii output files and/or a summary file, and
; what delimiter to use for the summary file.
		summdcs=(action eq "summ" and filetype eq "dcs")
		dcs_davePtr_vbles,sns,datasize,descriptor,datanels,ntags,action,$
			choice,delim,totel,group_leader=group_leader,omitfilename=omitfilename,$
			summdcs=summdcs,do_dqs=do_dqs
		dummy=where(choice eq 1,count)
;
		; If summarizing dcs files, allow the user to specify additional derived quantities.
		if (do_dqs) then begin
; Open and read from system file that lists additional derived quantities.
			filename=!DAVE_AUXILIARY_DIR+'dcs_derived_quantities.txt'
			openr,unit,filename,/get_lun
			readf,unit,ndq
; Read information for each derived quantity.
			short_tits=strarr(ndq)
			long_tits=strarr(ndq)
			expressions=strarr(ndq)
			chars=""
			using_histohigh=0
			using_histptr=0
			for k=0,ndq-1 do begin
				readf,unit,chars
				a=strsplit(chars,"\|{2,}",/extract,/regex)
				if (n_elements(a) ne 3) then stop,"Error reading the file ",filename
				short_tits[k]=a[0]
				long_tits[k]=a[1]
				expressions[k]=a[2]
			endfor
			free_lun,unit
;
; Option to open and read from a personal file that lists additional derived quantities.
			filename=""
			x=dialog_message(["Do you wish to read from a personal file of derived quantities",$
				"(in addition to the default file)?"],/question)
			if (x eq "Yes") then begin
				filename=dialog_pickfile(file="personal_derived_quantities.txt",filter="*.txt",$
					path=!dcs_outp_directory,title="Select personal file of derived quantities.")
			endif
			ndqp=0
			if (filename ne "") then begin
				openr,unit,filename,/get_lun
				readf,unit,ndqp
; Read information for each derived quantity.
				short_tits=[short_tits,strarr(ndq)]
				long_tits=[long_tits,strarr(ndq)]
				expressions=[expressions,strarr(ndq)]
				for k=0,ndqp-1 do begin
					readf,unit,chars
					a=strsplit(chars,"\|{2,}",/extract,/regex)
					if (n_elements(a) ne 3) then stop,"Error reading the file ",filename
					short_tits[ndq+k]=a[0]
					long_tits[ndq+k]=a[1]
					expressions[ndq+k]=a[2]
				endfor
				free_lun,unit
				ndq=ndq+ndqp
			endif
;
			answers=strarr(ndq)
			dcs_make_summ_ascii_getdqs,ndq,ndqp,long_tits,answers,group_leader=group_leader
			count=count+total(answers)
;
;	Determine whether or not it is going to be necessary to read histohigh/histodata.
			for k=0,ndq-1 do begin
				if (answers[k] and strpos(strupcase(expressions[k]),'HISTOHIGH') ge 0) then using_histohigh=1
				if (answers[k] and strpos(strupcase(expressions[k]),'HISTPTR') ge 0) then using_histptr=1
			endfor
			if (not using_histptr) then begin
				if (using_histohigh) then omithisto=1 else omithisto=2
			endif
;
		endif else begin
;
			ndq=0
			answers=0
			short_tits=""
			long_tits=""
			expressions=""
		endelse
;
		if (count eq 0) then begin
			res=dialog_message("No variables specified.",/error)
			(*statePtr).davePtr=davePtr
			return
		endif
;
; Decide whether output files are to be compressed or not.
		if (action eq "make") then begin
			result=dialog_message("Do you want compressed (gzip'd) output files ?",/question,/default_no)
			out_compressed=(result eq "Yes")
			if (out_compressed) then out_exten="asc.gz" else out_exten="asc"
		endif
;
;	First line of summary.
		if (action eq "summ") then begin
			dcs_write_summaryfile,$
				summary_line,datafile_ptr=davePtr,choice=choice,0,$
				delim,"",sns=sns,tagnames=tagnames,omitfilename=omitfilename,$
				ndq=ndq,answers=answers,entries=short_tits
			summary_lines=summary_line
		endif
;
		progressBar = Obj_New($
			"SHOWPROGRESS",$
			title=title,$
			xsize=300,$
			ysize=10,$
			message="Please be patient...",$
			color=184)
		progressBar->Start
;
	endif
; END OF SECTION EXECUTED FOR FIRST FILE ONLY.
;
;	if (action eq "summ") then title="Summary file is being created."
;	if (action eq "make") then title="Ascii file is being created."
;
	progressBar->Update,100*float(ifile+1)/nfiles
	progressBar->SetLabel,strcompress(string(ifile+1),/remove_all)+"/"+$
		strcompress(string(nfiles),/remove_all)+" files read."
;
	if (action eq "make") then begin
		if (filetype eq "dave") then file_path=file_root+out_exten
		if (filetype eq "dcs") then file_path = !dcs_outp_directory+$
			strmid(file_root,strpos(file_root,!delimiter,/reverse_search)+1)+"."+out_exten
		dcs_write_asciiOfile,file_path,datafile_ptr=davePtr,$
			compress=out_compressed,choice=choice,tagnames=tagnames,shortnames=sns
		if (nfiles eq 1) then begin
			res=dialog_message("Ascii file "+file_path+" has been written",/information)
		endif else begin
			if (ifile eq 0) then res=$
				dialog_message("First ascii file, "+file_path+", has been written.",/information)
			if (ifile eq nfiles-1) then res=$
				dialog_message("Final ascii file, "+file_path+", has been written.",/information)
		endelse
	endif
;
	if (action eq "summ") then begin
		pos=strpos(file_path,!delimiter,/reverse_search)+1
		if (filetype eq "dcs") then begin
			short_form=strmid(file_path,pos,12)
			if (strmid(short_form,11) eq '.') then short_form=strmid(short_form,0,11)+' '
		endif
		if (filetype eq "dave") then begin
			short_form=strmid(file_path,pos)
		endif
		dcs_write_summaryfile,$
			summary_line,datafile_ptr=davePtr,choice=choice,1,$
			delim,short_form,sns=sns,tagnames=tagnames,omitfilename=omitfilename,$
			ndq=ndq,answers=answers,entries=expressions,filetype=filetype
		summary_lines=[summary_lines,summary_line]
	endif
;
endfor
; END OF LOOP OVER ALL FILES.

;
progressBar->Destroy
Obj_Destroy, progressBar
;
if (action eq "summ") then begin
;
	x=dialog_message("Do you wish to examine the file summary?",/question)
	if (x eq "Yes") then begin
		if (!windows) then dcs_fixedfont="courier*12"
		if (!unix) then dcs_fixedfont="courier-12"
		if (!macos) then dcs_fixedfont="courier*12"
		summary_file=""
		xdisplayfile,summary_file,DONE_BUTTON="Proceed",FONT=dcs_fixedfont,$
			EDITABLE=0,GROUP=group_leader,/MODAL,TITLE="File Summary "+summary_file,$
			text=summary_lines
	endif
;
	x=dialog_message("Do you wish to write the information to a summary file?",/question)
	if (x eq "Yes") then begin
		summary_file=dialog_pickfile(file="summary.txt",filter="*.txt",$
			path=!dcs_outp_directory,title="Select summary file name")
		if (summary_file eq "" or strpos(summary_file,"\00_") ne -1) then begin
			(*statePtr).davePtr=davePtr
			return
		endif
	endif else return
;
	openw,unit,summary_file,/get_lun
	for k=0,n_elements(summary_lines)-1 do printf,unit,summary_lines[k]
	free_lun,unit
;
endif
;
free_all_ptrs,davePtr
dave_makeDavePtr,davePtr=davePtr
(*statePtr).davePtr=davePtr
;
return
;
end
