' ******************************************************************
' Plotting routines : plot curve with error bars
' ******************************************************************

' ------------------------------------------------------------------
' Constant
' ------------------------------------------------------------------

#DEFINE LinScale 0
' Linear scale

' ------------------------------------------------------------------
' Global variables
' ------------------------------------------------------------------

COMMON SHARED AS INTEGER XScale, YScale
' Axis scales

' ------------------------------------------------------------------
' External functions
' ------------------------------------------------------------------

DECLARE FUNCTION MathErr() AS INTEGER
' Returns the error code from the last procedure call

DECLARE FUNCTION Log10(X AS DOUBLE) AS DOUBLE
' Decimal log

DECLARE FUNCTION Xpixel(X AS DOUBLE) AS INTEGER
' Converts user abscissa X to screen coordinate

DECLARE FUNCTION Ypixel(X AS DOUBLE) AS INTEGER
' Converts user ordinate Y to screen coordinate

DECLARE SUB PlotPoint(X      AS INTEGER, _
                      Y      AS INTEGER, _
                      Symbol AS INTEGER = 1, _
                      Size   AS INTEGER = 2)
' Plots a point

' ******************************************************************

SUB PlotCurveWithErrorBars(X()     AS DOUBLE, _
                           Y()     AS DOUBLE, _
                           S()     AS DOUBLE, _
                           Ns      AS INTEGER = 1, _
                           Symbol  AS INTEGER = 1, _
                           Size    AS INTEGER = 2, _
                           Connect AS INTEGER = 0)
' ------------------------------------------------------------------
' Plots a set of points
' ------------------------------------------------------------------
' Input parameters :
'
' X(), Y() : point coordinates in user units
'
' S()      : errors (standard deviations) in user units
'
' Ns       : number of S.D. for the error bars
'
' Connect  : True if the points must be connected by a line
'
' Other parameters as in PlotPoint
' ------------------------------------------------------------------

  DIM AS INTEGER I, Ierr, N, Lb, Ub, Xp, Yp, Xp1, Yp1, Yp2
  DIM AS DOUBLE  Xi, Yi, Y1, Y2

  Ierr = 0

  Lb = LBOUND(X)
  Ub = UBOUND(X)

  IF Ns > 0 THEN N = Ns ELSE N = 1
  
  FOR I = Lb TO Ub
    IF XScale = LinScale THEN
      Xi = X(I)
    ELSE
      Xi = Log10(X(I))
      Ierr = MathErr
    END IF

    IF YScale = LinScale THEN
      Yi = Y(I)
    ELSEIF Ierr = 0 THEN
      Yi = Log10(Y(I))
      Ierr = MathErr
    END IF

    IF Ierr = 0 THEN
      Xp = Xpixel(Xi)
      Yp = Ypixel(Yi)

      PlotPoint Xp, Yp, Symbol, Size

      IF Connect THEN
        IF I = Lb THEN PSET(Xp, Yp) ELSE LINE (Xp1, Yp1)-(Xp, Yp)
        Xp1 = Xp
        Yp1 = Yp
      END IF

      IF S(I) > 0 THEN
        Y1 = Y(I) - N * S(I)
        IF YScale <> LinScale THEN Y1 = Log10(Y1)
        Y2 = Y(I) + N * S(I)
        IF YScale <> LinScale THEN Y2 = Log10(Y2)
        Yp1 = Ypixel(Y1) 
        Yp2 = Ypixel(Y2)
        LINE (Xp - 5, Yp1) - (Xp + 5, Yp1)
        LINE (Xp - 5, Yp2) - (Xp + 5, Yp2)
        LINE (Xp, Yp1) - (Xp, Yp2)
      END IF
    END IF
  NEXT I
END SUB
