; $Id: dcs_reduction.pro,v 1.30 2005/09/14 15:55:28 jrdcopley 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_reduction,dcs_base,message_str,screensize,davePtr=davePtr
;************************************************************************************************
;
compile_opt strictarr
;
; Number of He-3 detectors.
nhedet=(*(*(*davePtr).dataStrPtr).specificPtr).nhedet
;
; Number of time channels.
ntchan=(*(*(*davePtr).dataStrPtr).specificPtr).ntchan
;
maxtypes=5; Maximum number of file types
maxfiles=100; Maximum number of files of each type
;
; Define types of files.
type_of_file=[$
	"Sample      ",$
	"Container   ",$
	"Vanadium    ",$
	"Absorber    ",$
	"Background  "]
type_of_filefile=[$
	"Sample file     ",$
	"Container file  ",$
	"Vanadium file   ",$
	"Absorber file   ",$
	"Background file "]
;
;
; *** ZEROTH STEPS ***  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; The zeroth steps are to define the path name for data reduction files and the reduction strategy.
;
; Get root file name for data reduction files.
;

;IF (LMGR(/RUNTIME)) THEN BEGIN
IF (0) THEN BEGIN
; BEGIN
;	Following line commented out (SIMPLIFICATION PROJECT)
;*****dcs_reduction_pathname,dcs_base,davePtr=davePtr,logentry=logentry
;
; Following lines substituted (SIMPLIFICATION PROJECT)
rootname=''
helpstring="You must first define the prefix for the output files in "+$
	"this data reduction session. \\ \\"+$
	"All files created during this session, including intermediate "+$
	"and final data files, plus a log file and various utility files, "+$
	"will have the same prefix. \\ \\ "+$
	"You may choose your own prefix or use the default prefix. \\ \\ "+$
	"Note that at this stage you may not change your "+$
	"input (''raw data'')  or your output (''Working'')directories. \\"+$
	"If you want to change the raw data directory you should click "+$
	"''Cancel'' to return to the main DAVE menu, and then select "+$
	"''File|Raw data directory''."+$
	"Similarly select ''File|Working directory'' to change the "+$
	"working directory."
maxlen=80
dcs_superstring_wrap,helpstring,maxlen,helptext,err
cancel=1
repeat begin
	dave_get_values,'Enter the output file prefix','File prefix',$
		rootname,checkall=0,cancel=cancel,group_leader=dcs_base,$
		help=helptext
	if (cancel) then return
endrep until rootname[0] ne ''
;
defsysv,'!dcs_rootname',rootname[0]

ENDIF ELSE BEGIN
	DEFSYSV, '!dcs_rootname', EXISTS = EXISTS
	IF (NOT EXISTS) THEN DEFSYSV, '!dcs_rootname', ''
	dcs_getstarted,group_leader=dcs_base,cancel_flag
	if (cancel_flag) then return
ENDELSE

defsysv,'!logfile',!dcs_outp_directory+!dcs_rootname+".log"
;
; Create line to be included in the log file.
datetime=systime(0)
datetime=strmid(datetime,0,11)+$
	strmid(datetime,20)+" at "+strmid(datetime,11,8)
;
logentry="DAVE-DCS session log file created "+datetime+"."
;
if (not lmgr(/demo)) then begin
	openw,unit,!logfile,/get_lun
	printf,unit,logentry
	free_lun,unit
endif
;
; END
;
if (!dcs_rootname eq "") then return
;
; [The system variable "!dcs_rootname" has been defined.]
;
; Define data reduction strategy.
; The variable "strategy" is a structure comprising a set of 1s and 0s that define
; the data reduction strategy (whether or not certain things are done).
;
;filename=file_which("dcs_reduction_stratagems.txt",/include_current_dir)
filename=!DAVE_AUXILIARY_DIR+'dcs_reduction_stratagems.txt'
;
; BEGIN
;	Following lines commented out (SIMPLIFICATION PROJECT)
;*****dcs_reduction_strategy,dcs_base,filename=filename,strategy
;*****if (strategy.(0) eq 999) then return
;
;	Following lines substituted (SIMPLIFICATION PROJECT) (largely taken
;		from the procedure dcs_reduction_stratagems.pro)
openr,unit,filename,/get_lun
readf,unit,n_stratagems
sname=strarr(n_stratagems)
istrategy=intarr(n_stratagems)
chars=""
for i=0,n_stratagems-1 do begin
	readf,unit,chars
	a=strsplit(chars," {2,}",/extract,/regex)
	if (n_elements(a) ne 4) then stop,"Error reading the file ",filename
	sname[i]=a[0]; these are the tag names of the structure "strategy"
	istrategy[i]=a[3]; these are the values
endfor
free_lun,unit
;
; Create and then execute a command that defines the structure "strategy"
com="strategy={"
for i=0,n_stratagems-1 do begin
	com=com+sname[i]+":"+string(istrategy[i])
	if (i lt n_stratagems-1) then com=com+"," else com=com+"}"
endfor
result=execute(com)
;	END
;
;	If raw data files have previously been treated up to and including the
; "Sum Identicals" step, those parts of the data reduction procedure can
; be skipped. If that option has been chosen the summed file names and
; wavelength information are restored and the early parts of the data
; reduction procedure are skipped.
if (strategy.readsummedfiles) then begin
	file=!dcs_outp_directory+!dcs_rootname+".sfi"
	if (not file_test(file)) then file=!dcs_default_root+".sfi" $
		else file=!dcs_rootname+".sfi"
	fullfilename=dialog_pickfile(filter="*.sfi",/fix_filter,$
		path=!dcs_outp_directory,/must_exist,$
		file=file,get_path=file_path,$
		title="Select the file that contains the summed file names and wavelength information.")
	cancel=fullfilename eq ""
	if (cancel) then begin
		x=dialog_message("Returning to main menu",/information)
		return
	endif
	if (strlowcase(strmid(fullfilename,3,/reverse)) ne ".sfi") then $
		fullfilename=fullfilename+".sfi"
	restore,filename=fullfilename
	logentry=logentry+string(10B)+$
		"Summed run information has been restored from "+fullfilename
	goto, done_summing
endif
;
; [The structure "strategy" has been defined.]
;
;
; *** NEXT STEP ***   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; The next step is to select the input files.
;
dcs_choose_files,dcs_base,message_str,maxtypes,maxfiles,files_selected,nfiles_selected,$
	type_of_file,skipdefaultchoices=strategy.skipdefaultchoices
;
if (nfiles_selected[0] eq 0) then return
;
; [The variables "files_selected{maxtypes,maxfiles}" and "nfiles_selected{maxtypes}" have been defined.]
;
;
; *** NEXT STEP ***   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Label the input files consecutively.
;
; nruns is the toal number of runs selected
nruns=fix(total(nfiles_selected))
runtyp=bytarr(nruns)
runnum=bytarr(nruns)
tmpPtr=ptr_new(strarr(nruns))
;
; Work through files, adding information to the arrays runtyp, runnum and *tmpPtr.
; e.g., if there are 5 sample files, 1 container file and 1 background file, then
; runtyp will end up as [0,0,0,0,0,1,4], runnum as [0,1,2,3,4,0,0], and *tmpPtr
; will contain the names of the 7 files.
irun=-1
nonexistent=0
for i=0,4 do begin
	if (nfiles_selected[i] gt 0) then begin
		for j=0,nfiles_selected[i]-1 do begin
			irun=irun+1
			runtyp[irun]=i
			runnum[irun]=j
			(*tmpPtr)[irun]=files_selected[i,j]
			if (file_test(files_selected[i,j])) then begin
				logentry=logentry+string(10B)+"  File"+strcompress(irun+1)+$
					", "+type_of_filefile[i]+strcompress(j+1)+", is "+files_selected[i,j]
			endif else begin
				r=dialog_message(["FATAL ERROR:  File ",files_selected[i,j],$
					" DOES NOT EXIST!"],/error)
				nonexistent=nonexistent+1
			endelse
		endfor
	endif
endfor
;
if (not lmgr(/demo)) then begin
	openw,unit,!logfile,/get_lun
	printf,unit,logentry
	free_lun,unit
endif
;
if (nonexistent gt 0) then return
;
files_selected=*tmpPtr
ptr_free,tmpPtr
;
; [The variables "nruns", "runtyp{nruns}" and "runnum{nruns}" have been defined.]
; [Furthermore "files_selected" has been redefined as a singly dimensioned ({nruns}) variable.]
;
;
; *** NEXT STEP ***   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Open files and perform sanity checks.
;
runtemperatures=fltarr(nruns)
;
ratiocriterion=0.0001
;
maxbitflips=10
;
; 1st index of bitflips array is time channel, 2nd is detector number, 3rd is value.
bitflips=lonarr(3,maxbitflips,nruns)+1000
;
; If the strategy is to do no more than the mandatory bitflip sanity check, do it!
if (strategy.nodetailedsanitycheck) then begin
	dcs_sanitycheck,dcs_base,files_selected,nruns,nhedet,allchecks=0,silent=0,$
		bitflips,maxbitflips,$
		davePtr=davePtr,runtemperatures,message_str,$
		skiptchanmismatchmes=strategy.skiptchanmismatchmes,$
		logentry=logentry
	logentry=logentry+string(10B)+"Bit flip sanity checks have been completed."
	if (nruns eq 0) then return
;
endif else begin
;
; Otherwise, ask whether detailed sanity checks are to be performed.
	dcs_multiplechoice,dcs_base,decision,"Sanity_check",message_str,60,$
		skipdefaultchoices=strategy.skipdefaultchoices
	case decision of
;
; Detailed sanity checks.
		0: begin
			dcs_sanitycheck,dcs_base,files_selected,nruns,nhedet,/allchecks,silent=0,$
				bitflips,maxbitflips,$
				davePtr=davePtr,runtemperatures,message_str,ratiocriterion=ratiocriterion,$
				skipdefaultchoices=strategy.skipdefaultchoices,$
				skiptchanmismatchmes=strategy.skiptchanmismatchmes,$
				logentry=logentry
			logentry=logentry+string(10B)+"Detailed sanity checks have been completed."
			if (nruns eq 0) then return
		end
;
;	Mandatory sanity checks only.
		1: begin
			dcs_sanitycheck,dcs_base,files_selected,nruns,nhedet,allchecks=0,silent=0,$
				bitflips,maxbitflips,$
				davePtr=davePtr,runtemperatures,message_str,$
				skipdefaultchoices=strategy.skipdefaultchoices,$
				skiptchanmismatchmes=strategy.skiptchanmismatchmes,$
				logentry=logentry
			logentry=logentry+string(10B)+"Bit flip sanity checks have been completed."
			if (nruns eq 0) then return
		end
;
		else: return
	endcase
endelse
;
if (not lmgr(/demo)) then begin
	openw,unit,!logfile,/get_lun
	printf,unit,logentry
	free_lun,unit
endif
;
; [The variable "bitflips{3,maxbitflips,nruns}" has been defined.  Also the variable
;	"runtemperatures{nruns}", containing the values of temp_setpoint for each run.]
;
;
; *** NEXT STEP ***   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Open files and check their "sameness".
;
; If there is only one file there is no need to check "sameness".
decision=0
if (total(nfiles_selected) eq 1) then goto,done_samenesscheck
;
; If the user elects to skip the sameness check, do just that.
decision=1
if (strategy.skipsamenesscheck) then goto,done_samenesscheck
;
; Ask user whether to do sameness check, skip it, or go to main menu.
; BEGIN
;	A number of the following lines are commented out (SIMPLIFICATION PROJECT)
;dcs_multiplechoice,dcs_base,decision,"Sameness",message_str,60,$
;		skipdefaultchoices=strategy.skipdefaultchoices
;case decision of
;	0: begin
		dcs_sameness,dcs_base,files_selected,nfiles_selected,nruns,notsame,davePtr=davePtr
		if (notsame) then return; If files are not "the same", return to main program.
		logentry=logentry+string(10B)+"Files have been successfully checked for ''sameness''."
;	end
;	1:
;	else: return
;endcase
;
done_samenesscheck:
;if (decision eq 1) then begin
;	logentry=logentry+string(10B)+"N.B.  Files have NOT been checked for ''sameness''."
;endif
;
; END
;
if (not lmgr(/demo)) then begin
	openw,unit,!logfile,/get_lun
	printf,unit,logentry
	free_lun,unit
endif
;
;
; *** NEXT STEP ***   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;	Give user the option of looking at information from each file.
;
if (strategy.skipheaders) then goto,done_headerdisplay
dcs_multiplechoice,dcs_base,decision,"Examine_header",message_str,60,$
	skipdefaultchoices=strategy.skipdefaultchoices
case decision of
	0: begin
;		widget_control,dcs_base,/iconify
		dcs_display_contents,dcs_base,files_selected,nruns,davePtr=davePtr,bitflips
;		widget_control,dcs_base,iconify=0
		if (nruns eq 0) then return
	end
	1:
	else: return
endcase
;
done_headerdisplay:
;
;
; *** NEXT STEP ***   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Determine beam monitor integrated counts for each file.
;
; Choose whether to proceed or go to main menu.
if (strategy.skipbmmessage1) then goto,done_bm_message1
dcs_multiplechoice,dcs_base,decision,"BM_integration",message_str,60,$
	skipdefaultchoices=strategy.skipdefaultchoices
if (decision eq 1) then return
;
done_bm_message1:
;
; Call a procedure that typically returns the beam monitor counts and durations for each run.
; These quantities are used for normalization purposes. No errors are calculated for these
; quantities.
dcs_normalization_counts,dcs_base,files_selected,nfiles_selected,nruns,normalization_values,$
	fbnormalization_values,davePtr=davePtr,bitflips,maxbitflips,strategy.skipbmmessage2,$
	strategy.normalizetoBM1,strategy.dontsavebminfo,nhedet=nhedet,fbdecision=fbdecision,$
	message_str,skipdefaultchoices=strategy.skipdefaultchoices,logentry=logentry
;
if (nruns eq 0) then return
;
; [The arrays normalization_values{nruns} and fbnormalization_values{nruns}"
; 	have been defined.]
;
if (not lmgr(/demo)) then begin
	openw,unit,!logfile,/get_lun
	printf,unit,logentry
	free_lun,unit
endif
;
;
; *** NEXT STEP ***   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;	Have the user define conditions of sample runs and then associate each sample file with
; one of these conditions.
; If there is more than one sample file and the user has not chosen the single condition,
;	strategy, ask what the user wants to do.
decision=0
if (nfiles_selected[0] eq 1 or strategy.singlesamplecondition) then begin
	decision=0
endif else begin
	dcs_multiplechoice,dcs_base,decision,"Sample_conditions",message_str,60,$
		skipdefaultchoices=strategy.skipdefaultchoices
	if (decision eq 2) then return
endelse
;
; Either assign a single condition to all of the sample runs ....
if (nfiles_selected[0] eq 1 or decision eq 0) then begin
	conditions=strarr(1)
	assignments=bytarr(nfiles_selected[0])+1
	logentry=logentry+string(10B)+$
		"All sample runs are considered to correspond to a single sample condition."
endif else begin
;
; or have the user define conditions and then assign a condition to each run.
; The conditions are represented by strings, e.g. ["T=10K","T=50K"] and the
; assignments are an array of numbers, e.g. [1,1,2,2,2]; that means runs 1 and 2
; were at 10K and runs 3-5 were at 50K.
	dcs_sample_conditions,dcs_base,files_selected,nfiles_selected,runtemperatures,$
		conditions,assignments,message_str=message_str,$
		skipdefaultchoices=strategy.skipdefaultchoices
	logentry=logentry+string(10B)+$
		"Sample runs have been classified according to sample condition."
	for j=1,nfiles_selected[0] do logentry=logentry+string(10B)+$
			"File "+files_selected[j-1]+", condition "+conditions[assignments[j-1]-1]
endelse
;
; [The singly dimensioned variables "conditions" and "assignments" have been defined.]
;
if (not lmgr(/demo)) then begin
	openw,unit,!logfile,/get_lun
	printf,unit,logentry
	free_lun,unit
endif
;
;
; *** NEXT STEP ***   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Have the user define a detector mask.
;
if (strategy.donomasking) then begin
	decision=0
endif else begin
	dcs_multiplechoice,dcs_base,decision,"Masking",message_str,60,$
		skipdefaultchoices=strategy.skipdefaultchoices
endelse
;
if (decision eq 2) then return
;
; Call a procedure that returns a 2-d array called mask, containing a mask for each run.
dcs_choose_mask,dcs_base,mask,nruns,nhedet,decision,files_selected,nfiles_selected,$
	davePtr=davePtr,logentry=logentry,bitflips,maxbitflips,conditions,assignments
if (decision eq 2) then return
if (mask[0,0] eq 999) then return
;
if (not lmgr(/demo)) then begin
	openw,unit,!logfile,/get_lun
	printf,unit,logentry
	free_lun,unit
endif
;
; [The variable "mask{nhedet,nruns}" has been defined.]
;
;
; *** NEXT STEP ***   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Sum "identical" files.
; Also sum the two sets of normalization values.
; Mask(s) are also applied.
;
if (strategy.donotprompttosumfiles) then goto,done_sumidenticals_message
;
dcs_multiplechoice,dcs_base,decision,"Sum_identicals",message_str,60,$
	skipdefaultchoices=strategy.skipdefaultchoices
if (decision eq 1) then return
;
done_sumidenticals_message:
;
; The wavelength is the same for all runs other than the background file(s).
; We need to save it here because davePtr will be cleared in "dcs_sumidenticals".
omithisto=2
printinfo=0
filetype="binary"
dcs_readdatafile,files_selected[0],omithisto,printinfo,filetype,davePtr=davePtr
lambda=(*(*(*davePtr).dataStrPtr).specificPtr).ch_wl
;
; Do the summing.
dcs_sumidenticals,dcs_base,files_selected,nfiles_selected,nruns,normalization_values,$
	fbnormalization_values,mask,assignments,ntchan,nhedet,sumfiles,n_sumfiles,$
	bitflips,maxbitflips,davePtr=davePtr,logentry=logentry
;
;	At this stage we generally wish to save the summed file names and wavelength
; information for possible use in a later reduction session. We need a name for
; the file where this information is to be saved. We either use the default file
; name or request a file name (with the option to not save).
;
if (strategy.usedefaultsfiname) then begin
; Use default file name.
	fullfilename=!dcs_outp_directory+!dcs_rootname+".sfi"
	save,filename=fullfilename,lambda,sumfiles,n_sumfiles
	logentry=logentry+string(10B)+$
		"Summed run information has been saved in "+fullfilename
;
endif else begin
; Ask for a file name.
	repeat begin
		file=!dcs_rootname+".sfi"
		fullfilename=dialog_pickfile(filter="*.sfi",/fix_filter,$
			path=!dcs_outp_directory,$
			file=file,get_path=file_path,$
			title="Define a file where the summed file names and wavelength "+$
				"information will be stored.")
		cancel=fullfilename eq ""
		compok=strcmp(file_path,!dcs_outp_directory,/fold_case)
		if (not compok) then res=dialog_message("You may not change the directory.")
	endrep until (cancel or compok)
;
; If the cancel button was pressed the information will not be saved.
	if (not cancel) then begin
		if (strlowcase(strmid(fullfilename,3,/reverse)) ne ".sfi") then $
			fullfilename=fullfilename+".sfi"
		save,filename=fullfilename,lambda,sumfiles,n_sumfiles
		logentry=logentry+string(10B)+$
			"Summed run information has been saved in "+fullfilename
	endif
endelse
;
done_summing:
;
if (not lmgr(/demo)) then begin
	openw,unit,!logfile,/get_lun
	printf,unit,logentry
	free_lun,unit
endif
;
; [Two new variables have now been defined:
;	(a) The file names are in "sumfiles{n}" where n is the number of summed files created,
;	(b) "n_sumfiles{maxtypes}" is the number of summed files of each type.]
;
;
; *** NEXT STEP ***   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Construct normalized background, if there is one.
fbdata_qty=fltarr(nhedet)
fbdata_err=fltarr(nhedet)
fbnormalization=fltarr(nhedet)
if (strategy.skipfbgdsubtraction) then goto,done_fbgdsubtraction
;if (n_sumfiles[4] eq 0) then goto,done_fbgdsubtraction
;
repeat begin
	dcs_multiplechoice,dcs_base,decision_bs,"Background_subtraction",message_str,60,$
		skipdefaultchoices=strategy.skipdefaultchoices
	if (decision_bs eq 5) then return
	dcs_bgd_subtract,dcs_base,sumfiles,n_sumfiles,nhedet,decision_bs,logentry=logentry,$
		fbdata_qty=fbdata_qty,fbdata_err=fbdata_err,fbnormalization=fbnormalization
endrep until (decision_bs ge 0)
;
done_fbgdsubtraction:
;
if (not lmgr(/demo)) then begin
	openw,unit,!logfile,/get_lun
	printf,unit,logentry
	free_lun,unit
endif
;
; [The variables "fbdata_qty{nhedet}", "fbdata_err{nhedet}" and
;		"fbnormalization{nhedet}" have been defined.]
;
;
; *** NEXT STEP ***   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Have the user define detector efficiencies.
decision_det_eff=0
;if (not strategy.setunitydeteffs and n_sumfiles[2] eq 1) then $
if (not strategy.setunitydeteffs) then $
	dcs_multiplechoice,dcs_base,decision_det_eff,"Detector_efficiencies",message_str,60,$
		skipdefaultchoices=strategy.skipdefaultchoices
;
if (n_sumfiles[2] eq 1) then begin; this means there is a Vanadium run
	ns=n_sumfiles[0]+n_sumfiles[1]
	vansumfile=sumfiles[ns]
endif else vansumfile=""
;
if (decision_det_eff eq 4) then return
dcs_choose_det_eff,dcs_base,det_eff_qty,det_eff_err,decision_det_eff,message_str,nhedet=nhedet,$
	vansumfile=vansumfile,skipdefaultchoices=strategy.skipdefaultchoices,logentry=logentry
;
if (not lmgr(/demo)) then begin
	openw,unit,!logfile,/get_lun
	printf,unit,logentry
	free_lun,unit
endif
;
; [The variables "det_eff_qty{nhedet}" and "det_eff_err{nhedet}" have been defined.]
;
;
; *** NEXT STEP ***   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Have the user define detector groupings.
;
if (strategy.nodetectorgrouping) then decision_grouping=1 else begin
	dcs_multiplechoice,dcs_base,decision_grouping,"Detector_grouping",message_str,60,$
		skipdefaultchoices=strategy.skipdefaultchoices
	if (decision_grouping eq 2) then return
endelse
;
dogrouping:
grouping=intarr(nhedet)
doQgrouping=0
dcs_choose_grouping,dcs_base,nhedet,lambda,decision_grouping,grouping,ngroups,$
	angle_props,Q_props,elasticqvals=elasticqvals,doQgrouping,strategy.do2thetagrouping
;
if (decision_grouping eq 0) then $
	logentry=logentry+string(10B)+"Detector groups have been defined." else $
	logentry=logentry+string(10B)+"NO detector groups have been defined."
;
if (not lmgr(/demo)) then begin
	openw,unit,!logfile,/get_lun
	printf,unit,logentry
	free_lun,unit
endif
;
; [The variables "grouping{nhedet}","angle_props{ngroups,3}" and
; "Q_props{ngroups,3}" have been defined (rows 1, 2, 3 are mean, min and max).
;	Also doQgrouping is defined.]
;
;
; *** NEXT STEP ***   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Perform corrections, i.e. "fast background" subtraction, detector grouping, detector
; efficiency correction, data normalization, corrections for container and absorber runs.
;
dcs_multiplechoice,dcs_base,decision,"Group_correct_normalize",message_str,60,$
	skipdefaultchoices=strategy.skipdefaultchoices
if (decision eq 1) then begin
	decision_grouping=0
	goto,dogrouping
endif
if (decision eq 2) then return
;
dcs_docorrections,dcs_base,sumfiles,n_sumfiles,det_eff_qty,det_eff_err,grouping,ngroups,$
	angle_props,Q_props,samfiles,temperatures,logentry=logentry,elasticqvals=elasticqvals,$
	fbdata_qty=fbdata_qty,fbdata_err=fbdata_err,fbnormalization=fbnormalization,doQgrouping,$
	message_str,skipdefaultchoices=strategy.skipdefaultchoices
;
if (not lmgr(/demo)) then begin
	openw,unit,!logfile,/get_lun
	printf,unit,logentry
	free_lun,unit
endif
;
; [The string array "samfiles{n}" has been defined: n is the number of corrected sample files created
;		and samfiles contains the names of the corrected sample files created.]
;
;
; *** NEXT STEP ***   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;	Convert data to d2sigma/domegadt or some other quantity, then save results of data reduction.
savescattering:
;
dcs_save_scattering,dcs_base,samfiles,temperatures,logentry=logentry,message_str=message_str
;
dcs_multiplechoice,dcs_base,decision,"Save_scattering",message_str,60,$
	skipdefaultchoices=strategy.skipdefaultchoices
;
if (not lmgr(/demo)) then begin
	openw,unit,!logfile,/get_lun
	printf,unit,logentry
	free_lun,unit
endif
;
if (decision eq 1) then return
if (decision eq 2) then goto,savescattering
;
;
; *** NEXT STEP ***   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Clean up files.
dcs_cleanup,dcs_base,message_str,skipdefaultchoices=strategy.skipdefaultchoices
;
;x=dialog_message("Data reduction completed. Click ''OK'' to proceed.",/information)
;
end
