; $Id: davedat2d__xspec.pro,v 1.5 2005/02/08 17:17:34 azuah Exp $
;###############################################################################
;
; CLASS NAME:
;   DaveDat2D
;
; PURPOSE:
;   This class encapsulates a DAVE formated dataset containing 2D
;   data.
;
; CATEGORY:
;   Data Browser
;
; SUPERCLASSES:
;   DaveDat
;
; PUBLIC METHODS:
;   Clone
;   Get
;   Print
;   Rebin
;   ResetData
;   Restore
;   Set
;   Transpose
;   XSpec
;
; 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.
;
;###############################################################################



;===============================================================================
; DaveDat2D::transpose
; 
; PURPOSE:
;   Transpose the current object's data and swap x and y axes.
;
; PARAMETERS:
;   axis [in] - (string) Is the axis (either 'x' or 'y') along which
;               the 'spectrum' should be extracted. That is, the axis
;               values become the independent variable of the
;               extracted data.
;
;   spectrum [in] - (integer) the zero-based index value of the
;                   spectrum to be extracted.
;
; KEYWORDS:
;
; RETURN VALUE: 
;   A NULL object, on failure
;   A new DaveDat1D object, on success
;
function DaveDat2D::xspec, axis, spectrum

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

retFail = obj_new()


; ensure (required) number of parameters are present
if (n_params() ne 2) then begin
    !error_state.code = -1
    !error_state.msg = "DaveDat2D::xspec: Inappropriate number of parameters"
    return, retFail
endif

; ensure axis is a string and set to 'x' or 'y'
if (vartype(axis) eq 'STRING') then begin
    if ((strupcase(axis) ne 'X') and (strupcase(axis) ne 'Y')) then begin
        !error_state.code = -1
        !error_state.msg = "DaveDat2D::xspec: first parameter should be either 'X' or 'Y'"
        return, retFail
    endif
endif else begin
    !error_state.code = -1
    !error_state.msg = "DaveDat2D::xspec: first parameter (axis) should be a string ('X' or 'Y')"
    return, retFail
endelse

; ensure lolim, hilim and binw have integral type
if ((vartype(spectrum) ne 'BYTE') and $
    (vartype(spectrum) ne 'INT') and $
    (vartype(spectrum) ne 'LONG') ) then begin
    !error_state.code = -1
    !error_state.msg = "DaveDat2D::xspec: second parameter (spectrum) should be an integer"
    return, retFail
endif

; spectrum should be scaler
if ((n_elements(spectrum) ne 1) or (spectrum[0] lt 0)) then begin
    !error_state.code = -1
    !error_state.msg = "DaveDat2D::xspec: second parameter should be a scaler which is >= 0"
    return, retFail
endif

; Get the data - depends on the axis 
case strupcase(axis) of 
    'X': begin 
        if (not self->get(xval=xval,zval=zval,zerr=zerr,nameTag=nameTag, $
                          xtype=xtype,xlabel=xlabel,xunits=xunits, $
                          zlabel=zlabel,zunits=zunits,treatment=trmt,xDir=xDir $
                          ,scalefactor=sfactor,descriptr=dscPtr,daveptr=dPtr)) then return, 0
        info = size(zval)
        outOfBounds = (spectrum ge info[2])
        if (outOfBounds) then begin
            if (ptr_valid(dscPtr)) then ptr_free, dscPtr
            if (ptr_valid(dPtr)) then heap_free, dPtr
            !error_state.code = -1
            !error_state.msg = "DaveDat2D::xspec: There is no spectrum ("+strtrim(string(spectrum+1),2)+") for the specified axis"
            return, retFail
        endif
        zval = zval[*,spectrum]
        zerr = zerr[*,spectrum]
    end
    'Y': begin
        if (not self->get(yval=xval,zval=zval,zerr=zerr,nameTag=nameTag, $
                          ytype=xtype,ylabel=xlabel,yunits=xunits, $
                          zlabel=zlabel,zunits=zunits,treatment=trmt,yDir=xDir $
                          ,scalefactor=sfactor,descriptr=dscPtr,daveptr=dPtr)) then return, 0
        info = size(zval)
        outOfBounds = (spectrum ge info[1])
        if (outOfBounds) then begin
            if (ptr_valid(dscPtr)) then ptr_free, dscPtr
            if (ptr_valid(dPtr)) then heap_free, dPtr
            !error_state.code = -1
            !error_state.msg = "DaveDat2D::xspec: requested spectrum is not available"
            return, retFail
        endif
        zval = reform(zval[spectrum,*])
        zerr = reform(zerr[spectrum,*])
    end
endcase

;; add additional entry in treatment
line = '=================================================='
trmt = [trmt, $
        line, $
        'Spectrum '+strtrim(string(spectrum),2)+' extracted along '+axis+'-axis']

;; modify the davePtr because some things should/might change in going
;; from the current object to the new 1D object

;(*(*dPtr).descriPtr) = (*dscPtr)
(*(*(*dPtr).dataStrPtr).commonStr.treatmentPtr) = trmt
(*(*(*dPtr).dataStrPtr).commonStr.histPtr) = {qty:zval, $
                                              err:zerr, $
                                              x:xval, $
                                              y:0.0}

(*(*dPtr).dataStrPtr).commonStr.xlabel = xlabel
(*(*dPtr).dataStrPtr).commonStr.xtype = xtype
(*(*dPtr).dataStrPtr).commonStr.xunits = xunits
(*(*dPtr).dataStrPtr).commonStr.histlabel = zlabel
(*(*dPtr).dataStrPtr).commonStr.histunits = zunits

; modify nameTag to include spectrum
axistext = (strupcase(axis) eq 'X')? '_of_y-axis_' : '_of_x-axis_'
nameTag = 'spec'+strtrim(string(spectrum+1),2)+axistext+nameTag
;; create the 1D object from the davePtr
newObj = obj_new('davedat1d',davePtr=dPtr,scalefactor=sfactor,nameTag=nameTag)
if (not obj_valid(newObj)) then begin
    heap_free, dPtr
    ptr_free, dscPtr
    return, retFail
endif
if (not newObj->set(descriPtr=dscPtr,xDir=xDir)) then begin ; assign descriPtr to new object
    heap_free, dPtr
    ptr_free, dscPtr
    obj_destroy, newObj
    return, retFail
endif

;; cleanup 
heap_free, dPtr
ptr_free, dscPtr

return, newObj
end
;_______________________________________________________________________________
