; $Id: davedat__define.pro,v 1.9 2007/10/18 20:57:53 azuah Exp $
;###############################################################################
;
; CLASS NAME:
;   DaveDat
;
; PURPOSE:
;   This class encapsulates a DAVE formated dataset
;
; CATEGORY:
;   Data Browser
;
; SUPERCLASSES:
;
; PUBLIC METHODS:
;   Get
;   Set
;   ResetData
;
; AUTHOR:
;   Richard Tumanjong Azuah
;   NIST Center for Neutron Research
;   100 Bureau Drive, Gaithersburg, MD 20899
;   United States
;   azuah@nist.gov; (301) 9755604
;   Oct, 2002
;
; 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.
;
;###############################################################################



;===============================================================================
; DaveDat::Cleanup
;
; PURPOSE:
;   Cleanup method for objects of this class
;
; PARAMETERS:
;
; KEYWORDS:
;
pro DaveDat::Cleanup

; use heap_free recursively deletes a pointer
if (ptr_valid(self.davePtr)) then heap_free, self.davePtr 
if (ptr_valid(self.descriPtr)) then ptr_free, self.descriPtr
if (ptr_valid(self.treatPtr)) then ptr_free, self.treatPtr
if (ptr_valid(self.xvPtr)) then ptr_free, self.xvPtr
if (ptr_valid(self.zvPtr)) then ptr_free, self.zvPtr
if (ptr_valid(self.zePtr)) then ptr_free, self.zePtr

end
;-------------------------------------------------------------------------------



;===============================================================================
; DaveDat::Init
;
; PURPOSE:
;   Initialization method for objects of this class
;
; PARAMETERS:
;
; KEYWORDS:
;   filname [in] - The name of the file from which the DAVE format
;                  data should be retrieved and used for constructing
;                  the object. The filename and davePtr keywords are
;                  mutually exclusive; either one may be used for
;                  creating a DaveDat object but not both.
;
;   davePtr [in] - Specifies a DAVE pointer structure to be used in
;                  constructing the current object. The filename and
;                  davePtr keywords are mutually exclusive; either one
;                  may be used for creating a DaveDat object but not
;                  both.
;
;   nameTag [in] - A string name tag for object.
;
;   scalefactor [in] - a multiplicative scalefactor to be assigned to
;                      the created object's data.
;
; RETURN VALUE:
;     0 signifies failure and 1 success.
;
function DaveDat::init, filename=fname, davePtr=dPtr, scalefactor=sfactor, nameTag=nameTag

; reset !error_state structure, ie clear all errors
message,/reset

;; caller should not specify both filename and davePtr as this is ambiguous
if ((n_elements(fname)  gt 0 ) and (n_elements(dPtr) gt 0)) then begin
    !error_state.msg = 'DaveDat::init: Ambiguous call - cannot specify both filename and davePtr!'
    !error_state.code = -1
    return, 0
endif

if (n_elements(fname) gt 0) then begin
    ;; make sure fname exists
    ffname = findfile(fname,count=cnt)
    if (cnt ge 1) then begin
        self.filename = ffname
        self.nameTag = ffname
        restore,ffname,/RELAXED_STRUCTURE_ASSIGNMENT
        ;; make sure a valid davePtr was restored
        if (ptr_valid(davePtr)) then begin
            self.davePtr = davePtr
        endif else begin
            !error_state.msg = 'DaveDat::init: "'+fname+'" does not contain a valid davePtr'
            !error_state.code = -1
            return, 0
        endelse
    endif else begin
        !error_state.msg = 'DaveDat::init: file "'+fname+'" not found'
        !error_state.code = -1
        return, 0
    endelse

    ;; should have a davePtr by now so initialize rest of class variables
    if (self->DaveDat::resetData() eq 0) then return, 0
endif

if (n_elements(nameTag)) then begin
    if (vartype(nameTag) eq 'STRING') then self.nameTag = nameTag
endif

if (n_elements(dPtr) gt 0) then begin
    if (ptr_valid(dPtr)) then begin
;        dave_beast_ops,'dup',dPtr,davePtr ; make a copy of dPtr
        davePtr = dPtr
        ;; dave_beast_ops procedure does not maintain structure names
        ;; so explicitly copying the contents of the davePtr copy to
        ;; another davePtr created using create_dave_pointer procedure.
        descriPtr = (*davePtr).descriPtr
        if (ptr_valid(descriPtr) && (n_elements(*descriPtr) gt 0)) then begin
           dname = (*descriPtr).name
           dunits = (*descriPtr).units 
           dlegend = (*descriPtr).legend 
           dqty = (*descriPtr).qty 
           derr = (*descriPtr).err 
        endif
        res = create_dave_pointer(dPtrCopy $
                                  ,instrument = (*(*davePtr).dataStrPtr).commonStr.instrument	$
                                  ,qty = (*(*(*davePtr).dataStrPtr).commonStr.histPtr).qty $
                                  ,qtunits = (*(*davePtr).dataStrPtr).commonStr.histunits $
                                  ,qtlabel = (*(*davePtr).dataStrPtr).commonStr.histlabel $
                                  ,err = (*(*(*davePtr).dataStrPtr).commonStr.histPtr).err $
                                  ,xvals = (*(*(*davePtr).dataStrPtr).commonStr.histPtr).x $
                                  ,xtype = (*(*davePtr).dataStrPtr).commonStr.xtype $
                                  ,xunits = (*(*davePtr).dataStrPtr).commonStr.xunits $
                                  ,xlabel = (*(*davePtr).dataStrPtr).commonStr.xlabel $
                                  ,yvals =  (*(*(*davePtr).dataStrPtr).commonStr.histPtr).y $
                                  ,ytype =  (*(*davePtr).dataStrPtr).commonStr.ytype $
                                  ,yunits = (*(*davePtr).dataStrPtr).commonStr.yunits $
                                  ,ylabel = (*(*davePtr).dataStrPtr).commonStr.ylabel $
                                  ,specificstr = (*(*(*davePtr).dataStrPtr).specificPtr) $
                                  ,treatment = (*(*(*davePtr).dataStrPtr).commonStr.treatmentPtr) $
                                  ,dname = dname $
                                  ,dunits = dunits $
                                  ,dlegend = dlegend $
                                  ,dqty = dqty $
                                  ,derr = derr $
                                  ,ermsg = errmsg $
                                 )

        self.davePtr = dPtrCopy ; NOTE: a _copy_ of dPtr is put in object, not dPtr itself
;        heap_free, davePtr ; Should not delete this since it was not created by this procedure!
        if (res ne 1) then begin
           heap_free, dPtrCopy
           !error_state_msg = errmsg
           return, 0
        endif
    endif else begin
        !error_state.msg = 'DaveDat::init: invalid pointer (davePtr) passed'
        !error_state.code = -1
        return, 0
    endelse
    ;; should have a davePtr by now so initialize rest of class variables
    if (self->DaveDat::resetData() eq 0) then return, 0
endif

if (n_elements(sfactor) gt 0) then begin
    self.scaleFactor = sfactor
endif else begin
    self.scaleFactor = 1.0
endelse

return, 1

end
;-------------------------------------------------------------------------------



;===============================================================================
; DaveDat__define
;
; PURPOSE:
;   Class structure definition procedure
;
; PARAMETERS:
;
; KEYWORDS:
;
pro DaveDat__define

void = {DaveDat, $
        nameTag:'', $           ; a string name tag for object
        nReferences:0b, $       ; nos references to this object
        davePtr: ptr_new(), $   ; davePtr as defined within DAVE
        descriPtr: ptr_new(), $ ; ptr to 'descriPtr' structure
        filename:'', $          ; if applicable, filename from which data obtained
        scaleFactor: 1.0, $     ; scalefactor for this data
        instrument:'',$         ; string containing instrument name
        treatPtr:ptr_new(), $   ; string arr containing data treatment record 
        xvPtr:ptr_new(), $      ; primary independent axis values (x-axis)
        xLabel:'', $            ; x-axis label eg 'Energy transfer'
        xType:'', $             ; x-axis type 'points' or 'hist'
        xUnits:'', $            ; x-axis units eg 'meV'
        xDir:0b, $              ; 0=original x was increasing; 1=x was decreasing with index
        zvPtr:ptr_new(), $      ; dependent values (z-axis)
        zePtr:ptr_new(), $      ; z-axis errors
        zLabel:'', $            ; z-axis labels
        zUnits:'' $             ; z-axis units
       }
end

