; $Id: hfbs_scan__define.pro,v 1.8 2006/10/05 00:49:32 g_gasparovic Exp $
;###############################################################################
;
; NAME:
;  HFBS_SCAN__DEFINE
;
; PURPOSE:
;  Object class for fixed window scan data.
;
; CATEGORY:
;  DAVE, HFBS, Fixed Window Scans, Analysis
;
; 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.
;
;###############################################################################
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro hfbs_scan::cleanup
compile_opt idl2,hidden
ptr_free,self.timePtr
ptr_free,self.tsamplePtr
ptr_free,self.tcontrolPtr
ptr_free,self.qPtr
ptr_free,self.iPtr
ptr_free,self.ierrPtr
ptr_free,self.uPtr
ptr_free,self.uerrPtr
ptr_free,self.wbmPtr
ptr_free,self.ibmPtr
ptr_free,self.tbmPtr
ptr_free,self.ratioPtr
ptr_free,self.xfitPtr
ptr_free,self.yfitPtr
ptr_free,self.ydatPtr
ptr_free,self.xdatPtr
ptr_free,self.ydatErrPtr
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hfbs_scan::calc_msd,dets,tsample = tsample,tcontrol = tcontrol
compile_opt idl2,hidden
if keyword_set(tsample) then t = *self.tsamplePtr
if keyword_set(tcontrol) then t = *self.tcontrolPtr
if keyword_set(tsample) and keyword_set(tcontrol) then t = *self.tsamplePtr


; Normalize the data to that at the lowest temperature
data = *self.iPtr
error = *self.ierrPtr
q = *self.qPtr
ndet = n_elements(q)
nchan = n_elements(t)
nt = 1
datSize = size(data)
ngroups = datSize[1]

datanew = data
for i = 1,ndet do begin
  if t[0] gt t[nchan-1] then begin
    normfact = total(data[i,nchan-nt:nchan-1])/nt
  endif else begin
    normfact = total(data[i,0:nt-1])/nt
  endelse
  datanew[i,*] = data[i,*]/normfact
  error[i,*] = error[i,*]/normfact
  data[i,*] = datanew[i,*]
endfor


usq = fltarr(nchan,/nozero)
intensity = fltarr(ndet,/nozero)
uerr = fltarr(nchan,/nozero)
index = dets
qlim = q[index - 1]
nlim = n_elements(index)
ydat = fltarr(ndet,nchan,/nozero)
ydaterr = fltarr(ndet,nchan,/nozero)
xfit = fltarr(ndet,nchan,/nozero)
yfit = fltarr(ndet,nchan,/nozero)

for i = 0,nchan-1 do begin
  intensity[0:ndet-1] = -(alog(data[1:ndet,i]))*3.0
  interr = fltarr(ndet)
  ; Added the factor of 3 in the computation of the error bar (12/17/02)
  ;interr[0:ndet-1] = abs(1.0/data[1:ndet,i])*error[1:ndet,i]
  interr[0:ndet-1] = abs(3.0/data[1:ndet,i])*error[1:ndet,i]
  intlim = fltarr(nlim)
  intlim = intensity[index-1]
  errlim = fltarr(nlim)
  errlim = interr[index-1]
  result = LINFIT(qlim^2,intlim,sdev = errlim,sigma = errs)

  ydat[0:ndet-1,i] = intensity[0:ndet-1]
  ydaterr[0:ndet-1,i] = interr[0:ndet-1]
  xfit[0:ndet-1,i] = q^2
  yfit[0:ndet-1,i] = (result[0]+result[1]*q^2)
  usq[i] = result[1]
  uerr[i] = errs[1]
endfor

*self.xfitPtr = xfit
*self.yfitPtr = yfit
*self.xdatPtr = xfit
*self.ydatPtr = ydat
*self.ydatErrPtr = ydatErr

*self.uPtr = usq
*self.uerrPtr = uerr
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro hfbs_scan::readhscnfile
compile_opt idl2,hidden
filename = self.davePath+self.daveFile

hfbs_readhscn,filename,time,ctemp,stemp,data,error,comments,$
    TBM,FC,header,xout,titles,$
    WBM = wbm, LIVETIME = livetime, $
    norm2Mon = self.norm2Mon

; Scale the data by the livetime
aveTime = (moment(liveTime))[0]
tScale = aveTime/liveTime

; Wed Oct  4 20:16:37 EDT 2006
; Goran.Gasparovic@nist.gov
; Do not scale by time.  This results in double normalizatin: by liveTime
; and by IBM.  Vicky noticed this, as it clearly shows as faulty data.
; Ref Begin gasparovic-061004.01.
tScale=liveTime*0.+1.d0
; End gasparovic-061004.01.

*self.tbmPtr = tbm*tScale
*self.timePtr = time/60.0
*self.tcontrolPtr = ctemp
*self.tsamplePtr = stemp
*self.wbmPtr = wbm*tScale
*self.ibmPtr = fc*tScale

dSize = size(data)
ngroups = dSize[1] & nchan = dSize[2]
ug = 1+bytarr(ngroups)
tArray = ug#tScale
*self.iPtr = data*tArray
*self.ierrPtr = error*tArray

; Calculate the q-values
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]
lamo = 6.27
*self.qPtr = (4.0*!pi/lamo)*sin(0.5*!dtor*detAngles)

end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro hfbs_scan::readdavefile
compile_opt idl2,hidden
filename = self.davePath+self.daveFile
restore,filename = filename

ret_val = GET_DAVE_PTR_CONTENTS(	$
								DAVEPTR ,					$
								INSTRUMENT = instrument,	$
								QTY = qty,					$
								QTUNITS = qtunits,			$
								QTLABEL = qtlabel,			$
								ERR = err,					$
								XVALS = xvals,				$
								XTYPE = xtype,				$
								XUNITS = xunits,			$
								XLABEL = xlabel,			$
								YVALS = yvals,				$
								YTYPE = ytype,				$
								YUNITS = yunits,			$
								YLABEL = ylabel,			$
								SPECIFICSTR = specificstr,	$
								TREATMENT = treatment,		$
								ERMSG = errmsg				)

livetime = *specificstr.lt_ptr
tbm = *specificstr.tbm_ptr
wbm = *specificstr.wbm_ptr
fc = *specificstr.fc_ptr
ctemp = *specificstr.tc_ptr
stemp = *specificstr.ts_ptr
time = *specificstr.time_ptr
q = yvals
data = transpose(qty)
error = transpose(err)

; Scale the data by the livetime
aveTime = (moment(liveTime))[0]
tScale = aveTime/liveTime

*self.tbmPtr = tbm*tScale
*self.timePtr = time/60.0
*self.tcontrolPtr = ctemp
*self.tsamplePtr = stemp
*self.wbmPtr = wbm*tScale
*self.ibmPtr = fc*tScale

dSize = size(data)
ngroups = dSize[1] & nchan = dSize[2]
ug = 1+bytarr(ngroups)
tArray = ug#tScale
*self.iPtr = data*tArray
*self.ierrPtr = error*tArray

*self.qPtr = q
heap_free,daveptr

end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro hfbs_scan::getProperty,	time = time,			$
							path = path,			$
							file = file,			$
							tsample = tsample,		$
							tcontrol = tcontrol,	$
							temperature = temperature, $
							q = q,					$
							intensity = intensity,	$
							error = error,			$
							usq = usq,				$
							uerr = uerr,			$
							wbm = wbm,				$
							ibm = ibm,				$
							tbm = tbm,				$
							xfit = xfit,			$
							yfit = yfit,			$
							xdat = xdat,			$
							ydat = ydat,			$
							yerr = yerr,			$
							ratio = ratio,			$
							eratio = eratio
compile_opt idl2,hidden
if arg_present(time) then time = *self.timePtr
if arg_present(path) then path = self.davePath
if arg_present(file) then file = self.daveFile
if arg_present(tsample) then begin
  tsample = *self.tsamplePtr
  temperature = tsample
endif
if arg_present(tcontrol) then begin
  tcontrol = *self.tcontrolPtr
  temperature = tcontrol
endif
if arg_present(q) then q = *self.qPtr
if arg_present(intensity) then intensity = *self.iPtr
if arg_present(error) then error = *self.ierrPtr
if arg_present(usq) then begin
  if n_elements(*self.uPtr) ne 0 then begin
    usq = *self.uPtr
  endif else begin
    usq = -999
  endelse
endif
if arg_present(uerr) then begin
  if n_elements(*self.uerrPtr) ne 0 then begin
    uerr = *self.uerrPtr
  endif else begin
    uerr = -1
  endelse
endif
if arg_present(wbm) then wbm = *self.wbmPtr
if arg_present(tbm) then tbm = *self.tbmPtr
if arg_present(ibm) then ibm = *self.ibmPtr
if arg_present(ratio) or arg_present(ratioerr) then begin
  x = *self.tbmPtr
  sigx = sqrt(x)
  y = *self.ibmPtr
  sigy = sqrt(y)
  ratio = x/y
  eratio = (x/y)*sqrt((sigx/x)^2+(sigy/y)^2)
endif
; Get the fits and data out
if arg_present(xdat) then xdat = *self.xdatPtr
if arg_present(ydat) then ydat = *self.ydatPtr
if arg_present(yerr) then yerr = *self.ydatErrPtr
if arg_present(yfit) then yfit = *self.yfitPtr
if arg_present(xfit) then xfit = *self.xfitPtr
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hfbs_scan::init,daveFile = daveFile, davePath = davePath, $
         norm2Mon = norm2Mon
compile_opt idl2,hidden
if n_elements(daveFile) eq 0 then begin
  strout = 'This method expects a proper DAVE file'
  void = dialog_message(strout)
  return,0
endif

if n_elements(davePath) eq 0 then begin
  strout = 'This method expects a proper DAVE path'
  void = dialog_message(strout)
  return,0
endif

if n_elements(norm2Mon) eq 0 then norm2Mon = 1
self.norm2Mon = norm2Mon

self.davePath = davePath
self.daveFile = daveFile
self.timePtr = ptr_new(/allocate_heap)
self.tsamplePtr = ptr_new(/allocate_heap)
self.tcontrolPtr = ptr_new(/allocate_heap)
self.qPtr = ptr_new(/allocate_heap)
self.iPtr = ptr_new(/allocate_heap)
self.ierrPtr = ptr_new(/allocate_heap)
self.uPtr = ptr_new(/allocate_heap)
self.uerrPtr = ptr_new(/allocate_heap)
self.wbmPtr = ptr_new(/allocate_heap)
self.ibmPtr = ptr_new(/allocate_heap)
self.tbmPtr = ptr_new(/allocate_heap)
self.ratioPtr = ptr_new(/allocate_heap)

self.xfitPtr = ptr_new(-999)
self.yfitPtr = ptr_new(-999)
self.xdatPtr = ptr_new(-999)
self.ydatPtr = ptr_new(-999)
self.ydatErrPtr = ptr_new(-999)


return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro hfbs_scan__define
compile_opt idl2,hidden
define = {	hfbs_scan,					$
			timePtr:ptr_new(),			$
			tsamplePtr:ptr_new(),		$
			tcontrolPtr:ptr_new(),		$
			qPtr:ptr_new(),				$
			iPtr:ptr_new(),				$
			ierrPtr:ptr_new(),			$
			uPtr:ptr_new(),				$
			uerrPtr:ptr_new(),			$
			wbmPtr:ptr_new(),			$
			ibmPtr:ptr_new(),			$
			tbmPtr:ptr_new(),			$
			ratioPtr:ptr_new(),			$
			daveFile:'',				$
			davePath:'',				$
			norm2Mon:1,					$
			xfitPtr:ptr_new(),			$
			yfitPtr:ptr_new(),			$
			xdatPtr:ptr_new(),			$
			ydatPtr:ptr_new(),			$
			ydatErrPtr:ptr_new()		$
		 }
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;