; $Id: larploterr.pro,v 1.18 2005/12/07 20:42:43 kneller Exp $
;###############################################################################
;
;FILENAME:
;larploterr.pro
;
;PURPOSE:
;           Create plots of rhte ooDisplayEcho display class.
;CATEGORY:
;           Data visualization.
;
;METHODS IN FILE:
;
;    setCircleSymbol
;    LarPloterr
;
;
; AUTHOR:
; Larry Kneller
; NIST Center for Neutron Research
; 100 Bureau Drive, Gaithersburg, MD 20899
; United States
; kneller@nist.gov  301-975-8839
; Jan 24,2005
;
; 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.
;
;###############################################################################
;
;
;   Title   LarPloterr.pro
;
;   Author  Larry Kneller
;
;   Purpose     A 2-D plot with error bars and a secondary y axis.
;               This is essentially ploterr with the available options that
;               I want.
;
;               The goal is to be able to overlay several useful data
;               sets for the plot window in my ooDisplayEcho viewer
;               program.  These quantities include:
;                               - a single echo with error bars
;                               - the fit to that echo
;                               - the flipper up and down values
;                               - Bx,By,Bz
;                               - other possible alternative data sets
;
;   Usage
;
;   e.g.
;
;   x = findgen(10)
;   y = 100.0 + 30.0*sin(x)
;   sy = sqrt(y)
;   testPloterr,x,y,x,y,sy,winid=0,title='The Data'
;



pro setCircleSymbol
;
;NAME:
;        setCircleSymbol
;
;PURPOSE:
;           Set up the circle as user-defined psym=8.
;PARAMETERS:
;           none
;KEYWORDS:
;           none

    ;CREATE USER-DEFINED SYMBOL OF A CIRCLE
    ;ACCESS VIA psym=8

    ;102704
    ;CHANGE RADIUS OF CIRCLE SYMBOLS SO THEY DON'T OVERWHELM
    ;VIEW IN PLOTS
    ;
    ;
    ;symrad = 0.15

    symrad = 0.05

    symx = [symrad*(findgen(20)-10.0),symrad*(10.0-findgen(21))]
    symy = sqrt((10.0*symrad)^2 - symx^2)
    symy[21:*] = -1.0*symy[21:*]
    usersym,symx,symy
end;setCircleSymbol

pro LarPloterr,xfull,yfull,syfull,$ ;ORIGINAL RANGES IN CASE OF MASKED VALUES
                        x,y,sy,$
                        ymin=ymin,$
                        ymax=ymax,$
                        symax=symax,$
                        symin=symin,$
                        yoffset=yoffset,$
                        xfit=xfit,$
                        yfit=yfit,$
                        fitplotswitch = fitplotswitch,$
                        bx=bx,$
                        by=by,$
                        bz=bz,$
                        winid=winid,$       ;WINDOW ID
                        psym=psym,$         ;SYMBOL CHOICE
                        symsize=symsize,$   ;SYMBOL SIZE
                        title = title,$     ;PLOT TITLE
                        xmargin = xmargin,$ ;X MARGINS
                        ymargin = ymargin,$ ;Y MARGINS
                        xtitle = xtitle,$   ;X-AXIS TITLE
                        ytitle = ytitle,$   ;Y-AXIS TITLE
                        nodata = nodata,$
                        plotxrange=plotxrange,$
                        plotyrange=plotyrange,$
                        zoomxrange=zoomxrange,$
                        zoomyrange=zoomyrange,$
                        plotzoombox = plotzoombox,$
                        _Extra = _Extra
;
;NAME:
;        LarPloterr
;
;PURPOSE:
;               Create the plots for ooDisplayEcho.
;PARAMETERS:
;               xfull           all x data
;               yfull           all y data
;               syfull          all sy data
;               x               x data to plot
;               y               y data to plot
;               sy              eb's for plot
;KEYWORDS:
;                ymin           ymin
;                ymax           ymax
;                xfit           x values fot fit values
;                yfit           fit values
;                fitplotswitch  switch plotting of fit on/off
;                bx         change in b fields - z
;                by         change in b fields - z
;                bz         change in b fields - z
;                arrb       x array for the b field changes.
;                winid      ;WINDOW ID
;                psym       ;SYMBOL CHOICE
;                title      ;PLOT TITLE
;                xmargin    ;X MARGINS
;                ymargin    ;Y MARGINS
;                xtitle     ;X-AXIS TITLE
;                ytitle     ;Y-AXIS TITLE
;                nodata
;


    ;
    ;PLAN:
    ;
    ;PLOT ALL 'full' VALUES WITH CIRCLES (SET SCALE USING full DATA)
    ;
    ;OVERPLOT MASKED DATA WITH ERROR BARS
    ;
    ;OVER PLOT THE FIT USING THE FULL X-RANGE OF THE
    ;full DATA (EVEN IF POINTS ARE MASKED)
    ;
    ;NOTE: chisq IN THE DATA MUST BE BASED ON THE NON-MASKED DATA.
    ; ---> chisq SHOULD ONLY USE POINTS FROM FIT.
    ;
    ;USE SEPARATE PLOTTING ROUTINE PROCEDURE FOR
    ;CASE WHERE MULTIPLE PLOTS ARE REQUIRED (e.g. MULTIPLE B-FIELDS)
    ;
    ;   HAVE AN ARRAY WHICH TELLS THIS ROUTINE WHAT TO PLOT.
    ;   e.g. 1 FOR PLOT AND 0 FOR NO PLOT.  THIS ARRAY WILL BE
    ;        SET BY THE MENU EVENT HANDLER.
    ;

if n_elements(plotxrange) ne 2 then plotxrange = 0
if n_elements(plotyrange) ne 2 then plotyrange = 0
if n_elements(zoomxrange) ne 2 then zoomxrange = 0
if n_elements(zoomyrange) ne 2 then zoomyrange = 0
if n_elements(plotzoombox) eq 0 then plotzoombox = 0
;if plotzoombox eq 1 then begin
;    print,'In LarPlotErr:'
;    print,plotxrange
;    print,plotyrange
;    print,zoomxrange
;    print,zoomyrange
;
;endif


device,get_decomposed = dc

device,decomposed=0
    tvlct,red,green,blue,/get

    loadct,3,/silent

device,decomposed=1



    if (n_elements(winid) eq 0) then begin
        winid = !d.window
        wset,!d.window
    endif
    if (n_elements(psym) eq 0) then psym = 4
    if (n_elements(symsize) eq 0) then symsize = 1.25
    if (n_elements(title) eq 0) then title = 'DATA'
    if (n_elements(xmargin) eq 0) then xmargin = [10,10]
    if (n_elements(ymargin) eq 0) then ymargin = [5,5]
    if (n_elements(xtitle) eq 0) then xtitle = 'X UNITS'
    if (n_elements(ytitle) eq 0) then ytitle = 'Y UNITS'
    if (n_elements(nodata) eq 0) then nodata = 1

    yerr = abs(syfull)
    yy = yfull
    xx = xfull

    ;;
    ;CREATE USER DEFINED SYMBOLS (psym=8). HERE THEY WILL BE CIRCLES.
    ;THESE WILL BE USED FOR THE SHADOW POINTS.
    ;;;
    setCircleSymbol
    red = 255L
    green = red*256L
    blue = green*256L
    white = red+green+blue
    black = 0L


    ;CHECK THAT THERE ARE ENOUGH POINTS TO PLOT AND
    ;
    nx = n_elements(x)
    ny = n_elements(y)
    nyerr = n_elements(sy)

    ;DECLARE AXIS STRUCTURE AT THIS SCOPE
    tempy = !y
    n = nx < ny < nyerr
    if ((n lt 2) or $
        (nx ne ny) or $
        (ny ne nyerr) or $
        (nx ne nyerr)) then begin

        ;print,'n=',n
        ;print,'ny=',ny
        ;print,'nx=',nx
        ;print,'nyerr=',nyerr

        ;THIS CAN BE A PROBLEM IF THIS DIALOG IS PLACED OVER THE APP IN A
        ;POSITION WHERE THE draw METHOD IS CALLED AS SOON AS THE DIALOG IS CLOSED.
        ;
        ;THE KEY THING TO DO IS TO MAKE SURE THAT YOU ALWAYS HAVE ENOUGH POINTS TO PLOT
        ;BEFORE SENDING DATA TO larploterr.
        ;


        plot,[0,1],[0,0],title='No Data to Plot.  Less then two points.',$
                color=black,background=white


        ;113005
        ;void = dialog_message('There are not enough points to fit' + $
        ;                        'IN LarPloterr')
        print,'There are not enough points to fit in LarPloterr'

        ;print, 'THERE IS A PROBLEM WITH THE PLOT DATA.'
    endif else begin

        ylo = y - sy
        yhi = y + sy


        wset,winid

;ADD LEGENDS FOR THE IUp/Down VALUES.
        cR = 0L;200L
        cG = 200L
        cB = 0L;255L;200L
        iucolor = cR + 256L * (cG + 256L * cB)
        cR = 200L & cG = 0L
        idcolor = cR + 256L * (cG + 256L * cB)
        cR = 200L & cG = 200L & cB = 255L
        ioffsetcolor = cR + 256L * (cG + 256L * cB)


        yrange0 = [min(yy)-max(abs(yerr)),max(yy)+max(abs(yerr))]
        if n_elements(ymax) ne 0 and n_elements(ymin) ne 0 then begin
            yrange0[0] =  min([yy,ymin,ymax])-max(abs(yerr))
            yrange0[1] =  max([yy,ymin,ymax])+max(abs(yerr))
        endif

        if n_elements(plotxrange) eq 2 then xrange0 = plotxrange
        if n_elements(plotyrange) eq 2 then yrange0 = plotyrange
;        yrange0 = [2500,3000]
;        yrange0 = [11500,18500]

;yrange0 = [-1,10]


;102705
;CHANGE MIN HERE TO VIEW Iup,Idown FOR MAGNETIC CASES
 ;       yrange0 = [-(min(yy)+max(abs(yerr))),max(yy)+max(abs(yerr))]

        axiscolor = 0L
        background = 255L + 256L*(255L + 256L*255L)

        ;PLOT FULL SET WITH CIRCLES ONLY AND NO ERROR BARS
;110105
;If available, get ranges and plot zoomed scale.

;if n_elements(xrange0) eq 2 then print,xrange0
;120105
;ZOOMING OPTIONS
if n_elements(xrange0) eq 2 then begin
        plot,xx,yy,title = title,$
                        xrange=xrange0,$
                        yrange=yrange0,$
                        psym=8,$
                        xmargin = xmargin,$
                        ymargin = ymargin,$
                        xtitle = xtitle,$
                        ystyle = 4,$
                        $;ytitle = ytitle,$ ;ADD Y AXIS TITLE ON AXIS CALL BELOW
                        color = axiscolor,$
                        background = background,$
                        nodata = 1,$
                        _Extra = _Extra

;print,yrange0
        axis,yaxis=0,yrange=yrange0,$
                    /save,ytitle=ytitle,color=axiscolor,ystyle=1

endif else begin
        plot,xx,yy,title = title,$
                        yrange=yrange0,$
                        psym=8,$
                        xmargin = xmargin,$
                        ymargin = ymargin,$
                        xtitle = xtitle,$
                        ystyle = 4,$
                        $;ytitle = ytitle,$ ;ADD Y AXIS TITLE ON AXIS CALL BELOW
                        color = axiscolor,$
                        background = background,$
                        nodata = 1,$
                        _Extra = _Extra
        axis,yaxis=0,yrange=yrange0,$
                    /save,ytitle=ytitle,color=axiscolor
endelse



        ;SAVE THIS AXIS FOR MOUSE EVENTS ON PLOT
        tempy = !y

        ;032905
        ;COMMENT OUT THE NEXT LINE SINCE IT SEEMS TO CONFUSE PEOPLE.
        ;oplot,xx,yy,psym=8,symsize = 1.5


        nse_legend,winid,0.1,0.95,'ymax='+strtrim(string(ymax),2),$
                    color = idcolor,$
                    psym = 0,symsize=1
        nse_legend,winid,0.35,0.95,'ymin='+strtrim(string(ymin),2),$
                    color = iucolor,$
                    psym = 0,symsize=1

if n_elements(yoffset) gt 0 then begin
        nse_legend,winid,0.60,0.95,'yoffset='+strtrim(string(yoffset[0]),2),$
                    color = ioffsetcolor,$
                    psym = 0,symsize=1
endif

;041205
;
;MAKE SYMBOLS LESS INTRUSIVE; AND USE A COLOR CODING
;TO REMIND USER WHERE MASKED POINTS ARE.
;
;
        maskedcolor = 0L + 256L*(255L + 256L*255L)  ;light blue
        oplot,xx,yy,psym=4,color=maskedcolor,symsize=symsize


        ;NOW PLOT THE MASKED DATA WITH ERROR BARS
        oplot,x,y,psym=4,color = axiscolor,symsize=symsize;,min_value=yrange0[0],max_value=yrange0[1]
        for i = 0,n-1 do plots,[x[i],x[i]], [ylo[i], yhi[i]],/data,color = axiscolor

        ;OVERLAY A FIT TO THE FIRST DATA SET
        if (n_elements(yfit) gt 1) and (n_elements(xfit) eq n_elements(yfit)) then begin
            ;!y.range = yrange1

;            tvlct,rtemp,gtemp,btemp,/get
;            dumcol = bindgen(256)
;            tvlct,0*dumcol,dumcol,0*dumcol

            ;091604
            ;
            ;CHECK FOR fitplotswitch - - - IF IT IS THERE
            ;THEN DETERMINE WHETHER TO OVERPLOT THE FIT.
            ;IF IT IS NOT THERE JUST PLOT THE FIT

            cR = 255L
            cG = 0L;255L
            cB = 0L
            fcolor = cR + 256L * (cG + 256L * cB)

;          green = hfbs_GETCOLOR('green', 100)
;          fcolor=green



            if n_elements(fitplotswitch) ne 0 then begin
                if fitplotswitch eq 1 then begin
;                    oplot,xx[0:n_elements(yfit)-1],yfit,psym=0,color=fcolor;225;$
;                                    ;,min_value=yrange1[0],max_value=yrange1[1]
                    oplot,xfit,yfit,psym=0,color=fcolor,thick=2;225;$
                                    ;,min_value=yrange1[0],max_value=yrange1[1]
                endif
            endif else begin
;                    oplot,xx[0:n_elements(yfit)-1],yfit,psym=0,color=fcolor;225;$
;                                    ;,min_value=yrange1[0],max_value=yrange1[1]
                    oplot,xfit,yfit,psym=0,color=fcolor;225;$
                                    ;,min_value=yrange1[0],max_value=yrange1[1]
            endelse
;            tvlct,rtemp,gtemp,btemp

        endif else begin
            ;print,'             NO FIT FOR testPloterr'
            ;
            ;091604
            ;
            ;WHY IS THE NEXT COMMAND HERE??????
            ;

;032905
;            axis,yaxis=1,yrange=yrange0,ytitle=ytitle,color=axiscolor
        endelse

        ;Iup AND Idown VALUES
;        tvlct,rtemp,gtemp,btemp,/get
;        tvlct,0*bindgen(256),0*bindgen(256),bindgen(256)
        cR = 100L;0L;200L
        cG = 200L
        cB = 100L;0L;255L;200L
        iucolor = cR + 256L * (cG + 256L * cB)

        cR = 200L & cG = 100L
        idcolor = cR + 256L * (cG + 256L * cB)
        cR = 200L & cG = 200L & cB = 255L
        ioffsetcolor = cR + 256L * (cG + 256L * cB)

        if (n_elements(ymax) gt 0) then begin
            ;print,'Plotting ymax'
            xmax = [min(xx),max(xx)]
            ymax = [ymax,ymax]
            oplot,xmax,ymax,psym=0,thick = 2,color=idcolor;255,psym=0

            if n_elements(symax) gt 0 then begin
                symax = [symax,symax]
                oplot,xmax,ymax+symax,psym=0,thick = 1,color=idcolor;255,psym=0
                oplot,xmax,ymax-symax,psym=0,thick = 1,color=idcolor;255,psym=0
            endif
        endif
        if (n_elements(ymin) gt 0) then begin
            ;print,'Plotting ymin'
            xmin = [min(xx),max(xx)]
            ymin = [ymin,ymin]
            oplot,xmin,ymin,psym=0,thick = 2,color=iucolor;255,psym=0
            if n_elements(symin) gt 0 then begin
                symin = [symin,symin]
                oplot,xmin,ymin+symin,psym=0,thick = 1,color=iucolor;255,psym=0
                oplot,xmin,ymin-symin,psym=0,thick = 1,color=iucolor;255,psym=0
            endif
        endif
        if (n_elements(yoffset) eq 2) then begin
            ;print,'Plotting ymax'
            xoffset = [min(xx),max(xx)]
            yoffset = [yoffset[0],yoffset[0]]
            oplot,xoffset,yoffset,psym=0,thick = 2,color=ioffsetcolor
;            yoffset = [yoffset[0]-yoffset[1],yoffset[0]-yoffset[1]]
;            oplot,xoffset,yoffset,psym=0,thick = 2,color=ioffsetcolor
;            yoffset = [yoffset[0]+yoffset[1],yoffset[0]+yoffset[1]]
;            oplot,xoffset,yoffset,psym=0,thick = 2,color=ioffsetcolor
        endif
;        tvlct,rtemp,gtemp,btemp

        ;NOW OVER PLOT EACH OF THE MAGNETIC FIELD DATA SETS THAT ARE
        ;PASSED TO LarPloterr

;110105
if plotzoombox eq 1 then begin
    plots,[zoomxrange[0],zoomxrange[1]],[zoomyrange[0],zoomyrange[0]],color=0L
    plots,[zoomxrange[1],zoomxrange[1]],[zoomyrange[0],zoomyrange[1]],color=0L
    plots,[zoomxrange[1],zoomxrange[0]],[zoomyrange[1],zoomyrange[1]],color=0L
    plots,[zoomxrange[0],zoomxrange[0]],[zoomyrange[1],zoomyrange[0]],color=0L
    plots,[zoomxrange[0],zoomxrange[1]],[zoomyrange[0],zoomyrange[0]],color=0L
endif


        ;PUT ALL THE FIELDS INTO A SINGLE ARRAY AND
        ;SET THE ALTERNATE AXIS RANGE FROM THIS
        cR = 1 & cG = 0 & cB = 0
        fccolor = cR + 256L * (cG + 256L * cB)
        yalt= [0]
        bxtest = [0]
        if (n_elements(bx) gt 1) then begin
            yalt = [yalt,bx]
            bxtest = [bxtest,xx]
        endif

        if (n_elements(by) gt 1) then  begin
            yalt = [yalt,by]
            bxtest = [bxtest,xx]
        endif
        if (n_elements(bz) gt 1) then  begin
            yalt = [yalt,bz]
            bxtest = [bxtest,xx]
        endif


        if (n_elements(yalt) gt 1) then begin

            if n_elements(plotxrange) eq 2 and n_elements(bxtest) gt 1 then begin
                bxtest = bxtest[1:*]
                bwh = where(bxtest ge plotxrange[0] and bxtest le plotxrange[1],bcount)
            endif else bcount = 0


            if bcount ne 0 then begin
                yrange2 = [min((yalt[1:*])[bwh]),max((yalt[1:*])[bwh])]
                axis,yaxis=1,yrange=yrange2,$
                        ytitle='Field Change (uT)',$
                        /save,color=axiscolor,ystyle=1
            endif else begin
                yrange2 = [min(yalt[1:*]),max(yalt[1:*])]
                axis,yaxis=1,yrange=yrange2,$
                        ytitle='Field Change (uT)',$
                        /save,color=axiscolor
            endelse



            !y.range = yrange2


;REPLACE xx WITH xarrb
                if n_elements(bx) gt 1 then begin
                    if n_elements(xarrb) eq 0 then $
                        xarrb = xx[0:n_elements(bx)-1]
                    oplot,xarrb,bx,psym=-3,$;xx,bx,psym=-3,$
                        color=100L+256L*(100L + 256L*100L);200L;175L*fccolor
                endif
                if n_elements(by) gt 1 then begin
                    if n_elements(xarrb) eq 0 then $
                        xarrb = xx[0:n_elements(by)-1]
                    oplot,xarrb,by,psym=-3,$;xx,by,psym=-3,$
                        color=150L + 256L * 256L*150L;150L*fccolor
                endif
                if n_elements(bz) gt 1 then begin
                    if n_elements(xarrb) eq 0 then $
                        xarrb = xx[0:n_elements(bz)-1]
                    oplot,xarrb,bz,psym=-3,$;xx,bz,psym=-3,$
                    color=200L + 256L * (200L);125L*fccolor
                endif



        endif else begin
            axis,yaxis=1,yrange=yrange0,ytitle=ytitle,color=axiscolor
        endelse
    endelse

    ;RESET AXIS STRUCTURE FOR CORRECT RESPONSE TO MOUSE POSITION IN PROGRAMS
    ;RELYING ON THIS PROCEDURE.
    !y = tempy
device,decomposed = 0

    tvlct,red,green,blue

device,decomposed = dc


    return  ;RETURN CONTROL TO IDLDE
end;LarPloterr
