; $Id: createobjectgrerrors.pro,v 1.4 2005/02/08 17:17:34 azuah Exp $
;###############################################################################
;
; NAME:
;   createObjectGrErrors
;
; PURPOSE:
;   Create an IDLgrPolyline object to represent errors for a given
;   (x,y,err) dataset.
;
; CATEGORY:
;   Data Browser
;
; AUTHOR:
;   Richard Tumanjong Azuah
;   NIST Center for Neutron Research
;   100 Bureau Drive, Gaithersburg, MD 20899
;   United States
;   azuah@nist.gov; (301) 9755604
;   Nov, 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 of if the code in this file is
;  included in another product.
;
;###############################################################################



;===============================================================================
; createObjectGrErrors
;
; PURPOSE:
;   Create a IDLgrPolyline object to represent errors for a given
;   (x,y,err) dataset.
;
; PARAMETERS:
;
;   xData [in] - a vector specifying the independent (x-axis) values.
;
;   yData [in] - a vector specifying the dependent (y-axis) values.
;
;   yDErr [in] - a vector specifying the corresponding y-axis errors
;
; KEYWORDS:
;   xrange [in] - the x-axis range. The object is only defnined within
;                 this range.
;
;   yrange [in] - the y-axis range. The object is only defnined within
;                 this range.
;
;   zrange [in] - the z-axis range. The object is only defnined within
;                 this range.
;
;   log [in] - not used currently
;
; RETURN VALUE:
;   null object if unsuccessful,  
;   an IDLgrPoliline object if successful.
;
function createObjectGrErrors, log=log,xdata_in,ydata,yderr,xrange=xrange,yrange=yrange,_EXTRA=etc

if (n_params() ne 3) then begin
    !error_state.code = -1
    !error_state.msg = "createObjectGrErrors: Three parameters are required!"    
    return, obj_new()
endif

; Chop off data that fall outside the display range; the display
; range is defined by xrange and yrange keywords
if (n_elements(xrange) gt 0) then begin
    xmin = xrange[0]
    xmax = xrange[1]
    ;; deal with lower x-axis limit
    index = where(xData_in ge xmin, count)
    if (count gt 0) then begin
        xData = xData_in[index]
        yEhi = yData[index] + yDerr[index]
        yElo = yData[index] - yDerr[index]
    endif else begin
        xData = xData_in
        yEhi = yData + yDerr
        yElo = yData - yDerr
    endelse
    ;; deal with upper x-axis limit
    index = where(xData le xmax, count)
    if (count gt 0) then begin
        xData = xData[index]
        yEhi = yEhi[index]
        yElo = yElo[index]
    endif 
endif else begin
    xData = xData_in
    yEhi = yData + yDerr
    yElo = yData - yDerr
endelse
if (n_elements(yrange) gt 0) then begin
    ymin = yrange[0]
    ymax = yrange[1]

    ;; if data is falls entirely outside specified range then exit
    if ((max(yEhi) le ymin) and (max(yElo) le ymin)) then return, obj_new()
    if ((min(yEhi) ge ymax) and (min(yElo) ge ymax)) then return, obj_new()
 
    ;; deal with lower y-axis limit
    index = where(yEhi gt ymin, count)    
    if (count gt 0) then begin
        xData = xData[index]
        yEhi = yEhi[index]
        yElo = yElo[index]
    endif
    index = where(yElo lt ymin, count)    
    if (count gt 0) then begin
        yElo[index] = ymin
    endif
    ;; deal with upper y-axis limit
    index = where(yElo lt ymax, count)    
    if (count gt 0) then begin
        xData = xData[index]
        yEhi = yEhi[index]
        yElo = yElo[index]
    endif
    index = where(yEhi gt ymax, count)    
    if (count gt 0) then begin
        yEhi[index] = ymax
    endif
endif

nd = n_elements(xData) 
nvert = 2*nd                    ; nos of vertices required
ind = lindgen(nd)

;; Define vertices which specify the end points of the lines
;; representing the errorbars
vert = fltarr(2,nvert)          ; array to hold vertices of error lines
vert[0,2*ind] = xData
vert[0,2*ind+1] = xData
vert[1,2*ind] = yElo
vert[1,2*ind+1] = yEhi
;vert[1,2*ind] = (keyword_set(log))? alog10(yElo) : yElo
;vert[1,2*ind+1] = (keyword_set(log))? alog10(yEhi) : yEhi

;; Each errorbar is a polyline with two vertices. 
;; Define an array describibg all the lines
polyline = intarr(3*nd)         ; array to hold polyline descriptions
polyline[ind*3] = 2             ; number of vertices per line
polyline[ind*3+1] = 2*ind       ; the indices which specify vertex 1 of lines
polyline[ind*3+2] = 2*ind+1     ; the indices which specify vertex 2 of lines

;;
oPoly = obj_new('IDLgrPolyline',vert,polylines=polyline,_EXTRA=etc)

return, (obj_valid(oPoly))? oPoly : obj_new()
end
