; $Id: hfbs_hscn.pro,v 1.8 2005/02/09 16:58:01 dimeo Exp $
;###############################################################################
;
; NAME:
;  HFBS_HSCN
;
; PURPOSE:
;
;
; CATEGORY:
;  DAVE, HFBS, data reduction
;
; AUTHOR:
;   Robert M. Dimeo, Ph.D.
;   NIST Center for Neutron Research
;   100 Bureau Drive
;   Gaithersburg, MD 20899
;   Phone: (301) 975-8135
;   E-mail: robert.dimeo@nist.gov
;   http://www.ncnr.nist.gov/staff/dimeo
;
; 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 of if the code in this file is
;  included in another product.
;
;###############################################################################
; HFBS_HSCN.PRO
;
; Fixed window scan data reduction utility.
;
; Written by R.M.Dimeo (01/23/02)
;
; Modification history:
; ---------------------
;
;;;;;;;;;;;;;;;;;;;;;;;
pro hscnQuit,event
widget_control,event.top,get_uvalue = pState,/no_copy
(*pState).msg = 'CANCEL'
widget_control,event.top,set_uvalue = pState,/no_copy
widget_control,event.top,/destroy
return
end
;;;;;;;;;;;;;;;;;;;;;;;
pro hscnDaveView,event
widget_control,event.top,get_uvalue = pState,/no_copy
if n_elements(*(*pState).outFilePtr) eq 0 then begin
  widget_control,event.top,set_uvalue = pState,/no_copy
  void = dialog_message(dialog_parent = event.top,'No new DAVE files')
  return
endif else begin
  (*pState).msg = 'DISMISS'
  widget_control,event.top,set_uvalue = pState,/no_copy
  widget_control,event.top,/destroy
endelse
return
end
;;;;;;;;;;;;;;;;;;;;;;;
pro hscnSelFiles,event
widget_control,event.top,get_uvalue = pState,/no_copy
files = dialog_pickfile(dialog_parent = event.top,/read, $
                               filter = ['*.hscn'],$
                               title = 'Select raw data file',$
                               path = (*pState).path,$
                               /multiple_files)
nfiles = n_elements(files)
if (1.0*total(file_test(files,/regular)) ne nfiles) then begin
  void = dialog_message(dialog_parent = event.top,'At least one of the selected files is invalid')
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif
*(*pState).filePtr = files
widget_control,(*pState).fileText,set_value = files
widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;;;;;;;;;;;;;;;;;;;;;;;
pro hscnTreatSum,event
widget_control,event.top,get_uvalue = pState,/no_copy
; Read in the individual files
nfiles = n_elements(*(*pState).filePtr)
; Let's start reading in the data files.
;
; First desensitize all widgets
widget_control,event.top,sensitive = 0
widget_control,(*pState).fileText,sensitive = 1

; Get the date
  caldat,systime(/julian),month,day,year
  date = strcompress(string(month))+$
        '/'+strcompress(string(day))+$
        '/'+strcompress(string(year))

widget_control,(*pState).normGroup,get_value = normIndex
thisIndex = bytarr(2)
thisIndex[normIndex[0]] = 1
norm2Mon = thisIndex[0]
norm2Time = thisIndex[1]
filename = strarr(nfiles)
fileOut = strarr(nfiles)

datPtr = ptrarr(24,/allocate_heap)
errPtr = ptrarr(24,/allocate_heap)

for i = 0,nfiles-1 do begin
    file = (*(*pState).filePtr)[i]
    extPos = strpos(file,'.hscn')
    filename[i] = strmid(file,extPos-11,11)
    fileOut[i] = filepath(filename[i],root_dir = (*pState).path);(*(*pState).inPtr).workDir)
    fileOut[i] = fileOut[i] + '.dave'
    HFBS_ReadHSCN,file,time,ctemp,stemp,data,error,comments,$
                  TBM,FC,header,xout,titles,WBM = WBM,norm2Mon = thisIndex[0],$
                  norm2One = 0,norm2Time = thisIndex[1]

    data = transpose(data)
    error = transpose(error)

    datsize = size(data)
    scPos = strpos(header[1],':')	; position of semicolon in header entry for user
    user = strpos(header[1],scPos+1)	; string var with user's name(s)
    time = temporary(time)/60.0
    sx = datsize[1]		; number of temperatures
    sy = datsize[2]
    nchan = sy
    ncycles = sx
    detangles = [14.46,20.98,27.08,32.31,36.0,43.75,51.5,59.25,67.0,$
                     74.75,82.5,90.25,98.0,105.75,113.5,121.5]
    ndet = n_elements(detangles)	; number of q-values
    lamo = 6.27
    q = fltarr(ndet)
    q = (4.0*!pi/lamo)*sin(0.5*!dtor*detangles)
    x = stemp
    y = q
    if i gt 0 then begin
      for j = 0,sy-1 do begin
        oldDat = *datPtr[j]
        oldErr = *errPtr[j]
        combine_data,x,reform(data[*,j]),reform(error[*,j]),$
                     reform(oldx),reform(oldDat),reform(oldErr),$
                     xout,yout,sigout
        *datPtr[j] = yout
        *errPtr[j] = sigout
      endfor
      oldx = xout
    endif else begin
      for j = 0,sy-1 do begin
        *datPtr[j] = reform(data[*,j])
        *errPtr[j] = reform(error[*,j])
      endfor
      oldx = x
    endelse
endfor
x = xout

nchan = n_elements(*datPtr[0])
data = fltarr(nchan,sy)
error = fltarr(nchan,sy)
for j = 0,sy-1 do begin
  data[*,j] = *datPtr[j]
  error[*,j] = *errPtr[j]
endfor
ptr_free,datPtr,errPtr

*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr = {qty:data[*,1:16],$
                                                err:error[*,1:16],$
                                                x:x,$
                                                y:y}
instrument = 'HFBS'
daqmode = 'ELASTIC'
(*(*(*pState).inPtr).dataStrPtr).commonStr.instrument = instrument
(*(*(*pState).inPtr).dataStrPtr).commonStr.xlabel = 'T '
(*(*(*pState).inPtr).dataStrPtr).commonStr.ylabel = 'Q '
(*(*(*pState).inPtr).dataStrPtr).commonStr.xunits = 'temperature:kelvin'
(*(*(*pState).inPtr).dataStrPtr).commonStr.yunits = 'wavevector:A-1'
(*(*(*pState).inPtr).dataStrPtr).commonStr.histunits = ''
(*(*(*pState).inPtr).dataStrPtr).commonStr.histlabel = 'I (arbitrary units)'


 treatment = ['The following files were summed together: ']
for i = 0,nfiles-1 do begin
	treatment = [treatment,(*(*pState).filePtr)[i]]
endfor

treatment = [treatment,'converted from RAW to DAVE']
if norm2Mon eq 1 then treatment = [treatment, 'monitor normalization']
if norm2Time eq 1 then treatment = [treatment,'time normalization']
*(*(*(*pState).inPtr).dataStrPtr).commonStr.treatmentPtr = treatment
(*(*(*pState).inPtr).dataStrPtr).commonStr.xtype = 'POINTS'
(*(*(*pState).inPtr).dataStrPtr).commonStr.ytype = 'POINTS'

specific = 	   {nchan:nchan,$							; number of "energy" channels
                ndet:ndet,$							; number of detectors (or groups)
                ncycles:ncycles,$						; number of raw data file updates
                phiPtr:ptr_new(detangles),$			; detector angles
                qPtr:ptr_new(q),$						; wavevector transfer for each detector
                ePtr:ptr_new(e),$						; energy
                monPtr:ptr_new(transpose(data[*,0])),$
                monErrPtr:ptr_new(transpose(error[*,0])),$
                instrument:instrument,$
                wavelength:lamo,$
                camType:'',$
                daqmode:daqmode,$
                dopplerFrequency:0.0,$
                date:date,$
                user:user,$
                veldist:0.0,$
                temp_sample:stemp,$
                temp_setpoint:ctemp,$
                temp_control:ctemp,$
                timePtr:ptr_new(time),$
                rawFileName:file,$
                comments:header,$
                TBMPtr:ptr_new(TBM),$
                FCPtr:ptr_new(FC),$
                WBMPtr:ptr_new(WBM)}

*(*(*(*pState).inPtr).dataStrPtr).specificPtr = specific

; Now write the pointer out to a dave file
state = *(*pState).inPtr
fileOut = dialog_pickfile(dialog_parent = event.top,/write, $
                               filter = ['*.dave'],$
                               title = 'Output filename',$
                               path = (*pState).path)
fileOut = fileOut + 'scn.dave'
dave_beast_ops,"dup",state,outState
davePtr = ptr_new(outState,/no_copy)
save, davePtr, FILENAME = fileOut
ptr_free,davePtr

; Sensitize the widgets again
widget_control,event.top,sensitive = 1
void = dialog_message(dialog_parent = event.top,['The following file was created:',fileOut])
*(*pState).outFilePtr = fileOut
widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;;;;;;;;;;;;;;;;;;;;;;;
pro hscnTreatSingle,event
widget_control,event.top,get_uvalue = pState,/no_copy
; Read in the individual files
nfiles = n_elements(*(*pState).filePtr)
; Let's start reading in the data files.
;
; First desensitize all widgets
widget_control,event.top,sensitive = 0
widget_control,(*pState).fileText,sensitive = 1

; Get the date
  caldat,systime(/julian),month,day,year
  date = strcompress(string(month))+$
        '/'+strcompress(string(day))+$
        '/'+strcompress(string(year))

widget_control,(*pState).normGroup,get_value = normIndex
thisIndex = bytarr(2)
thisIndex[normIndex[0]] = 1
norm2Mon = thisIndex[0]
norm2Time = thisIndex[1]
filename = strarr(nfiles)
fileOut = strarr(nfiles)
cRates = fltarr(nfiles,16)

for i = 0,nfiles-1 do begin
    file = (*(*pState).filePtr)[i]
    extPos = strpos(file,'.hscn')
    filename[i] = strmid(file,extPos-11,11)
    fileOut[i] = filepath(filename[i],root_dir = (*pState).path);(*(*pState).inPtr).workDir)
    fileOut[i] = fileOut[i] + 'scn.dave'
    HFBS_ReadHSCN,file,time,ctemp,stemp,data,error,comments,$
                  TBM,FC,header,xout,titles,WBM = WBM,norm2Mon = thisIndex[0],$
                  norm2One = 0,norm2Time = thisIndex[1],liveTime = liveTime,$
                  detrates = detrates
    cRates[i,*] = detrates[0:15]
    data = transpose(data)
    error = transpose(error)

    datsize = size(data)
    scPos = strpos(header[1],':')	; position of semicolon in header entry for user
    user = strpos(header[1],scPos+1)	; string var with user's name(s)
    time = temporary(time)/60.0
    sx = datsize[1]		; number of temperatures
    sy = datsize[2]
    nchan = sy
    ncycles = sx
    detangles = [14.46,20.98,27.08,32.31,36.0,43.75,51.5,59.25,67.0,$
                     74.75,82.5,90.25,98.0,105.75,113.5,121.5]
    ndet = n_elements(detangles)	; number of q-values
    lamo = 6.27
    q = fltarr(ndet)
    q = (4.0*!pi/lamo)*sin(0.5*!dtor*detangles)
    x = stemp
    y = q

    *(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr = {qty:data[*,1:16],$
                                                err:error[*,1:16],$
                                                x:x,$
                                                y:y}
    instrument = 'HFBS'
    daqmode = 'ELASTIC'
    (*(*(*pState).inPtr).dataStrPtr).commonStr.instrument = instrument
    (*(*(*pState).inPtr).dataStrPtr).commonStr.xlabel = 'T '
    (*(*(*pState).inPtr).dataStrPtr).commonStr.ylabel = 'Q '
    (*(*(*pState).inPtr).dataStrPtr).commonStr.xunits = 'temperature:kelvin'
    (*(*(*pState).inPtr).dataStrPtr).commonStr.yunits = 'wavevector:A-1'
    (*(*(*pState).inPtr).dataStrPtr).commonStr.histunits = ''
    (*(*(*pState).inPtr).dataStrPtr).commonStr.histlabel = 'I (arbitrary units)'
    treatment = ['file: '+file]
    treatment = [treatment,'converted from RAW to DAVE']
    if norm2Mon eq 1 then treatment = [treatment, 'monitor normalization']
    if norm2Time eq 1 then treatment = [treatment,'time normalization']
    *(*(*(*pState).inPtr).dataStrPtr).commonStr.treatmentPtr = treatment
    (*(*(*pState).inPtr).dataStrPtr).commonStr.xtype = 'POINTS'
    (*(*(*pState).inPtr).dataStrPtr).commonStr.ytype = 'POINTS'

    specific = {nchan:nchan,$							; number of "energy" channels
                ndet:ndet,$							; number of detectors (or groups)
                ncycles:ncycles,$						; number of raw data file updates
                phiPtr:ptr_new(detangles),$			; detector angles
                qPtr:ptr_new(q),$						; wavevector transfer for each detector
                ePtr:ptr_new(e),$						; energy
                monPtr:ptr_new(transpose(data[*,0])),$
                monErrPtr:ptr_new(transpose(error[*,0])),$
                instrument:instrument,$
                wavelength:lamo,$
                camType:'',$
                daqmode:daqmode,$
                dopplerFrequency:0.0,$
                date:date,$
                user:user,$
                veldist:0.0,$
                temp_sample:stemp,$
                temp_setpoint:ctemp,$
                temp_control:ctemp,$
                timePtr:ptr_new(time),$
                rawFileName:file,$
                comments:header,$
                crates:reform(cRates[i,*]),$
                liveTime:liveTime,$
                TBMPtr:ptr_new(TBM),$
                FCPtr:ptr_new(FC),$
                WBMPtr:ptr_new(WBM)}

    *(*(*(*pState).inPtr).dataStrPtr).specificPtr = specific

	; Now write the pointer out to a dave file
	state = *(*pState).inPtr
	dave_beast_ops,"dup",state,outState
	davePtr = ptr_new(outState,/no_copy)
	save, davePtr, FILENAME = fileOut[i]
	ptr_free,davePtr
endfor
; Sensitize the widgets again
widget_control,event.top,sensitive = 1
void = dialog_message(dialog_parent = event.top,['The following files were created:',fileOut])
*(*pState).outFilePtr = fileOut
widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;;;;;;;;;;;;;;;;;;;;;;;
pro hscnProceed,event
widget_control,event.top,get_uvalue = pState,/no_copy
nfiles = n_elements(*(*pState).filePtr)
if nfiles lt 1 then begin
  widget_control,event.top,set_uvalue = pState,/no_copy
  void = dialog_message(dialog_parent = event.top,'No files selected')
  return
endif

; Do we want to sum the data together or
; save the files individually?
widget_control,(*pState).runGroup,get_value = runIndex
if runIndex[0] eq 0 then treat = "INDIVIDUAL" else treat = "SUM"
case treat of
"SUM":	begin
		  widget_control,event.top,set_uvalue = pState,/no_copy
		  hscnTreatSum,event
		  widget_control,event.top,get_uvalue = pState,/no_copy
		end
else:	begin
		  widget_control,event.top,set_uvalue = pState,/no_copy
		  hscnTreatSingle,event
		  widget_control,event.top,get_uvalue = pState,/no_copy
		end
endcase
widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;;;;;;;;;;;;;;;;;;;;;;;
pro hfbs_hscn_event,event
return
end
;;;;;;;;;;;;;;;;;;;;;;;
function hfbs_hscn,group_leader = group_leader
; Widget definition module
widget_control,group_leader,get_uvalue = inPtr	; get the pointer information from group leader
davePtr = (*inPtr).davePtr

butSize = 150
if n_elements(group_leader) gt 0 then begin
  tlb = widget_base(/col,/modal,group_leader = group_leader,$
        title = 'Fixed Window Scan Data Reduction')
endif else begin
  tlb = widget_base(/col,title = 'Fixed Window Scan Data Reduction')
endelse
base = widget_base(tlb,/row)
ctrlbase = widget_base(base,/col)

runTypes = ['Single sample runs','Sum all runs']
runGroup = cw_bgroup(ctrlbase,runTypes,/col,/exclusive,$
           /no_release,set_value = 0,/return_index)
normTypes = ['Beam monitor','Time']
normGroup = cw_bgroup(ctrlbase,normTypes,/col,/exclusive,$
           /no_release,set_value = 0,/return_index)

fileBase = widget_base(base,/col)
void = widget_button(fileBase,value = 'Select file(s)',xsize = butsize,$
       event_pro = 'hscnSelFiles')
fileText = widget_text(fileBase,xsize = 30,ysize = 3,/scroll,/editable,sensitive = 1)

butBase = widget_base(tlb,/row)
void = widget_button(butBase,xsize = butsize,value = 'Reduce data',event_pro = 'hscnProceed')
void = widget_button(butBase,xsize = butsize,value = 'Cancel',event_pro = 'hscnQuit')
void = widget_button(butBase,xsize = butsize,value = 'View new DAVE file(s)',event_pro = 'hscnDaveView')

centertlb,tlb
widget_control,tlb,/realize
msg = 'CANCEL'
path = (*!dave_defaults).workDir
state = {runGroup:runGroup,$
         normGroup:normGroup,$
         filePtr:ptr_new(/allocate_heap),$
         outFilePtr:ptr_new(/allocate_heap),$
         fileText:fileText,$
         path:path,$
         inPtr:davePtr,$
         msg:msg}

pState = ptr_new(state,/no_copy)
widget_control,tlb,set_uvalue = pState
xmanager,'hfbs_hscn',tlb
return,pState
end

;;;;;;;;;;;;;;;;;;;;;;;