home *** CD-ROM | disk | FTP | other *** search
- /*
- * hippoplot.c - Routines for displaying hippo ntuples.
- *
- * Copyright (C) 1991 The Board of Trustees of The Leland Stanford
- * Junior University. All Rights Reserved.
- *
- * $Id: hippoplot.c,v 3.20 1992/04/24 01:12:19 rensing Rel $
- *
- * by jonas karlsson, at SLAC, August 1990
- * split up by Paul Rensing, Feb 28,1991
- * modified by M. Gravina, March 28, 1991
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <string.h>
- #include <float.h>
- #include <ctype.h>
- #include "hippo.h"
- #include "hippoutil.h"
-
- GLOB_QUAL const char hippoplot_c_rcsid[] =
- "$Id: hippoplot.c,v 3.20 1992/04/24 01:12:19 rensing Rel $";
-
-
- #ifdef _NEXT_PLOT_
- #include "hippoplotNeXT.h"
- #ifndef DEF_PLOT_DRVR
- #define DEF_PLOT_DRVR NEXT
- #endif
- #endif
-
- #ifdef _UNIXPLOT_PLOT_
- #include "hippoplotUP.h"
- #ifndef DEF_PLOT_DRVR
- #define DEF_PLOT_DRVR UNIXPLOT
- #endif
- #endif
-
- #ifdef _XIV_PLOT_
- #include "hippoplotXIV.h"
- #ifndef DEF_PLOT_DRVR
- #define DEF_PLOT_DRVR XIVPLOT
- #endif
- #endif
-
- #ifdef _X11_PLOT_
- #include "hippoplotX11.h"
- #ifndef DEF_PLOT_DRVR
- #define DEF_PLOT_DRVR X11PLOT
- #endif
- #endif
-
- #ifdef THINK_C
- #include "hippoplotMAC.h"
- #ifndef DEF_PLOT_DRVR
- #define DEF_PLOT_DRVR MAC
- #endif
- #endif
-
- #include "hippoplotPS.h"
- #ifndef DEF_PLOT_DRVR
- #define DEF_PLOT_DRVR PSPLOT
- #endif
-
- #define NUM_FUZZ FLT_EPSILON*4
-
- /* find offset to matrix element */
- #define INDEX(row, column, totcols) ((row) * (totcols) + (column))
- #define BININDEX(x, y, z, xs, ys) ((xs) * (ys) * (z) + (x) * (ys) + y)
-
- #define MIN(x, y) (((x) > (y)) ? (y) : (x))
- #define MAX(x, y) (((x) > (y)) ? (x) : (y))
-
- #define XPADDING(disp) ((disp)->drawRect.size.width*0.01)
- #define YPADDING(disp) ((disp)->drawRect.size.height*0.01)
-
-
- #ifdef VMS
- #define Concat3(x,y,z) x/**/y/**/z
- #else
- #define Concat3(x,y,z) x##y##z
- #endif
-
- #ifdef _NEXT_PLOT_
- #define NeXTFunc(name,parm) \
- case NEXT: \
- rc = Concat3(name,_NeXT,parm); \
- break;
-
- #else
- #define NeXTFunc(name,parm)
- #endif
-
- #ifdef _UNIXPLOT_PLOT_
- #define UPFunc(name,parm) \
- case UNIXPLOT: \
- rc = Concat3(name,_UP,parm); \
- break;
-
- #else
- #define UPFunc(name,parm)
- #endif
-
- #ifdef _XIV_PLOT_
- #define XIVFunc(name,parm) \
- case XIVPLOT: \
- Concat3(name,_XIV,parm); \
- rc = 0; \
- break;
-
- #else
- #define XIVFunc(name,parm)
- #endif
-
- #ifdef _X11_PLOT_
- #define X11Func(name,parm) \
- case X11PLOT: \
- Concat3(name,_X11,parm); \
- rc = 0; \
- break;
-
- #else
- #define X11Func(name,parm)
- #endif
-
- #ifdef THINK_C
- #define MACFunc(name,parm) \
- case MAC: \
- Concat3(name,_MAC,parm); \
- rc = 0; \
- break;
-
- #else
- #define MACFunc(name,parm)
- #endif
-
- /*
- * always make PS driver available
- */
- #define PSFunc(name,parm) \
- case PSPLOT: \
- case EPSPLOT: \
- Concat3(name,_PS,parm); \
- rc = 0; \
- break;
-
- #define PlotSwitch(drvr,name, parm) \
- switch (drvr) \
- { \
- NeXTFunc(name,parm) \
- UPFunc(name,parm) \
- XIVFunc(name,parm) \
- X11Func(name,parm) \
- MACFunc(name,parm) \
- PSFunc(name,parm) \
- default: \
- rc = -1; \
- }
-
- struct maxs
- {
- float xl,xh,yl,yh;
- };
-
-
- /*
- * private functions
- */
- static float calcTicks(float size, float *magnitude);
-
- static int drawData( display disp );
- static int drawData1D( display disp );
- static int drawAxis( display disp );
- static int drawLabels( display disp );
-
- static int drawLego1D(display disp, float *lego, int *over, int npts);
- static int drawPoint1D(display disp, float *xy, int *over, int npts);
- static int drawError1D(display disp, float *xy, float *err,
- int *over, int npts, int err_type);
- static int drawLine1D(display disp, float *xy, int *over,
- int npts, int xmin_pt, linestyle_t ls);
- static void box_cross(float *p1, float *p2, display disp);
- int intcmp(const void *i1, const void *i2);
-
- static int drawColor2D(display disp);
- static int drawScatter2D(display disp);
- static int drawLego2D(display disp);
-
- static int initPlot(display disp);
- static int endPlot(display disp);
- static int drawAxisBox( display disp );
- static int drawTicks(display disp, binding_t axis);
- static int drawXTicks(float *ticks, int nticks, float tickLength, char tickLoc );
- static int drawYTicks(float *ticks, int nticks, float tickLength, char tickLoc );
- static int drawMag( float x, float y, int mag, float fontSize );
-
- static int drawText(char *s, float x, float y, float fontsize, float angle,
- char xp, char yp );
-
- static int getXYData( display disp, float **xy, float **xerr,
- float **yerr, int **over, struct maxs *m, int *xmin_pt);
- static int getHistoData( display disp, float **xy, float **xylego,
- float **xerr, float **yerr, int **over,struct maxs *m);
- static int getScatData( display disp, float **xy, struct maxs *m );
-
- static int plotFunc(display disp, func_id fun );
-
- /*
- * global variables.
- */
- static int init_done;
- static plotdrvr_t plot_drvr = DEF_PLOT_DRVR;
-
- #ifdef _XIV_PLOT_
- /* For passing to the X Interviews driver... */
- static void* canvas;
- static void* painter;
- #endif
-
- #ifdef _X11_PLOT_
- /* for passing to X11 driver ... */
- static void* dpy;
- static void* screen;
- static void* drawable;
- static void* gc;
- #endif
-
-
- int h_setPlotDrvr( plotdrvr_t drvr, ...)
- {
- int rc;
- va_list argPtr;
- void *parm;
-
- switch (drvr)
- {
- #ifdef _NEXT_PLOT_
- case NEXT:
- #endif
- #ifdef _XIV_PLOT_
- case XIVPLOT:
- #endif
- #ifdef _X11_PLOT_
- case X11PLOT:
- #endif
- #ifdef THINK_C
- case MAC:
- #endif
- case LPR:
- rc = 0;
- break;
-
- case PSPLOT:
- case EPSPLOT:
- va_start( argPtr, drvr );
- parm = va_arg(argPtr, FILE *);
- rc = initDrvr_PS( parm );
- va_end(argPtr);
- break;
-
- #ifdef _UNIXPLOT_PLOT_
- case UNIXPLOT:
- va_start( argPtr, drvr );
- parm = va_arg(argPtr, FILE *); /* this shit does not work yet */
- rc = initDrvr_UP( parm );
- va_end(argPtr);
- break;
- #endif
-
- default:
- h_error("h_setPlotDrvr - invalid plot driver. Driver may not be compiled in this version.\n");
- rc = -1;
- }
-
- if (rc == 0)
- plot_drvr = drvr;
- else
- h_error("h_setPlotDrvr - error in driver init. Driver not changed.\n");
-
- return rc;
- }
-
- int h_endPlotDrvr( void )
- {
- int rc;
-
- switch (plot_drvr)
- {
- case PSPLOT:
- case EPSPLOT:
- rc = endDrvr_PS( );
- break;
-
- default:
- rc = 0;
- }
-
- return rc;
- }
-
- int h_endPage( void )
- {
- int rc;
-
- switch (plot_drvr)
- {
- case PSPLOT:
- case EPSPLOT:
- rc = endPage_PS( );
- break;
-
- default:
- rc = 0;
- }
-
- return rc;
- }
-
- int h_plot(display disp,...)
- {
- int rc = 0;
- func_id fun;
- #if defined(_XIV_PLOT_) || defined(_X11_PLOT_)
- va_list argPtr;
- #endif
-
- /*
- * be nice. If driver is lineprinter, call h_print.
- */
- if (plot_drvr == LPR)
- {
- h_print( disp );
- return 0;
- }
-
- #ifdef _XIV_PLOT_
- if (plot_drvr == XIVPLOT)
- {
- va_start( argPtr, disp );
- painter = va_arg(argPtr, void *);
- canvas = va_arg(argPtr, void *);
- va_end(argPtr);
- }
- #endif
-
- #ifdef _X11_PLOT_
- if (plot_drvr == X11PLOT)
- {
- va_start( argPtr, disp );
- dpy = va_arg(argPtr, void *);
- screen = va_arg(argPtr, void *);
- drawable = va_arg(argPtr, void *);
- gc = va_arg(argPtr, void *);
- va_end(argPtr);
- }
- #endif
-
- if (h_bin(disp) != 0) return -1;
-
- init_done = 0;
-
- drawData(disp);
-
- for (fun = disp->plot_func; fun != NULL && rc == 0; fun = fun->next )
- {
- rc = plotFunc( disp, fun );
- }
-
- if (disp->flags.drawAxes) drawAxis(disp);
-
- if (disp->flags.drawTitles) drawLabels( disp );
-
- endPlot( disp );
-
- return 0;
- }
-
-
- #define LABEL_SPACE_X 4.0
- #define LABEL_SPACE_Y 4.0
- #define MIN_TICKS 4
- #define MAX_TICKS (MIN_TICKS*2+1)
-
- static float calcTicks(float size, float *magnitude)
- {
- static float goodTicks[] = {10.0, 5.0, 4.0, 2.0, 1.0};
- float tickSize;
- int tickIndex;
-
- if (size <= 0.0)
- {
- h_error("calcTicks: size is <= 0");
- size = fabs(size);
- if (size == 0.0) size = 1.0;
- }
-
- *magnitude = floor(log10(size));
- if (size/pow(10.0,*magnitude) < MIN_TICKS) (*magnitude)--;
-
- /*
- * now fit the max number of ticks into this range
- */
- for (tickIndex = 0;
- size / (tickSize=goodTicks[tickIndex]*pow(10.0,*magnitude) )
- < MIN_TICKS;
- tickIndex++);
-
- if (tickIndex == 0)
- (*magnitude)++;
-
- return tickSize;
- }
-
- static int drawAxis(display disp)
- {
- if (disp == NULL) return -1;
-
- if (disp->graphtype == LEGOPLOT && disp->dim == 2) return 0;
-
- if (!init_done)
- {
- initPlot(disp);
- init_done = 1;
- }
-
- drawAxisBox( disp );
- if (drawTicks(disp,YAXIS))
- h_error("drawAxis: error drawing y ticks");
- if (drawTicks(disp,XAXIS))
- h_error("drawAxis: error drawing x ticks");
-
- return 0;
- }
-
-
- static int drawData(display disp)
- {
- float fontHeight;
-
- if (disp->ntuple == NULL) return 0;
-
- if (disp->ntuple->ndata == 0)
- {
- fontHeight= MIN(disp->drawRect.size.width*0.05,24.0);
- drawText("No Data in Tuple",
- disp->marginRect.origin.x+disp->marginRect.size.width/2.0,
- disp->marginRect.origin.y+disp->marginRect.size.height/2.0,
- fontHeight, 0, 'c', 'c');
- return 0;
- }
-
- switch (disp->graphtype)
- {
- case HISTOGRAM:
- case XYPLOT:
- case STRIPCHART:
- drawData1D( disp );
- break;
-
- case COLORPLOT: /* 2D COLOR */
- drawColor2D(disp);
- break;
-
- case SCATTERPLOT: /* 2D SCATTER */
- drawScatter2D(disp);
- break;
-
- case LEGOPLOT: /* 2D LEGO */
- drawLego2D(disp);
- break;
- }
-
-
- return 0;
- }
-
- static int drawData1D(display disp)
- {
- float *xy = NULL, *lego = NULL, *xerr = NULL, *yerr = NULL;
- int *over = NULL, xmin_pt = 0, npts;
- struct maxs limits;
-
- /*
- * first get the appropriate data, depending on the graphtype.
- */
- switch (disp->graphtype)
- {
- case HISTOGRAM: /* Histogra */
- npts = getHistoData(disp,&xy,&lego,&xerr,&yerr,&over,&limits);
- if (npts == 0) return 0;
- if (npts < 0)
- {
- h_error("h_plot - error getting bin data");
- return -1;
- }
-
- if (disp->yAxis.flags.autoScale)
- {
- if (limits.yh < limits.yl)
- {
- /* must be no points in range. */
- return 0;
- }
- else if (limits.yh == limits.yl)
- {
- /* must be only on point in range. */
- disp->yAxis.low = limits.yh - 0.5;
- disp->yAxis.high = limits.yh + 0.5;
- }
- else
- {
- if (limits.yh > 0.0)
- disp->yAxis.high = limits.yh;
- else
- {
- if (disp->yAxis.flags.log)
- {
- h_error("All data < 0 on log axis");
- return -1;
- }
- disp->yAxis.high = 0.0;
- }
-
- if (limits.yl < 0.0 || disp->yAxis.flags.log)
- disp->yAxis.low = limits.yl;
- else
- disp->yAxis.low = 0.0;
- }
- }
- else if (disp->yAxis.flags.log && disp->yAxis.low <= 0.0)
- {
- if (limits.yl > 0.0)
- disp->yAxis.low = limits.yl;
- else
- disp->yAxis.low = pow(10.0, FLT_MIN);
- if (disp->yAxis.high <= disp->yAxis.low)
- disp->yAxis.high = disp->yAxis.low*(1.0+NUM_FUZZ);
- }
-
- break;
-
- case XYPLOT:
- case STRIPCHART:
- npts = getXYData(disp,&xy,&xerr,&yerr,&over,&limits,&xmin_pt);
- if (npts == 0) return 0;
- if (npts < 0)
- {
- h_error("h_plot - error getting data for x-y plot");
- return -1;
- }
-
- if (disp->graphtype == XYPLOT) xmin_pt = 0;
-
- /*
- * autoscale axes
- */
- if (disp->xAxis.flags.autoScale)
- {
- if (limits.xh > limits.xl)
- {
- disp->xAxis.low = limits.xl;
- disp->xAxis.high = limits.xh;
- }
- else if (limits.xh == limits.xl)
- {
- /* must be only on point in range. */
- disp->xAxis.low = limits.xl - 0.5;
- disp->xAxis.high = limits.xh + 0.5;
- }
- else
- {
- /* must be no points in range. */
- return 0;
- }
- h_adjustAxis(&(disp->xAxis.low), &(disp->xAxis.high),
- 0, disp->xAxis.flags.log);
- }
- else if (disp->xAxis.flags.log && disp->xAxis.low <= 0.0)
- {
- if (limits.xl > 0.0)
- disp->xAxis.low = limits.xl;
- else
- disp->xAxis.low = pow(10.0, FLT_MIN);
- if (disp->xAxis.high <= disp->xAxis.low)
- disp->xAxis.high = disp->xAxis.low*(1.0+NUM_FUZZ);
- }
-
- if (disp->yAxis.flags.autoScale)
- {
- if (limits.yh > limits.yl)
- {
- disp->yAxis.low = limits.yl;
- disp->yAxis.high = limits.yh;
- }
- else if (limits.yh == limits.yl)
- {
- /* must be only on point in range. */
- disp->yAxis.low = limits.yl - 0.5;
- disp->yAxis.high = limits.yh + 0.5;
- }
- else
- {
- /* must be no points in range. */
- return 0;
- }
- }
- else if (disp->yAxis.flags.log && disp->yAxis.low <= 0.0)
- {
- if (limits.yl > 0.0)
- disp->yAxis.low = limits.yl;
- else
- disp->yAxis.low = pow(10.0, FLT_MIN);
- if (disp->yAxis.high <= disp->yAxis.low)
- disp->yAxis.high = disp->yAxis.low*(1.0+NUM_FUZZ);
- }
-
- break;
-
- default:
- h_error("hippo error: invalid disp->graphtype\n");
- return -1;
- break;
- }
-
- if (disp->yAxis.flags.autoScale)
- h_adjustAxis(&(disp->yAxis.low), &(disp->yAxis.high),
- 0, disp->yAxis.flags.log );
-
- /*
- * init the plot device
- */
- if (!init_done)
- {
- initPlot( disp );
- init_done = 1;
- }
-
- /*
- * draw the points, lines etc.
- */
-
- /* draw points */
- if ( disp->drawtype & POINT )
- drawPoint1D(disp, xy, over, npts);
-
- /* draw error bars */
- if ( disp->drawtype & ERRBAR )
- {
- if (yerr != NULL) drawError1D(disp,xy,yerr,over,npts,YERROR);
- if (xerr != NULL) drawError1D(disp,xy,xerr,over,npts,XERROR);
- }
-
-
- /* join points */
- if ( disp->drawtype & LINE )
- drawLine1D(disp,xy,over,npts,xmin_pt,disp->lineStyle);
-
- /* draw bars */
- if ( (disp->drawtype & BOX) && disp->graphtype==HISTOGRAM )
- drawLego1D(disp, lego, over, npts);
-
- free(lego);
- free(xy);
- free(xerr);
- free(yerr);
- free(over);
-
- return 0;
- }
-
-
- static int initPlot(display disp)
- {
- int rc;
- rectangle userRect;
-
- if (disp->xAxis.flags.log)
- {
- userRect.origin.x = log10(disp->xAxis.low);
- userRect.size.width = log10(disp->xAxis.high) -
- log10(disp->xAxis.low);
- }
- else
- {
- userRect.origin.x = disp->xAxis.low;
- userRect.size.width = disp->xAxis.high - disp->xAxis.low;
- }
- if (disp->yAxis.flags.log)
- {
- userRect.origin.y = log10(disp->yAxis.low);
- userRect.size.height = log10(disp->yAxis.high)
- - log10(disp->yAxis.low);
- }
- else
- {
- userRect.origin.y = disp->yAxis.low;
- userRect.size.height = disp->yAxis.high - disp->yAxis.low;
- }
-
- switch (plot_drvr)
- {
- NeXTFunc(initPlot,(&disp->drawRect, &disp->marginRect, &userRect));
- UPFunc(initPlot,(&disp->drawRect, &disp->marginRect, &userRect));
- MACFunc(initPlot,(&disp->drawRect, &disp->marginRect, &userRect));
- PSFunc(initPlot,(&disp->drawRect, &disp->marginRect, &userRect));
-
- #ifdef _XIV_PLOT_
- case XIVPLOT:
- initPlot_XIV(painter,canvas);
- setHistoCoords_XIV(&disp->marginRect, &userRect);
- rc = 0;
- break;
- #endif
-
- #ifdef _X11_PLOT_
- case X11PLOT:
- initPlot_X11(dpy,screen,drawable,gc);
- setHistoCoords_X11(&disp->drawRect, &disp->marginRect, &userRect);
- rc = 0;
- break;
- #endif
-
- default:
- rc = -1;
- }
-
- return rc;
- }
-
-
-
- static int endPlot(display disp)
- {
- int rc;
-
- switch (plot_drvr)
- {
- UPFunc(endPlot,());
-
- default:
- rc = 0;
- }
-
- return rc;
- }
-
-
-
- static int drawLabels( display disp )
- {
- float x, y;
- float fontSize;
- char string[80];
-
- /*
- * title
- */
- fontSize = disp->drawRect.size.width*0.05;
- fontSize = MIN(fontSize,
- (disp->drawRect.size.height -
- disp->marginRect.size.height - 2*YPADDING(disp) -
- (disp->marginRect.origin.y-disp->drawRect.origin.y)));
- x = disp->marginRect.origin.x + 0.5 * disp->marginRect.size.width;
- y = disp->drawRect.origin.y + disp->drawRect.size.height - YPADDING(disp);
- h_expandLabel(string,disp->title,80,disp);
- if (fontSize > disp->marginRect.size.width/strlen(string)*2)
- {
- fontSize = disp->drawRect.size.width/strlen(string)*2;
- x = disp->drawRect.origin.x + 0.5 * disp->drawRect.size.width;
- }
-
- if (drawText(string, x, y, fontSize,0.0,'c','t') != 0)
- {
- h_error("Error drawing plot title");
- return -1;
- }
-
- /*
- * x axis label
- */
- fontSize = MIN(disp->drawRect.size.width*0.04,14.0);
- fontSize = MIN(fontSize,
- (disp->marginRect.origin.y-disp->drawRect.origin.y)/2.0);
- fontSize = MIN(fontSize,
- disp->drawRect.size.width/strlen(disp->xAxis.label)*2);
- y = disp->drawRect.origin.y + YPADDING(disp);
- h_expandLabel(string,disp->xAxis.label,80,disp);
- if (drawText(string, x, y, fontSize,0.0,'c','b') != 0)
- {
- h_error("Error drawing x axis label");
- return -1;
- }
-
- /*
- * y axis label
- */
- fontSize = MIN(disp->drawRect.size.width*0.04,14.0);
- fontSize = MIN(fontSize,
- disp->drawRect.size.height/strlen(disp->yAxis.label)*2);
- x = disp->drawRect.origin.x + XPADDING(disp);
- y = disp->marginRect.origin.y + disp->marginRect.size.height/2.0;
- h_expandLabel(string,disp->yAxis.label,80,disp);
- if (drawText(string, x, y, fontSize,90.0,'c','t') != 0)
- {
- h_error("Error drawing y axis label");
- return -1;
- }
-
-
- return 0;
- }
-
-
-
- static int drawText(char *s, float x, float y, float fontsize, float angle,
- char xp, char yp )
- {
- int rc;
-
- PlotSwitch(plot_drvr,drawText,(s, x, y, fontsize, angle, xp, yp));
-
- return rc;
- }
-
-
- static int drawAxisBox( display disp )
- {
- int rc = 0;
- float xy[10];
-
- if (disp->xAxis.flags.log)
- {
- xy[0] = xy[2] = xy[8] = log10(disp->xAxis.low);
- xy[4] = xy[6] = log10(disp->xAxis.high);
- }
- else
- {
- xy[0] = xy[2] = xy[8] = disp->xAxis.low;
- xy[4] = xy[6] = disp->xAxis.high;
- }
- if (disp->yAxis.flags.log)
- {
- xy[1] = xy[7] = xy[9] = log10(disp->yAxis.low);
- xy[3] = xy[5] = log10(disp->yAxis.high);
- }
- else
- {
- xy[1] = xy[7] = xy[9] = disp->yAxis.low;
- xy[3] = xy[5] = disp->yAxis.high;
- }
-
- PlotSwitch(plot_drvr,drawLine,(xy,5, SOLID));
-
- return rc;
- }
-
- #define N__TICKS 20
-
- static int drawTicks(display disp, binding_t axis)
- {
- int nticks = 0;
- int i, rc=0;
-
- float ticks[N__TICKS];
- char labels[N__TICKS][10];
- float magnitude,y,yr,startTick,tickSize;
- float x=0.0;
- char string[70];
- float fontSize;
- float pmag;
- char pstr[10];
- int nLogTicks;
- float logTicks[5];
- float maglow, maghigh, magrng, magStep;
-
- axis_t *thisaxis;
- char xalign='c', yalign='c';
-
- fontSize = MIN(disp->drawRect.size.width*0.04,14.0);
-
- switch (axis)
- {
- case XAXIS:
- thisaxis = &disp->xAxis;
- break;
- case YAXIS:
- thisaxis = &disp->yAxis;
- break;
- default:
- return -1;
- }
-
- /* draw ticks on y axis */
- if (thisaxis->low >= thisaxis->high)
- {
- h_error("h_plot: axis low > high");
- sprintf(string,"low = %f, high = %f\n",thisaxis->low,
- thisaxis->high);
- h_error(string);
- return -1;
- }
-
- if (!thisaxis->flags.log)
- {
- tickSize = calcTicks((thisaxis->high -
- thisaxis->low), &magnitude);
- startTick = ceil( thisaxis->low / tickSize) * tickSize;
-
- if (fabs(magnitude) <= 3.0)
- pmag = 0.0;
- else
- {
- if (startTick != 0.0)
- pmag = floor(log10(fabs(startTick)));
- else
- pmag = magnitude;
- }
-
- sprintf(pstr,"%%1.%df",(int)MAX((pmag-magnitude),0.0));
-
- y = startTick;
- while (y <= thisaxis->high*(1.0+NUM_FUZZ))
- {
- if (nticks >= N__TICKS)
- {
- h_error("Too many ticks along y axis.");
- return -1;
- }
-
- yr = floor(y/pow(10.0,magnitude) + 0.5);
- ticks[nticks] = yr * pow(10.0,magnitude);
- sprintf(labels[nticks],pstr,yr*pow(10.0,magnitude-pmag));
- nticks++;
- y += tickSize;
- }
- if (fabs(magnitude) <= 3.0) magnitude = 0.0;
- }
- else
- {
- maghigh = ceil(log10(thisaxis->high));
- maglow = floor(log10(thisaxis->low));
- magrng = maghigh - maglow;
-
- if (magrng <=3)
- {
- nLogTicks = 3;
- logTicks[0] = 1.0;
- logTicks[1] = 2.0;
- logTicks[2] = 5.0;
- magStep = 1.0;
- }
- else
- {
- nLogTicks = 1;
- logTicks[0] = 1.0;
- if (magrng <= 7)
- magStep = 1.0;
- else
- magStep = 2.0;
- }
-
- if (nLogTicks == 3 && (fabs(maglow)>3 || fabs(maghigh)>3))
- pmag = maglow;
- else
- pmag = 0.0;
- magnitude = maglow;
- i = 0;
- while ((y=logTicks[i]*pow(10.0,magnitude)) <
- thisaxis->high*(1.0+NUM_FUZZ))
- {
- if (nticks >= N__TICKS)
- {
- h_error("Too many ticks along y axis.");
- return -1;
- }
- if (y >= thisaxis->low)
- {
- ticks[nticks] = log10(y);
- /*
- * be careful: there is a bug in the NeXT (s)printf
- * routine when you do, eg. printf("%1.0g",0.01);
- */
- if ((magnitude-pmag) > 4 || (magnitude-pmag) < -3)
- strcpy(pstr,"%1.0e");
- else
- sprintf(pstr,"%%1.%df",
- (int)((magnitude-pmag)>0?
- 0:-(magnitude-pmag)));
- sprintf(labels[nticks],pstr,y*pow(10.0,-pmag));
- nticks++;
- }
-
- i++;
- if (i>=nLogTicks)
- {
- i = 0;
- magnitude += magStep;
- }
- }
- }
-
- /*
- * Plot the tick marks
- */
- switch (axis)
- {
- case XAXIS:
- drawXTicks(ticks,nticks,thisaxis->tickLength,
- thisaxis->flags.tickLocation);
- break;
- case YAXIS:
- drawYTicks(ticks,nticks,thisaxis->tickLength,
- thisaxis->flags.tickLocation);
- break;
- default:
- return -1;
- }
- if (rc != 0) return rc;
-
- switch (axis)
- {
- case XAXIS:
- y = disp->marginRect.origin.y - YPADDING(disp);
- fontSize = MIN(fontSize,
- (disp->marginRect.origin.y -
- disp->drawRect.origin.y)/2.0);
- xalign = 'c';
- yalign = 't';
- break;
- case YAXIS:
- x = disp->marginRect.origin.x - XPADDING(disp);
- yr = MIN(disp->drawRect.size.width*0.04,14.0);
- yr = MIN(fontSize,
- disp->drawRect.size.height/strlen(disp->yAxis.label)*2);
- fontSize = MIN(fontSize,
- (disp->marginRect.origin.x -
- disp->drawRect.origin.x - yr)
- /strlen(labels[nticks-1]));
- xalign = 'r';
- yalign = 'c';
- break;
- default:
- return -1;
- }
-
- for (i=0; i<nticks; i++ )
- {
- if (!thisaxis->flags.log)
- {
- switch (axis)
- {
- case XAXIS:
- x = disp->marginRect.origin.x +
- (ticks[i]-thisaxis->low) *
- disp->marginRect.size.width
- /(thisaxis->high - thisaxis->low);
- break;
- case YAXIS:
- y = disp->marginRect.origin.y +
- (ticks[i]-thisaxis->low) *
- disp->marginRect.size.height
- /(thisaxis->high - thisaxis->low);
- break;
- default:
- return -1;
- }
- }
- else
- {
- switch (axis)
- {
- case XAXIS:
- x = disp->marginRect.origin.x +
- (ticks[i]-log10(thisaxis->low))
- * disp->marginRect.size.width
- /log10(thisaxis->high/thisaxis->low);
- break;
- case YAXIS:
- y = disp->marginRect.origin.y +
- (ticks[i]-log10(thisaxis->low))
- * disp->marginRect.size.height
- /log10(thisaxis->high/thisaxis->low);
- break;
- default:
- return -1;
- }
- }
-
- if (drawText(labels[i], x, y, fontSize, 0.0,
- xalign, yalign ) != 0)
- {
- h_error("Error draw label on axis.");
- return -1;
- }
- }
-
- if (pmag != 0.0)
- {
- switch (axis)
- {
- case XAXIS:
- x = disp->marginRect.origin.x + disp->marginRect.size.width
- + XPADDING(disp);
- y = disp->marginRect.origin.y;
- break;
- case YAXIS:
- x = disp->marginRect.origin.x;
- y = disp->marginRect.origin.y + disp->marginRect.size.height
- + YPADDING(disp);
- break;
- default:
- return -1;
- }
- drawMag(x, y, (int)pmag, fontSize*0.75 );
- }
-
- return 0;
- }
-
- static int drawXTicks(float *ticks, int nticks, float tickLength, char tickLoc )
- {
- int rc = 0;
-
- if (tickLoc & PLOTBOTTOM)
- {
- PlotSwitch(plot_drvr,drawXTicks,(ticks,nticks,tickLength,0));
- }
- if (tickLoc & PLOTTOP)
- {
- PlotSwitch(plot_drvr,drawXTicks,(ticks,nticks,tickLength,1));
- }
- return rc;
- }
-
-
- static int drawYTicks(float *ticks, int nticks, float tickLength, char tickLoc )
- {
- int rc = 0;
-
- if (tickLoc & PLOTLEFT)
- {
- PlotSwitch(plot_drvr,drawYTicks,(ticks,nticks,tickLength,0));
- }
- if (tickLoc & PLOTRIGHT)
- {
- PlotSwitch(plot_drvr,drawYTicks,(ticks,nticks,tickLength,1));
- }
- return rc;
- }
-
-
- static int drawMag( float x, float y, int mag, float fontSize )
- {
- int rc;
-
- PlotSwitch(plot_drvr,drawMag,( x, y, mag, fontSize ));
-
- return rc;
- }
-
-
-
- static int drawLego1D(display disp, float *xylego, int *over,
- int npts)
- {
- int rc = 0;
- int end;
- int i_over;
- float ylow, yhigh;
-
- if (disp->yAxis.flags.log)
- {
- yhigh = log10(disp->yAxis.high);
- ylow = log10(disp->yAxis.low);
- }
- else
- {
- yhigh = disp->yAxis.high;
- ylow = disp->yAxis.low;
- }
-
- /*
- * first, check the first group of points, since
- * it is not associated with a bin. (last group is check
- * by last element in over)
- */
- if (xylego[1] > yhigh) xylego[1] = yhigh;
- if (xylego[1] < ylow) xylego[1] = ylow;
- if (xylego[3] > yhigh) xylego[3] = yhigh;
- if (xylego[3] < ylow) xylego[3] = ylow;
-
- i_over = 0;
- do
- {
- end = over[i_over++];
- if (xylego[4*(end+1)+1] > yhigh) xylego[4*(end+1)+1] = yhigh;
- if (xylego[4*(end+1)+1] < ylow) xylego[4*(end+1)+1] = ylow;
- if (xylego[4*(end+1)+3] > yhigh) xylego[4*(end+1)+3] = yhigh;
- if (xylego[4*(end+1)+3] < ylow) xylego[4*(end+1)+3] = ylow;
- }
- while (end < npts);
-
-
- PlotSwitch(plot_drvr,drawLine,( xylego, 2*(npts+2), SOLID ));
-
- return rc;
- }
-
-
- static int drawPoint1D(display disp, float *xy, int *over, int npts)
- {
- int rc=0;
- int start = -1, end;
- int i_over=0;
-
- float xlow, ylow;
- float xhigh, yhigh;
-
- if (disp->xAxis.flags.log)
- {
- xhigh = log10(disp->xAxis.high);
- xlow = log10(disp->xAxis.low);
- }
- else
- {
- xhigh = disp->xAxis.high;
- xlow = disp->xAxis.low;
- }
- if (disp->yAxis.flags.log)
- {
- yhigh = log10(disp->yAxis.high);
- ylow = log10(disp->yAxis.low);
- }
- else
- {
- yhigh = disp->yAxis.high;
- ylow = disp->yAxis.low;
- }
-
- do
- {
- /*
- * Check that points marked as over are really over (it may be
- * that error bar is over).
- */
- do
- {
- if (start == -1)
- start = 0;
- else
- start = over[i_over++]+1;
- end = over[i_over];
-
- while (end<npts)
- {
- /* include some fuzz in comparisons */
- if (xy[2*end+1]<(ylow*(1.0-NUM_FUZZ)) ||
- xy[2*end+1]>(yhigh*(1.0+NUM_FUZZ))) break;
- if (xy[2*end]<(xlow*(1.0-NUM_FUZZ)) ||
- xy[2*end]>(xhigh*(1.0+NUM_FUZZ))) break;
- end = over[++i_over];
- }
- }
- while ( (end-start) <= 0 && start<npts );
-
- if (start >= npts) continue;
-
- PlotSwitch(plot_drvr,drawPoints,(&(xy[2*start]),end-start,
- disp->plotSymbol,disp->symbolSize));
- }
- while (rc == 0 && end < npts && start < npts);
-
- return rc;
- }
-
-
- static int drawLine1D(display disp, float *xy, int *over,
- int npts, int xmin_pt, linestyle_t ls)
- {
- int rc = 0;
- int start, end;
- int s_saved, e_saved;
- int i_over = 0;
- float *xy_alt;
- int *over_alt;
- float xlow, ylow;
- float xhigh, yhigh;
-
- float start_save[2],end_save[2];
-
- if (npts < 2) return 0;
-
- if (xmin_pt > 0)
- {
- if ( (xy_alt = (float *)malloc( 2*npts*sizeof(float) ))
- == NULL)
- {
- h_error("drawLine1D - ran out of memory");
- return -1;
- }
- if ( (over_alt = (int *)malloc( (npts+1)*sizeof(int) ))
- == NULL)
- {
- h_error("drawLine1D - ran out of memory");
- return -1;
- }
- memcpy((char *)xy_alt, (char *)&xy[2*xmin_pt],
- 2*(npts-xmin_pt)*sizeof(float) );
- memcpy((char *)&xy_alt[2*(npts-xmin_pt)], (char *)xy,
- 2*xmin_pt*sizeof(float) );
- for (i_over=0; over[i_over]<npts; i_over++ )
- {
- if (over[i_over] >= xmin_pt)
- over_alt[i_over] = over[i_over] - xmin_pt;
- else
- over_alt[i_over] = over[i_over] + npts - xmin_pt;
- }
- over_alt[i_over++] = npts;
- if (i_over > 1)
- qsort( over_alt, (size_t)i_over, sizeof(int), intcmp );
- }
- else
- {
- over_alt = over;
- xy_alt = xy;
- }
-
- if (disp->xAxis.flags.log)
- {
- xhigh = log10(disp->xAxis.high);
- xlow = log10(disp->xAxis.low);
- }
- else
- {
- xhigh = disp->xAxis.high;
- xlow = disp->xAxis.low;
- }
- if (disp->yAxis.flags.log)
- {
- yhigh = log10(disp->yAxis.high);
- ylow = log10(disp->yAxis.low);
- }
- else
- {
- yhigh = disp->yAxis.high;
- ylow = disp->yAxis.low;
- }
-
- i_over = 0;
- start = -1;
- do
- {
- /*
- * Check that points marked as over are really over (it may be
- * that error bar is over). Interpolate to find point where
- * line crosses axes.
- */
- s_saved = 0;
- e_saved = 0;
-
- do
- {
- if (start == -1)
- start = 0;
- else
- start = over_alt[i_over++]+1;
- end = over_alt[i_over];
-
- while (end<npts)
- {
- /* include some fuzz in comparisons */
- if (xy_alt[2*end+1]<(ylow*(1.0-NUM_FUZZ)) ||
- xy_alt[2*end+1]>(yhigh*(1.0+NUM_FUZZ))) break;
- if (xy_alt[2*end]<(xlow*(1.0-NUM_FUZZ)) ||
- xy_alt[2*end]>(xhigh*(1.0+NUM_FUZZ))) break;
- end = over_alt[++i_over];
- }
- }
- while ( (end-start) <= 0 && start<npts );
-
- if (start >= npts) continue;
-
- if (start > 0)
- {
- memcpy(start_save,&(xy_alt[2*(start-1)]),2*sizeof(float) );
- s_saved = 1;
- box_cross( &xy_alt[2*(start-1)], &xy_alt[2*start], disp);
- start--;
- }
- if (end < npts)
- {
- memcpy(end_save,&(xy_alt[2*end]),2*sizeof(float) );
- e_saved = 1;
- box_cross( &xy_alt[2*end], &xy_alt[2*(end-1)], disp);
- end++;
- }
-
- PlotSwitch(plot_drvr,drawLine,
- (&(xy_alt[2*start]),end-start,ls));
-
- if (s_saved)
- memcpy(&(xy_alt[2*start]),start_save,2*sizeof(float) );
- if (e_saved)
- memcpy(&(xy_alt[2*(end-1)]),end_save,2*sizeof(float) );
-
-
- }
- while (rc == 0 && end < npts && start < npts);
-
- if (xmin_pt != 0)
- {
- free(xy_alt);
- free(over_alt);
- }
-
- return rc;
- }
-
- /*
- * integer comparison for qsort.
- */
- int intcmp(const void *i1, const void *i2)
- {
- if ((int *)i1 > (int *)i2)
- return 1;
- else if ((int *)i1 == (int *)i2)
- return 0;
- else
- return -1;
- }
-
- /*
- * find point where interpolation between p1 and p2 cross the
- * axes box.
- */
- static void box_cross( float *p1, float *p2, display disp )
- {
- float xlow,ylow, xhigh, yhigh;
- float x_int1,x_int2,y_int1,y_int2;
-
- if (disp->xAxis.flags.log)
- {
- xlow = log10(disp->xAxis.low);
- xhigh = log10(disp->xAxis.high);
- }
- else
- {
- xlow = disp->xAxis.low;
- xhigh = disp->xAxis.high;
- }
- if (disp->yAxis.flags.log)
- {
- ylow = log10(disp->yAxis.low);
- yhigh = log10(disp->yAxis.high);
- }
- else
- {
- ylow = disp->yAxis.low;
- yhigh = disp->yAxis.high;
- }
-
- x_int1 = p1[0] + (ylow-p1[1])*(p2[0]-p1[0])/(p2[1]-p1[1]);
- if (x_int1 >= xlow && x_int1 <= xhigh &&
- ylow >= p1[1] && ylow <= p2[1])
- {
- p1[0] = x_int1;
- p1[1] = ylow;
- return;
- }
-
- x_int2 = p1[0] + (yhigh-p1[1])*(p2[0]-p1[0])/(p2[1]-p1[1]);
- if (x_int2 >= xlow && x_int2 <= xhigh &&
- yhigh <= p1[1] && yhigh >= p2[1])
- {
- p1[0] = x_int2;
- p1[1] = yhigh;
- return;
- }
-
- y_int1 = p1[1] + (xlow-p1[0])*(p2[1]-p1[1])/(p2[0]-p1[0]);
- if (y_int1 >= ylow && y_int1 <= yhigh &&
- xlow >= p1[0] && xlow <= p2[0])
- {
- p1[0] = xlow;
- p1[1] = y_int1;
- return;
- }
-
- y_int2 = p1[1] + (xhigh-p1[0])*(p2[1]-p1[1])/(p2[0]-p1[0]);
- if (y_int2 >= ylow && y_int1 <= yhigh &&
- xhigh <= p1[0] && xhigh >= p2[0])
- {
- p1[0] = xhigh;
- p1[1] = y_int2;
- return;
- }
- }
-
-
- /*
- * draw errors - err_type specifies whether they are x or y errors.
- */
- static int drawError1D(display disp, float *xy, float *err,
- int *over, int npts, int err_type)
- {
- int rc = 0;
- int start = -1;
- int end;
- int i_over = 0;
-
- float xlow, ylow;
- float xhigh, yhigh;
-
- if (disp->xAxis.flags.log)
- {
- xhigh = log10(disp->xAxis.high);
- xlow = log10(disp->xAxis.low);
- }
- else
- {
- xhigh = disp->xAxis.high;
- xlow = disp->xAxis.low;
- }
- if (disp->yAxis.flags.log)
- {
- yhigh = log10(disp->yAxis.high);
- ylow = log10(disp->yAxis.low);
- }
- else
- {
- yhigh = disp->yAxis.high;
- ylow = disp->yAxis.low;
- }
-
- do
- {
- /*
- * Plot any x/y error bar where the y/x coordinate is in range
- * because of bars which reach into plot, even when point
- * is outside.
- */
- do
- {
- if (start == -1)
- start = 0;
- else
- start = over[i_over++]+1;
- end = over[i_over];
-
- while (end<npts)
- {
- if (err_type==XERROR)
- {
- /* include some fuzz in comparisons */
- if ( xy[2*end+1]<(ylow*(1.0-NUM_FUZZ)) ||
- xy[2*end+1]>(yhigh*(1.0+NUM_FUZZ))) break;
- if ( err[2*end]<(xlow*(1.0-NUM_FUZZ)) ||
- err[2*end+1]>(xhigh*(1.0+NUM_FUZZ))) break;
- if ( err[2*end] > xhigh)
- err[2*end] = xhigh;
- if ( err[2*end+1] < xlow)
- err[2*end+1] = xlow;
- }
- else
- {
- if ( xy[2*end]<(xlow*(1.0-NUM_FUZZ)) ||
- xy[2*end]>(xhigh*(1.0+NUM_FUZZ))) break;
- if ( err[2*end]<(ylow*(1.0-NUM_FUZZ)) ||
- err[2*end+1]>(yhigh*(1.0+NUM_FUZZ))) break;
- if ( err[2*end] > yhigh)
- err[2*end] = yhigh;
- if ( err[2*end+1] < ylow)
- err[2*end+1] = ylow;
- }
- end = over[++i_over];
- }
- }
- while ( (end-start) <= 0 && start<npts );
-
- if (start >= npts) continue;
-
- if (err_type == YERROR)
- {
- PlotSwitch(plot_drvr,drawYError,(&(xy[2*start]),
- &(err[2*start]),
- end-start));
- }
- else
- {
- PlotSwitch(plot_drvr,drawXError,(&(xy[2*start]),
- &(err[2*start]),
- end-start));
- }
- }
- while (rc == 0 && end < npts && start < npts);
-
- return rc;
- }
-
-
- static int drawColor2D(display disp)
- {
- int rc=0;
-
- if (!init_done)
- {
- initPlot( disp );
- init_done = 1;
- }
-
- rc = disp->drawtype & COLOR; /* use temporarily */
- switch (plot_drvr)
- {
- NeXTFunc(drawColor2D,(disp->bins.xAxis.nBins,
- disp->bins.yAxis.nBins,
- &disp->marginRect,
- disp->bins.data,
- disp->bins.binMin,
- disp->bins.binMax,
- rc));
-
- PSFunc(drawColor2D,(disp->bins.xAxis.nBins,
- disp->bins.yAxis.nBins,
- &disp->marginRect,
- disp->bins.data,
- disp->bins.binMin,
- disp->bins.binMax,
- rc));
-
- UPFunc(drawColor2D,(disp));
-
- XIVFunc(drawColor2D,(disp->bins.xAxis.nBins,
- disp->bins.yAxis.nBins,
- disp->bins.binMin,
- disp->bins.binMax,
- disp->bins.data));
-
- X11Func(drawColor2D,(disp->bins.xAxis.nBins,
- disp->bins.yAxis.nBins,
- disp->bins.binMin,
- disp->bins.binMax,
- disp->bins.data,
- rc));
-
- default:
- rc = -1;
- }
-
- return rc;
- }
-
-
- static int drawScatter2D(display disp)
- {
- int rc;
- int npts;
- float *xylist;
- struct maxs max;
-
- npts = getScatData( disp, &xylist, &max );
- if (npts == 0) return 0;
- if (npts < 0)
- {
- h_error("h_plot - error getting scatter plot data");
- return -1;
- }
-
- if (disp->xAxis.flags.autoScale)
- {
- disp->xAxis.low = max.xl;
- disp->xAxis.high = max.xh;
- h_adjustAxis(&(disp->xAxis.low),&(disp->xAxis.high),
- 0, disp->xAxis.flags.log);
- }
- if (disp->yAxis.flags.autoScale)
- {
- disp->yAxis.low = max.yl;
- disp->yAxis.high = max.yh;
- h_adjustAxis(&(disp->yAxis.low),&(disp->yAxis.high),
- 0, disp->yAxis.flags.log);
- }
-
- if (!init_done)
- {
- initPlot( disp );
- init_done = 1;
- }
-
- PlotSwitch(plot_drvr,drawPoints,(xylist,npts,disp->plotSymbol,
- disp->symbolSize));
-
- free( xylist );
- return rc;
- }
-
-
- static int getXYData( display disp, float **xy, float **xerr,
- float **yerr, int **over, struct maxs *m, int *xmin_pt)
- {
- int i;
- float *xp,*yp,*nt;
- float *last;
- float xlow, xhigh;
- float ylow, yhigh;
- float *xerrorp = NULL, *yerrorp = NULL;
- float *xerrp, *yerrp;
- float *xyp;
- int *overp, isover;
- int nt_dim = disp->ntuple->ndim;
- int ylog, xlog;
-
-
- if (disp->binding.x < 0 || disp->binding.y < 0 ||
- disp->binding.x >= disp->ntuple->ndim ||
- disp->binding.y >= disp->ntuple->ndim )
- return -1;
-
- m->xl = FLT_MAX;
- m->xh = -FLT_MAX;
- m->yl = FLT_MAX;
- m->yh = -FLT_MAX;
-
- ylog = disp->yAxis.flags.log;
- xlog = disp->xAxis.flags.log;
-
- if (disp->xAxis.flags.autoScale)
- {
- xlow = -FLT_MAX;
- xhigh = FLT_MAX;
- }
- else
- {
- xlow = disp->xAxis.low;
- xhigh = disp->xAxis.high;
- }
- if (disp->yAxis.flags.autoScale)
- {
- ylow = -FLT_MAX;
- yhigh = FLT_MAX;
- }
- else
- {
- ylow = disp->yAxis.low;
- yhigh = disp->yAxis.high;
- }
-
-
- memset((char *)disp->bins.totals, (char)0, sizeof(disp->bins.totals) );
-
- if ( (*xy = (float *)malloc( 2*disp->ntuple->ndata*sizeof(float)))
- == NULL )
- {
- h_error("h_plot has run out of memory.");
- return -1;
- }
- if ( disp->drawtype&ERRBAR && disp->binding.xerror >=0 )
- {
- if ((*xerr = (float *)malloc( 2*disp->ntuple->ndata*sizeof(float)))
- == NULL )
- {
- free(*xy);
- h_error("h_plot has run out of memory.");
- return -1;
- }
- }
- else *xerr = NULL;
-
- if ( disp->drawtype&ERRBAR && disp->binding.yerror >= 0 )
- {
- if ( (*yerr = (float *)malloc( 2*disp->ntuple->ndata*sizeof(float)))
- == NULL )
- {
- free(xy);
- free(xerr);
- h_error("h_plot has run out of memory.");
- return -1;
- }
- }
- else *yerr = NULL;
-
- if ( (*over = (int *)malloc( (disp->ntuple->ndata+1)*sizeof(int)))
- == NULL )
- {
- free(xy);
- free(xerr);
- free(yerr);
- h_error("h_plot has run out of memory.");
- return -1;
- }
-
- last = &( disp->ntuple->data[INDEX(disp->ntuple->ndata,
- 0,
- disp->ntuple->ndim)] );
- xp = &(disp->ntuple->data[INDEX(0,disp->binding.x,disp->ntuple->ndim)]);
- yp = &(disp->ntuple->data[INDEX(0,disp->binding.y,disp->ntuple->ndim)]);
- if (disp->binding.xerror >=0 )
- xerrorp = &(disp->ntuple->data[INDEX(0,disp->binding.xerror,
- disp->ntuple->ndim)]);
- if (disp->binding.yerror >=0 )
- yerrorp = &(disp->ntuple->data[INDEX(0,disp->binding.yerror,
- disp->ntuple->ndim)]);
-
- nt = &(disp->ntuple->data[INDEX(0,0,disp->ntuple->ndim)]);
-
- i = 0;
- xerrp = *xerr;
- yerrp = *yerr;
- xyp = *xy;
- overp = *over;
-
- for ( ; xp<last;
- xp += nt_dim, yp += nt_dim, nt += nt_dim,
- xerrorp += nt_dim, yerrorp += nt_dim )
- {
- if (disp->nt_cut!=NULL && doCuts(nt, disp->nt_cut)) continue;
-
- isover = 0;
-
- if (*xp > xhigh)
- {
- if (*yp > yhigh)
- disp->bins.totals[2][2] += 1.0;
- else if (*yp < ylow)
- disp->bins.totals[2][0] += 1.0;
- else
- disp->bins.totals[2][1] += 1.0;
- }
- else if (*xp < xlow)
- {
- if (*yp > yhigh)
- disp->bins.totals[0][2] += 1.0;
- else if (*yp < ylow)
- disp->bins.totals[0][0] += 1.0;
- else
- disp->bins.totals[0][1] += 1.0;
- }
- else
- {
- if (*yp > yhigh)
- disp->bins.totals[1][2] += 1.0;
- else if (*yp < ylow)
- disp->bins.totals[1][0] += 1.0;
- else
- disp->bins.totals[1][1] += 1.0;
- }
-
- if (!xlog)
- *xyp++ = *xp;
- else
- {
- if (*xp > 0.0)
- *xyp++ = log10(*xp);
- else
- {
- isover = 1;
- *xyp++ = -FLT_MAX;
- }
- }
- if (*xp > xhigh || *xp < xlow) isover = 1;
-
- if (!ylog)
- *xyp++ = *yp;
- else
- {
- if (*yp > 0.0)
- *xyp++ = log10(*yp);
- else
- {
- isover = 1;
- *xyp++ = -FLT_MAX;
- }
- }
- if (*yp > yhigh || *yp < ylow ) isover = 1;
-
- if (! isover)
- {
- if (*xp > m->xh) m->xh = *xp;
- if (*xp < m->xl)
- {
- m->xl = *xp;
- *xmin_pt = i;
- }
-
- if (*yp > m->yh) m->yh = *yp;
- if (*yp < m->yl) m->yl = *yp;
- }
-
-
- if (xerrp != NULL)
- {
- *xerrp = *xp + *xerrorp;
- if (!isover && *xerrp > m->xh) m->xh = *xerrp;
- if (xlog)
- {
- if (*xerrp > 0.0)
- *xerrp = log10(*xerrp);
- else
- {
- *xerrp = -FLT_MAX;
- isover = 1;
- }
- }
- if (*xerrp > xhigh || *xerrp < xlow) isover = 1;
- xerrp++;
-
- *xerrp = *xp - *xerrorp;
- if (!isover && *xerrp < m->xl &&
- (!xlog || (xlog && *xerrp>0.0)) ) m->xl = *xerrp;
- if (xlog)
- {
- if (*xerrp > 0.0)
- *xerrp = log10(*xerrp);
- else
- {
- *xerrp = -FLT_MAX;
- isover = 1;
- }
- }
- if (*xerrp > xhigh || *xerrp < xlow) isover = 1;
- xerrp++;
- }
- if (yerrp != NULL)
- {
- *yerrp = *yp + *yerrorp;
- if (!isover && *yerrp > m->yh) m->yh = *yerrp;
- if (ylog)
- {
- if (*yerrp > 0.0)
- *yerrp = log10(*yerrp);
- else
- {
- *yerrp = -FLT_MAX;
- isover = 1;
- }
- }
- if (*yerrp > yhigh || *yerrp < ylow ) isover = 1;
- yerrp++;
-
- *yerrp = *yp - *yerrorp;
- if (!isover && *yerrp < m->yl &&
- (!ylog || (ylog && *yerrp > 0.0)) )
- m->yl = *yerrp;
- if (ylog)
- {
- if (*yerrp > 0.0)
- *yerrp = log10(*yerrp);
- else
- {
- *yerrp = -FLT_MAX;
- isover = 1;
- }
- }
- if (*yerrp > yhigh || *yerrp < ylow ) isover = 1;
- yerrp++;
- }
-
- if (isover)
- {
- *overp++ = i;
- isover = 1;
- }
-
- i++;
- }
-
- /* indicate last item in over */
- *overp = i;
-
- return i;
- }
-
- static int getHistoData( display disp, float **xy, float **xylego,
- float **xerr, float **yerr, int **over,
- struct maxs *m)
- {
- int i;
- float binwidth, binside;
- float *yp;
- float *last;
- float *xyp;
- int *overp;
- float xlow,xhigh;
- float ylow, yhigh;
- float *yerrorp, *xerrp, *yerrp;
- float *xylegop;
- float def_bin;
- int ylog, isover;
-
- if (disp->bins.data == NULL) return -1;
-
- ylog = disp->yAxis.flags.log;
-
- if (disp->xAxis.flags.autoScale)
- {
- xlow = -FLT_MAX;
- xhigh = FLT_MAX;
- }
- else
- {
- xlow = disp->xAxis.low;
- xhigh = disp->xAxis.high;
- }
- if (disp->yAxis.flags.autoScale)
- {
- ylow = -FLT_MAX;
- yhigh = FLT_MAX;
- }
- else
- {
- ylow = disp->yAxis.low;
- yhigh = disp->yAxis.high;
- }
-
- m->xl = FLT_MAX;
- m->xh = -FLT_MAX;
- m->yl = FLT_MAX;
- m->yh = -FLT_MAX;
-
- if ( (*xy = (float *)malloc( 2*disp->bins.xAxis.nBins*sizeof(float)))
- == NULL )
- {
- h_error("h_plot has run out of memory.");
- return -1;
- }
- if ( (*xylego = (float *)malloc( 4*(disp->bins.xAxis.nBins+2)*sizeof(float)))
- == NULL )
- {
- free(*xy);
- h_error("h_plot has run out of memory.");
- return -1;
- }
- if ( disp->drawtype&ERRBAR )
- {
- if ( (*xerr = (float *)malloc( 2*disp->bins.xAxis.nBins*sizeof(float)))
- == NULL )
- {
- free(*xy);
- free(*xylego);
- h_error("h_plot has run out of memory.");
- return -1;
- }
- }
- else *xerr = NULL;
-
- if ( disp->drawtype&ERRBAR )
- {
- if ( (*yerr = (float *)malloc( 2*disp->bins.xAxis.nBins*sizeof(float)))
- == NULL )
- {
- free(*xy);
- free(*xylego);
- free(*xerr);
- h_error("h_plot has run out of memory.");
- return -1;
- }
- }
- else *yerr = NULL;
-
- if ( (*over = (int *)malloc( (disp->bins.xAxis.nBins+1)*sizeof(int)))
- == NULL )
- {
- free(*xy);
- free(*xylego);
- free(*xerr);
- free(*yerr);
- h_error("h_plot has run out of memory.");
- return -1;
- }
-
- last = &( disp->bins.data[disp->bins.xAxis.nBins] );
- yp = disp->bins.data;
- yerrorp = disp->bins.variance;
-
- i = 0;
- xerrp = *xerr;
- yerrp = *yerr;
- xyp = *xy;
- xylegop = *xylego;
- overp = *over;
- binside = disp->xAxis.low;
- binwidth = (disp->xAxis.high - disp->xAxis.low)/disp->bins.xAxis.nBins;
-
- /*
- * connect the bins to the walls of the plot.
- * this is only useful if we allow plot axis to be bigger
- * than the bin limits.
- */
- if (disp->yAxis.low > 0.0) def_bin = disp->yAxis.low;
- else def_bin = 0.0;
- if (ylog)
- if (def_bin > 0.0)
- def_bin = log10(def_bin);
- else
- def_bin = -FLT_MAX;
-
- *xylegop++ = disp->xAxis.low;
- *xylegop++ = def_bin;
- *xylegop++ = binside;
- *xylegop++ = def_bin;
-
- for ( ; yp<last; yp++, yerrorp++ )
- {
- isover = 0;
-
- *xyp++ = binside + binwidth/2.0;
-
- if (!ylog)
- *xyp++ = *yp;
- else
- {
- if (*yp > 0.0)
- *xyp++ = log10(*yp);
- else
- {
- isover = 1;
- *xyp++ = -FLT_MAX;
- }
- }
- if (*yp > yhigh || *yp < ylow) isover = 1;
-
- if (!isover)
- {
- if (*yp > m->yh) m->yh = *yp;
- if (*yp < m->yl && (!ylog || (ylog && *yp>0.0)) )
- m->yl = *yp;
- }
-
-
- *xylegop++ = binside;
- if (xerrp != NULL) *xerrp++ = binside;
- *xylegop = *yp;
- if (ylog)
- {
- if (*xylegop > 0.0)
- *xylegop = log10(*xylegop);
- else
- *xylegop = -FLT_MAX;
- }
- xylegop++;
-
- binside += binwidth;
- *xylegop++ = binside;
- *xylegop = *(xylegop-2);
- xylegop++;
-
- if (xerrp != NULL) *xerrp++ = binside;
-
- if (yerrp != NULL)
- {
- *yerrp = *yp + sqrt(*yerrorp);
- if (!isover && *yerrp > m->yh) m->yh = *yerrp;
- if (ylog)
- {
- if (*yerrp > 0.0)
- *yerrp = log10(*yerrp);
- else
- {
- *yerrp = -FLT_MAX;
- isover = 1;
- }
- }
- if (*yerrp > yhigh || *yerrp < ylow) isover = 1;
- yerrp++;
-
- *yerrp = *yp - sqrt(*yerrorp);
- if (!isover && *yerrp < m->yl &&
- !( ylog && *yerrp<=0.0))
- m->yl = *yerrp;
- if (ylog)
- {
- if (*yerrp > 0.0)
- *yerrp = log10(*yerrp);
- else
- {
- *yerrp = -FLT_MAX;
- isover = 1;
- }
- }
- if (*yerrp > yhigh || *yerrp < ylow) isover = 1;
- yerrp++;
- }
-
- if (isover)
- {
- isover = 1;
- *overp++ = i;
- }
-
- i++;
- }
-
- /* connect to the walls */
- *xylegop++ = binside;
- *xylegop++ = def_bin;
- *xylegop++ = disp->xAxis.high;
- *xylegop++ = def_bin;
-
- /* indicate last item in over. */
- *overp = i;
-
- return i;
- }
-
-
- static int getScatData( display disp, float **xy, struct maxs *m )
- {
- int i = 0;
- float *xp,*yp,*nt;
- float *last;
- float *xyp;
- int nt_dim = disp->ntuple->ndim;
- float xlow, xhigh;
- float ylow, yhigh;
- int xlog, ylog;
-
-
- if (disp->binding.x < 0 || disp->binding.y < 0 ||
- disp->binding.x >= disp->ntuple->ndim ||
- disp->binding.y >= disp->ntuple->ndim )
- return -1;
-
- xlog = disp->xAxis.flags.log;
- ylog = disp->yAxis.flags.log;
-
- m->xl = FLT_MAX;
- m->xh = -FLT_MAX;
- m->yl = FLT_MAX;
- m->yh = -FLT_MAX;
-
- if (disp->xAxis.flags.autoScale)
- {
- xlow = -FLT_MAX;
- xhigh = FLT_MAX;
- }
- else
- {
- xlow = disp->xAxis.low;
- xhigh = disp->xAxis.high;
- }
- if (disp->yAxis.flags.autoScale)
- {
- ylow = -FLT_MAX;
- yhigh = FLT_MAX;
- }
- else
- {
- ylow = disp->yAxis.low;
- yhigh = disp->yAxis.high;
- }
-
- if (xlog && xlow < FLT_MIN) xlow = FLT_MIN;
- if (ylog && ylow < FLT_MIN) ylow = FLT_MIN;
- if (xhigh <= xlow) xhigh = xlow + 1.0;
- if (yhigh <= ylow) yhigh = ylow + 1.0;
-
- if ( (*xy = (float *)malloc( 2*disp->ntuple->ndata*sizeof(float)))
- == NULL )
- {
- h_error("h_plot has run out of memory.");
- return -1;
- }
-
- memset((char *)disp->bins.totals, (char)0, sizeof(disp->bins.totals) );
-
- last = &( disp->ntuple->data[INDEX(disp->ntuple->ndata,0,
- disp->ntuple->ndim)] );
- xp = &(disp->ntuple->data[INDEX(0,disp->binding.x,disp->ntuple->ndim)]);
- yp = &(disp->ntuple->data[INDEX(0,disp->binding.y,disp->ntuple->ndim)]);
- nt = &(disp->ntuple->data[INDEX(0,0,disp->ntuple->ndim)]);
-
- i = 0;
- xyp = *xy;
-
- for ( ; xp<last;
- xp += nt_dim, yp += nt_dim, nt += nt_dim )
- {
- if (disp->nt_cut!=NULL && doCuts(nt, disp->nt_cut)) continue;
-
- if (*xp >= xhigh)
- {
- if (*yp > yhigh)
- disp->bins.totals[2][2] += 1.0;
- else if (*yp < ylow)
- disp->bins.totals[2][0] += 1.0;
- else
- disp->bins.totals[2][1] += 1.0;
- }
- else if (*xp < xlow)
- {
- if (*yp >= yhigh)
- disp->bins.totals[0][2] += 1.0;
- else if (*yp < ylow)
- disp->bins.totals[0][0] += 1.0;
- else
- disp->bins.totals[0][1] += 1.0;
- }
- else
- {
- if (*yp > yhigh)
- disp->bins.totals[1][2] += 1.0;
- else if (*yp < ylow)
- disp->bins.totals[1][0] += 1.0;
- else
- {
- disp->bins.totals[1][1] += 1.0;
-
- if (!xlog)
- *xyp++ = *xp;
- else
- *xyp++ = log10(*xp);
-
- if (!ylog)
- *xyp++ = *yp;
- else
- *xyp++ = log10(*yp);
-
- if (*xp > m->xh) m->xh = *xp;
- if (*xp < m->xl) m->xl = *xp;
-
- if (*yp > m->yh) m->yh = *yp;
- if (*yp < m->yl) m->yl = *yp;
-
- i++;
- }
- }
- }
-
- return i;
- }
-
-
- static int drawLego2D(display disp)
- {
- int rc;
-
- if (!init_done)
- {
- initPlot( disp );
- init_done = 1;
- }
-
- switch (plot_drvr)
- {
- NeXTFunc(drawLego2D,( &disp->marginRect ));
-
- PSFunc(drawLego2D,( &disp->marginRect ));
-
- UPFunc(drawLego2D,( disp ));
-
- XIVFunc(drawLego2D,(disp->bins.xAxis.nBins,
- disp->bins.yAxis.nBins,
- disp->bins.binMin,
- disp->bins.binMax,
- disp->bins.data));
-
- X11Func(drawLego2D,(disp->bins.xAxis.nBins,
- disp->bins.yAxis.nBins,
- disp->bins.binMin,
- disp->bins.binMax,
- disp->bins.data));
-
- MACFunc(drawLego2D,( &disp->marginRect ));
-
- default:
- rc = -1;
- }
-
- return rc;
- }
-
- int h_shade(display disp, float var1, float var2)
- /*
- * Shade an area of a plot to indicate area. Make sure not
- * to outside the bounds of the plot.
- */
- {
- int rc;
- float low, high;
-
- if (disp == NULL) return -1;
-
- low = (var1 - disp->xAxis.low)/(disp->xAxis.high - disp->xAxis.low);
- if (low < 0.0) low = 0.0;
- low = low * disp->marginRect.size.width + disp->marginRect.origin.x;
-
- high = (var2 - disp->xAxis.low)/(disp->xAxis.high - disp->xAxis.low);
- if (high > 1.0) high = 1.0;
- high = high * disp->marginRect.size.width + disp->marginRect.origin.x;
-
- switch (plot_drvr)
- {
- NeXTFunc(shade,(low,high,disp->marginRect.origin.y,
- disp->marginRect.origin.y+
- disp->marginRect.size.height));
-
- PSFunc(shade,(low,high,disp->marginRect.origin.y,
- disp->marginRect.origin.y+
- disp->marginRect.size.height));
-
- MACFunc(shade,(low,high,disp->marginRect.origin.y,
- disp->marginRect.origin.y+
- disp->marginRect.size.height));
-
- XIVFunc(shade,(low,high,disp->marginRect.origin.y,
- disp->marginRect.origin.y+
- disp->marginRect.size.height));
-
- X11Func(shade,(low,high,disp->marginRect.origin.y,
- disp->marginRect.origin.y+
- disp->marginRect.size.height));
-
- default:
- rc = -1;
- }
-
- return rc;
- }
-
-
- typedef struct fp
- {
- float x,f;
- struct fp *n;
- } fp;
-
- static fp *pCache(int n );
- typedef double (*pfun)( double, double *);
-
- static int plotFunc( display disp, func_id func )
- {
- int yClip = 0;
- int i, nCacheUsed;
- float ylow, yhigh;
- float maxKink;
- float delta1, minDelta;
- float delta2, kink;
- int isover;
-
- fp *list=NULL, *p=NULL, *t;
- int *over, *overp;
- float *xy, *xyp;
-
- #define NSEG_START 20
-
- if (disp == NULL || func == NULL) return 0;
- if (disp->xAxis.high <= disp->xAxis.low)
- {
- h_error("Plotfunc - xAxis.high <= xAxis.low");
- return 0;
- }
-
- /*
- * start from the beginning of the cache of point structures.
- */
- nCacheUsed = 0;
-
- maxKink = 5.0 * 3.141593/180.0;
- minDelta = 4.0 * (disp->xAxis.high - disp->xAxis.low) /
- disp->marginRect.size.width; /* a couple of pixels */
-
- if (init_done || !disp->yAxis.flags.autoScale) yClip = 1;
- ylow = FLT_MAX;
- yhigh = -FLT_MAX;
-
- delta1 = (disp->xAxis.high - disp->xAxis.low)/((float)NSEG_START);
- for (i=0; i<=NSEG_START; i++)
- {
- if (i==0)
- {
- list = pCache(nCacheUsed++);
- p = list;
- }
- else
- {
- p->n = pCache(nCacheUsed++);
- p = p->n;
- }
- p->x = disp->xAxis.low + ((float) i) * delta1;
- p->f = (*(pfun)(func->funcPtr))((double)p->x,
- (double *)func->paramBlk);
- p->n = NULL;
- }
-
- for (p=list; (p->n)->n != NULL; p = p->n )
- {
- kink = atan((((p->n)->n)->f - (p->n)->f)/
- (((p->n)->n)->x - (p->n)->x)) -
- atan(((p->n)->f - p->f)/((p->n)->x - p->x));
- delta2 = ((p->n)->n)->x - (p->n)->x;
- delta1 = (p->n)->x - p->x;
- while ( fabs(kink) > maxKink &&
- (delta1 > minDelta || delta2 > minDelta) )
- {
- if (delta1 <= delta2)
- {
- t = pCache(nCacheUsed++);
- t->x = (p->n)->x + delta2/2.0;
- t->f = (float)
- (*(pfun)(func->funcPtr))((double)t->x,
- (double *)func->paramBlk);
- t->n = (p->n)->n;
- (p->n)->n = t;
- }
- if (delta1 >= delta2)
- {
- t = pCache(nCacheUsed++);
- t->x = p->x + delta1/2.0;
- t->f = (float)
- (*(pfun)(func->funcPtr))((double)t->x,
- (double *)func->paramBlk);
- t->n = p->n;
- p->n = t;
- }
- kink = atan((((p->n)->n)->f - (p->n)->f)/
- (((p->n)->n)->x - (p->n)->x)) -
- atan(((p->n)->f - p->f)/((p->n)->x - p->x));
- delta2 = ((p->n)->n)->x - (p->n)->x;
- delta1 = (p->n)->x - p->x;
- }
- }
-
- /*
- * We now have the complete list of points to plot. Create the
- * list of x-y points and overflow flags.
- */
- xy = (float *) malloc( 2 * nCacheUsed * sizeof(float) );
- over = (int *) malloc( (nCacheUsed+1) * sizeof(int) );
- xyp = xy;
- overp = over;
-
- for (p=list, i=0; i<nCacheUsed; p = p->n, i++ )
- {
- isover = 0;
-
- if (disp->xAxis.flags.log)
- if (p->x > 0.0)
- *xyp++ = p->x;
- else
- {
- isover = 1;
- *xyp++ = -FLT_MAX;
- }
- else
- *xyp++ = p->x;
-
- if (disp->yAxis.flags.log)
- if (p->f > 0.0)
- *xyp++ = p->f;
- else
- {
- isover = 1;
- *xyp++ = -FLT_MAX;
- }
- else
- *xyp++ = p->f;
-
- if (isover ||
- (yClip && (p->f > disp->yAxis.high || p->f < disp->yAxis.low)))
- *overp++ = i;
- else
- {
- if (p->f > yhigh) yhigh = p->f;
- if (p->f < ylow && (!disp->yAxis.flags.log || p->f > 0.0))
- ylow = p->f;
- }
- }
- *overp++ = i;
-
- /*
- * Set scales if it has not been done already.
- */
- if (! init_done)
- {
- if (disp->yAxis.flags.autoScale)
- {
- disp->yAxis.low = ylow;
- disp->yAxis.high = yhigh;
- h_adjustAxis(&(disp->yAxis.low), &(disp->yAxis.high),
- 0, disp->yAxis.flags.log );
- }
- initPlot( disp );
- init_done = 1;
- }
-
- /*
- * plot the line, clean up and we're done!
- */
- drawLine1D( disp, xy, over, nCacheUsed, 0, func->lineStyle );
-
- free(xy);
- free(over);
-
- return 0;
- }
-
- static fp *pCache(int n )
- {
- static npoints = 0;
- #define FP_BLK 100
- static fp *list;
-
- if (npoints == 0)
- {
- if ( (list = (fp *)malloc( FP_BLK * sizeof(fp) )) == NULL)
- {
- h_error("Plotfunc is out of memory");
- return NULL;
- }
- npoints = FP_BLK;
- }
-
- if (n >= npoints)
- {
- if ( (list = (fp *)realloc( list,
- (npoints+FP_BLK) * sizeof(fp) )) == NULL)
- {
- h_error("Plotfunc is out of memory");
- return NULL;
- }
- npoints += FP_BLK;
- }
-
- return &list[n];
- }
-