C DRAW GRAPH FROM DIRECTIVE FILE C C David Villeneuve, March 1984. C Updated April 1985. C C--BUILD DRAW,$PFLIB C C This program reads a file of directive commands from the file C specified on the command line, and generates a graph from it. C Directives begin the line, and are optionally followed by C parameter value(s). C Plotting is begun when a PLOT or OVERPLOT command is read. C If these commands are followed by a filename, then that file C is read for the xy pairs of data points. If there is no C filename on the command line, it is assumed that the xy pairs C follow in the command file, and they will be read until an C END directive is read, then command processing resumes. C C *********************************************************** C C The following are parameter setting commands, and must be C given before the PLOT command. Their values stay in effect C until changed. C C * Setting scales: C If you do not specify any scales, the program will choose C a nice set of scales from the range of the data. C However you may want to override this mechanism, e.g. if C the x-axis is degrees from 0 to 180, you may want the axis C labelled at 0, 30, 60, 90, 120, 150, and 180, rather than C the default 0, 50, 100, 150, 200. You may use X-SCALE and C Y-SCALE to do this (or equivalently X-FIRST, X-LAST, X-INC, C etc.) C If you want part of the axis to be not labelled or for the C first tick mark to start at some arbitrary location from C the corner, then you can specify the values at the four C corners using X-SPAN and Y-SPAN (or equivalently X-LEFT etc.). C If these are not given then the corners correspond to the C values set by X-SCALE and Y-SCALE. C You can mix up defaults and overrides together; the program C tries to determine what you want. C C X-LEFT, X-RIGHT, Y-BOTTOM, Y-TOP set the range of the graph C in user's units. For log scales, these values are the log C base 10 of the values, e.g. 1E-5 is set as -5. C Default values are chosen from the range of the data, C or from the x-first x-last values below. C X-SPAN, Y-SPAN have two parameters, corresponding to C x-left, xright etc. above. Both must be given if this C command is used. This is an equivalent way to set the C range of the graph. C X-FIRST, X-LAST, Y-FIRST, Y-LAST, X-INC, Y-INC set the values C at which the major tick marks and numbers are written on C the axes. For log scales, these are the log base 10 of the C value, and the increments must be set to 1. C Default values are chosen from the range of the data. C X-SCALE, Y-SCALE have three parameters, corresponding to C x-first, x-last, x-inc described in the previous paragraph. C This is an equivalent way of setting the scales, but all 3 C values must be given or will be set to zero. C X-LINEAR, X-LOG, Y-LINEAR, Y-LOG set the axes as either C linear or logarithmic. Default is linear. C LEFT-EDGE, RIGHT-EDGE, BOTTOM-EDGE, TOP-EDGE set the location C of the corners of the graph frame on the plotting page. C These are in inches on a 12 by 10 inch page. You must also C leave room below and to the left for axis labels. C Default is 2, 10, 2, 8.75 inches. C TICKS / NO-TICKS controls the minor tick marks. Default is ticks. C GRID-LINES / NO-GRID-LINES controls the drawing of grid lines C right across the plot. Default is no, just larger ticks. C NO-X-AXIS, NO-Y-AXIS, X-AXIS, Y-AXIS disable the drawing C of both tick marks and scales on the axes, for example C when using arbitrary units. C COMMENT is used to denote a comment line and is ignored. C RESET will reset the scales and attributes back to their default C values. It does not affect character height or pen choices. C LINE-TYPE specifies the type of line that is to be drawn between C data points. It takes three parameters: the line type code (1-9, C see writeup for GRTHKL), the line thickness in inches, and the C pen number to use. The defaults are 1 (solid line), 0.08, 1. C SYMBOL says that symbols are to be drawn at every data point, C and selects the symbol to be used. See writeup for GRSYM subroutine. C Parameter is in the range -65 to -72. (SYMBOL-PEN sets colour). C The default is to draw a line between points (see LINE-TYPE), C but the default for symbol's parameter is -66. C SPLINE says that the next PLOT or OVERPLOT is to be fitted with C a smooth curve which is generated by fitting piecewise cubic splines C to the data points. This works best with a small number of data C points since the curve passes through every point. The two parameters C give the left and right x-values between which to draw the curve. C If not given, the curve will be drawn between the first and last points. C The x values of the curve must be increasing from left to right. C This option is active for the next (over)plot only, then resets. C DECIMALS-X, DECIMALS-Y specify the number of decimal digits to follow C the decimal place in numbers which label the axes. 0 gives whole C numbers, positive gives F format, negative gives E format. This only C affects the formatting of the numbers, not the choice of which numbers C to use. Defaults are chosen from the range of the scales. C DATE / NO-DATE controls printing date in lower right corner. C Default is no date. C MAIN-TITLE, X-TITLE, Y-TITLE will print the rest of C the line at the corresponding position on the graph. C PUBLICATION sets a number of parameters suitable for graphs C in publications. The characters are such that they will C reduce to 2 mm in a 3.125 inch column. C The pen for the main title is 2, so it may be used for C notations when doing drafts; for the final copy, remove C pen 2 from the plotter. C VIEWGRAPH sets a number of parameters suitable for making C viewgraphs. C X-FACTOR, Y-FACTOR give the scaling factors to transform the C data points. These commands take two parameters, A and B, C and the corresponding coordinate is transformed according to C X' = AX + B. This stays in effect until a RESET or another C X-FACTOR command. The default transformation is 1, 0. C MAIN-TITLE-HEIGHT, AXIS-TITLE-HEIGHT, DATE-HEIGHT, NOTE-HEIGHT, C set the height in inches of the characters of these labels. C Default 0.22, 0.22, 0.1, 0.22 inches. C NUMERAL-HEIGHT sets the height of the numbers which label C the axis values. Default is 0.2 inches. C SYMBOL-HEIGHT sets the size of the plotting symbols. C Default is 0.22 inches. C MAJOR-TICK-LENGTH, MINOR-TICK-LENGTH sets the length of C the ticks around the graph. Defaults are 0.25, 0.1 inches. C FRAME-THICKNESS sets the width of the frame, which is drawn C with three passes of the pen, each separated by this distance. C Default is 0.012 inches. C MAIN-TITLE-PEN, AXIS-TITLE-PEN, NUMERAL-PEN, DATE-PEN, C SYMBOL-PEN, MAJOR-TICK-PEN, MINOR-TICK-PEN, FRAME-PEN, NOTE-PEN, C select the pen colours for the corresponding parts of the C graph. Values are in range 1-4 for HP plotter. Default 1. C NOTE-ANGLE is the angle of the notes in degrees counterclockwise C from the x axis. Default 0. C C *************************************************************** C C The following commands generate the graph, so all parameter C setting commands should have been given. However parameters C may be changed before OVERPLOTS to change scales and plot C characters, etc. C C PLOT filename will cause the named file to be read for xy pairs, C then the graph is plotted using the parameters set up to that C point. If filename is not given, the points are read from the C following lines up to an END directive. C OVERPLOT filename is the same as PLOT, except that the curve C is plotted on top of the existing one. No axes or labels are C drawn. C C ***************************************************************** C C These commands should come after the PLOT command, C and may come before or after OVERPLOTs. C C NOTE x,y text and NOTE-UU x,y text C will plot the text onto the graph. X and y are the coordinates C for the lower left point of the text; for NOTE the coordinates C are in inches, for NOTE-UU they are in the current user units. C These must be used AFTER the PLOT command since scales are not C set until the first PLOT. C NOTE-CENTER, NOTE-RIGHT will center or right-justify the next C note only, then NOTE will revert to left-justifying the text. C C************************************************************************ C C The command line may also contain, in addition to the name of C the input directive file, the name of the plot file to create; C if not given it will be asked for. C In addition there may be up to 9 additional parameters which C will be substituted into each directive line where indicated C by the characters %n%, where n=1-9. For example each occurrence C of %1% on any directive line will be replaced by the value of C the parameter on the command line following the plot filename. C The parameters may be separated by spaces or commas. C The command line should be of the form: C C DRAW directive_filename plot_filename P1 P2 ... P9 C C where P1 to P9 are optional. If the directive_filename does not C have an extension, .FIG is assumed. C .PAGE COMMON /DRAWCM/ SPLINE_LEFT, SPLINE_RIGHT, IDATE, IXAXIS, IYAXIS, 1 X0, X1, Y0, Y1, DX, DY, XL, XR, YB, YT, 2 X0S, X1S, Y0S, Y1S, XLS, XRS, YBS, YTS, 3 LINE_THICKNESS, LINE_TYPE, LINE_PEN, PNULL, NULL, 4 XFACTOR(2), YFACTOR(2), NDECXS, NDECYS REAL LINE_THICKNESS LOGICAL NEWPLOT, USE_SPLINE, USE_SYMBOL BYTE MTITLE(80), XTITLE(80), YTITLE(80) INTEGER IARG(40), COMPAR BYTE LINE(132), KEYWD(82), CMDLIN(132) REAL P(5) C C THE FOLLOWING COMMON STATEMENT MUST BE IDENTICAL TO THAT USED C IN THE GRAF SUBROUTINES. DITTO THE DATA STATEMENTS. C COMMON /GRAFCX/ XPLOTL, XPLOTR, YPLOTB, YPLOTT, DXSAVE, DYSAVE, 1 XLSAVE, XRSAVE, YBSAVE, YTSAVE, NUSCAL, NOGRID, NSYMBO, 2 NOHASH, NOTICK, LOGARX, LOGARY, XSCALE, YSCALE, XLMOST, 3 NOSIZE, IPEN(10), HITE(10) DATA NOHASH /1/, NOTICK /1/, NSYMBO /1/ C C PEN COLOURS AND HEIGHTS DEFAULTS HERE C C M-ttl S-ttl nums syms date maj-tk min-tk frame curve solid DATA IPEN / 1 1, 1, 1, 1, 1, 1, 1, 1, 1, 0/ DATA HITE / 1 0.22, 0.22, 0.16, 0.22, 0.1, 0.25, 0.1, 0.012, 0.0, 0.01/ C C RETRIEVE COMMAND LINE, GET NAME OF COMMAND FILE C CALL PARSCL (CMDLIN, IARG, NARG) IFF (NARG .LE. 0 .OR. LENGTH(CMDLIN(IARG(1))) .LE. 0) THEN { WRITE (5,%%) FORMAT (' Name of command directive file not given.') CALL EXIT } CALL STRING (KEYWD, CMDLIN(IARG(1))) CALL INDEXC (IDOT, '.', KEYWD) IF (IDOT .LE. 0) CALL CONCAT (KEYWD, '.FIG') !ADD DEFAULT EXTENSION OPEN (UNIT=2, NAME=KEYWD, TYPE='OLD', READONLY) IF (NARG .GE. 2) CALL PLOTNM (CMDLIN(IARG(2)), 0) !specify plotfile name C C DEFINE PLOTTING LIMITS IN INCHES C 50 XPLOTL = 2.00 XPLOTR = 10.0 YPLOTB = 2.00 YPLOTT = 8.75 C C SET OTHER DEFAULTS C PNULL = 1.23E-35 !NULL VALUE NOT LIKELY TO BE CHOSEN NULL = -12345 HITEN = HITE(1) !HEIGHT FOR NOTES IPENN = IPEN(1) !PEN FOR NOTES INOTEJ = -1 !LEFT-JUSTIFY NOTES LOGARX = 0 LOGARY = 0 NOHASH = 1 NOTICK = 1 NSYMBO = 1 IXAXIS = 1 IYAXIS = 1 NDECXS = NULL NDECYS = NULL X0 = PNULL !DUMMY VALUE X1 = PNULL DX = PNULL Y0 = PNULL Y1 = PNULL DY = PNULL XL = PNULL XR = PNULL YB = PNULL YT = PNULL X0S = PNULL X1S = PNULL Y0S = PNULL Y1S = PNULL USE_SPLINE = .FALSE. USE_SYMBOL = .FALSE. LINE_TYPE = 1 LINE_THICKNESS = 0.08 LINE_PEN = 1 XFACTOR(1) = 1.0 XFACTOR(2) = 0.0 YFACTOR(1) = 1.0 YFACTOR(2) = 0.0 C C MAIN LOOP FOR READING EACH COMMAND LINE C REPEAT { C C READ LINE, IGNORE EMPTY LINES, AND UPPERCASE C 100 READ (2,%%,END=1000) LLINE, (LINE(K), K=1,LLINE) FORMAT (Q, 132A1) IF (LLINE .LE. 0) GO TO 100 LINE(LLINE+1) = 0 !MAKE ASCIZ CALL SUBS (LINE, LLINE, CMDLIN, IARG, NARG) !SUBSTITUTE FOR %n% K = 1 CALL SKIPSP (LINE, K) !SKIP LEADING BLANKS IF (K .GT. LLINE) GO TO 100 !BLANK LINE C C ISOLATE COMMAND KEYWORD BY LOOKING FOR FOLLOWING BLANK C FOR J=K,LLINE IF (LINE(J) .EQ. ' ' .OR. LINE(J) .EQ. "11) GO TO 150 J = LLINE+1 !NOTHING FOLLOWING WORD 150 CALL SUBSTR (KEYWD, LINE, K, J-K) !COPY KEYWORD TO KEYWD IF (J .LE. LLINE) CALL SKIPSP (LINE, J) CALL UPCASE (KEYWD) C C NOW LINE IS THE COMMAND LINE, WITH J POINTING TO NEXT NONBLANK C CHARACTER FOLLOWING KEYWORD. KEYWD IS THE KEYWORD. C NOW READ THE PARAMETER VALUE FOLLOWING THE KEYWORD. C LEN = LLINE-J+1 !LENGTH OF PARAMETER PART OF LINE NP = 0 !number of parameters given FOR K=1,5 P(K) = 0.0 !UNENTERED PARAMETERS ARE ZERO IF (LEN .GT. 0) CALL DECODE (LINE(J), P, 5, NP) .PAGE C C THIS SECTION CHECKS FOR EACH KEYWORD IN TURN, AND STORES THE PARAMETERS. C .DEFINE LC ELSEIF (COMPAR( I, KEYWD, .DEFINE RC ) .EQ. 0) IFF (COMPAR( I, KEYWD, 'END') .EQ. 0) THEN IF (0 .EQ. 0) GO TO 1000 !FOOL F77 ABOUT DEAD GOTO LC 'X-SCALE' RC THEN { X0 = P(1) X1 = P(2) DX = P(3) } LC 'Y-SCALE' RC THEN { Y0 = P(1) Y1 = P(2) DY = P(3) } LC 'X-SPAN' RC THEN { XL = P(1) XR = P(2) } LC 'Y-SPAN' RC THEN { YB = P(1) YT = P(2) } LC 'X-FIRST' RC THEN X0 = P(1) LC 'X-LAST' RC THEN X1 = P(1) LC 'Y-FIRST' RC THEN Y0 = P(1) LC 'Y-LAST' RC THEN Y1 = P(1) LC 'X-INC' RC THEN DX = P(1) LC 'Y-INC' RC THEN DY = P(1) LC 'X-LEFT' RC THEN XL = P(1) LC 'X-RIGHT' RC THEN XR = P(1) LC 'Y-BOTTOM' RC THEN YB = P(1) LC 'Y-TOP' RC THEN YT = P(1) LC 'LEFT-EDGE' RC THEN XPLOTL = P(1) LC 'RIGHT-EDGE' RC THEN XPLOTR = P(1) LC 'BOTTOM-EDGE' RC THEN YPLOTB = P(1) LC 'TOP-EDGE' RC THEN YPLOTT = P(1) LC 'X-AXIS' RC THEN IXAXIS = 1 LC 'NO-X-AXIS' RC THEN IXAXIS = 0 LC 'Y-AXIS' RC THEN IYAXIS = 1 LC 'NO-Y-AXIS' RC THEN IYAXIS = 0 LC 'TICKS' RC THEN NOTICK = 0 LC 'NO-TICKS' RC THEN NOTICK = 1 LC 'GRID-LINES' RC THEN NOHASH = 0 LC 'NO-GRID-LINES' RC THEN NOHASH = 1 LC 'MAIN-TITLE-HEIGHT' RC THEN HITE(1) = P(1) LC 'AXIS-TITLE-HEIGHT' RC THEN HITE(2) = P(1) LC 'NUMERAL-HEIGHT' RC THEN HITE(3) = P(1) LC 'SYMBOL-HEIGHT' RC THEN HITE(4) = P(1) LC 'DATE-HEIGHT' RC THEN HITE(5) = P(1) LC 'MAJOR-TICK-LENGTH' RC THEN HITE(6) = P(1) LC 'MINOR-TICK-LENGTH' RC THEN HITE(7) = P(1) LC 'FRAME-THICKNESS' RC THEN HITE(8) = P(1) LC 'NOTE-HEIGHT' RC THEN HITEN = P(1) LC 'NOTE-PEN' RC THEN IPENN = P(1) LC 'NOTE-ANGLE' RC THEN ANGLEN = P(1) LC 'MAIN-TITLE-PEN' RC THEN IPEN(1) = P(1) LC 'AXIS-TITLE-PEN' RC THEN IPEN(2) = P(1) LC 'NUMERAL-PEN' RC THEN IPEN(3) = P(1) LC 'SYMBOL-PEN' RC THEN IPEN(4) = P(1) LC 'DATE-PEN' RC THEN IPEN(5) = P(1) LC 'MAJOR-TICK-PEN' RC THEN IPEN(6) = P(1) LC 'MINOR-TICK-PEN' RC THEN IPEN(7) = P(1) LC 'FRAME-PEN' RC THEN IPEN(8) = P(1) LC 'X-LOG' RC THEN LOGARX = 1 LC 'Y-LOG' RC THEN LOGARY = 1 LC 'X-LINEAR' RC THEN LOGARX = 0 LC 'Y-LINEAR' RC THEN LOGARY = 0 LC 'DATE' RC THEN IDATE = 1 LC 'NO-DATE' RC THEN IDATE = 0 LC 'COMMENT' RC THEN CONTINUE LC 'DECIMALS-X' RC THEN NDECXS = P(1) LC 'DECIMALS-Y' RC THEN NDECYS = P(1) LC 'RESET' RC THEN IF (0 .EQ. 0) GO TO 50 !F77 AGAIN LC 'LINE-TYPE' RC THEN { USE_SYMBOL = .FALSE. IF (NP .GE. 1) LINE_TYPE = P(1) IF (NP .GE. 2) LINE_THICKNESS = P(2) IF (NP .GE. 3) LINE_PEN = P(3) } LC 'SYMBOL' RC THEN { NSYMBO = P(1) IF (NP .LE. 0) NSYMBO = -66 USE_SYMBOL = .TRUE. } LC 'SPLINE' RC THEN { USE_SPLINE = .TRUE. SPLINE_LEFT = PNULL SPLINE_RIGHT = PNULL IF (NP .GE. 1) SPLINE_LEFT = P(1) IF (NP .GE. 2) SPLINE_RIGHT = P(2) } LC 'X-FACTOR' RC THEN { XFACTOR(1) = P(1) XFACTOR(2) = P(2) } LC 'Y-FACTOR' RC THEN { YFACTOR(1) = P(1) YFACTOR(2) = P(2) } LC 'PUBLICATION' RC THEN { IPEN(1) = 2 XPLOTL = 3.0 XPLOTR = 11.0 HITE(1) = 0.25 HITE(2) = 0.25 HITE(3) = 0.16 HITE(4) = 0.25 } LC 'VIEWGRAPH' RC THEN { IPEN(1) = 1 XPLOTL = 3.0 XPLOTR = 11.0 HITE(1) = 0.22 HITE(2) = 0.22 HITE(3) = 0.16 HITE(4) = 0.22 } LC 'MAIN-TITLE' RC THEN CALL STRING (MTITLE, LINE(J)) LC 'X-TITLE' RC THEN CALL STRING (XTITLE, LINE(J)) LC 'Y-TITLE' RC THEN CALL STRING (YTITLE, LINE(J)) LC 'NOTE-CENTER' RC THEN INOTEJ = 0 LC 'NOTE-RIGHT' RC THEN INOTEJ = 1 LC 'NOTE') .EQ. 0 1 .OR. COMPAR(I, KEYWD, 'NOTE-UU' RC THEN { XP = FPCONV( LINE, LLINE, J, NEXT) YP = FPCONV( LINE, LLINE, NEXT+1, NEXT1) IFF (COMPAR(I, KEYWD, 'NOTE-UU') .EQ. 0) THEN { XP = (XP-XLS)*XSCALE + XPLOTL !CONVERT TO USER UNITS YP = (YP-YBS)*YSCALE + YPLOTB } CALL NEWPEN (IPENN) CALL SYMBOC (XP, YP, HITEN, LINE(NEXT1), ANGLEN, 80, INOTEJ) INOTEJ = -1 !REVERT TO LEFT-JUSTIFYING NOTES CALL PLOTF } ELSEIF (COMPAR(I, KEYWD, 'PLOT') .EQ. 0 1 .OR. COMPAR(I, KEYWD, 'OVERPLOT') .EQ. 0) THEN { C C PLOT COMMAND - OPEN DATA POINT FILE C NEWPLOT = .FALSE. IF (COMPAR(I, KEYWD, 'PLOT') .EQ. 0) NEWPLOT = .TRUE. IFF (LEN .GT. 0) THEN { LUN = 3 OPEN (UNIT=3, NAME=LINE(J), TYPE='OLD', READONLY) } ELSE LUN = 2 !USE COMMAND FILE C C DRAW THE GRAPH C CALL DRAW (LUN, NEWPLOT, USE_SPLINE, USE_SYMBOL, 1 MTITLE, XTITLE, YTITLE) } !END IFF ('PLOT' OR 'OVERPLOT') C C CATCH ALL C ELSE { WRITE (5,%%) (KEYWD(K), K=1,LENGTH(KEYWD)) FORMAT (' Unrecognized directive: ', 80A1) } } !END REPEAT C C END OF INPUT FILE C 1000 CALL EXIT END SUBROUTINE DRAW (LUN, NEWPLOT, USE_SPLINE, USE_SYMBOL, 1 MTITLE, XTITLE, YTITLE) C C THIS ROUTINE READS FROM THE FILE OPEN ON THE X-Y POINTS C THAT ARE TO BE PLOTTED. IF IS TRUE A NEW PLOT PAGE C IS GENERATED, OTHERWISE IT IS ASSUMED THAT THE DATA ARE TO BE C PLOTTED ON TOP OF AN EXISTING GRAPH. C COMMON /DRAWCM/ SPLINE_LEFT, SPLINE_RIGHT, IDATE, IXAXIS, IYAXIS, 1 X0, X1, Y0, Y1, DX, DY, XL, XR, YB, YT, 2 X0S, X1S, Y0S, Y1S, XLS, XRS, YBS, YTS, 3 LINE_THICKNESS, LINE_TYPE, LINE_PEN, PNULL, NULL, 4 XFACTOR(2), YFACTOR(2), NDECXS, NDECYS REAL LINE_THICKNESS LOGICAL NEWPLOT, USE_SPLINE, USE_SYMBOL BYTE MTITLE(80), XTITLE(80), YTITLE(80) REAL P(5) BYTE LINE(82), KEYWD(10) C C STORAGE FOR X-Y POINTS. C XPOINT AND YPOINT ARE USED TO REMEMBER THE LOCATIONS OF ALL THE SYMBOLS C WHICH HAVE BEEN PLOTTED ON THE CURRENT GRAPH, SO THAT WHEN LINES ARE DRAWN C THE LINES WILL AVOID THE SYMBOLS. C .DEFINE NXY 200 !MAX NUMBER OF DATA POINTS IN A SINGLE CURVE .DEFINE NSPLINES 100 !NUMBER OF SPLINE POINTS .DEFINE NSPLINE_WORK 200 !WORK ARRAY FOR SPLINES, 3 TIMES # PTS TO FIT .DEFINE NPOINTMAX 300 !MAX NUMBER OF SYMBOL POINTS TO REMEMBER TO AVOID REAL X(NXY), Y(NXY) REAL XSPLINE(NSPLINES), YSPLINE(NSPLINES) REAL XPOINT(NPOINTMAX), YPOINT(NPOINTMAX) REAL SPLINE_WORK(NSPLINE_WORK) REAL XX(2), YY(2) C C THE FOLLOWING COMMON STATEMENT MUST BE IDENTICAL TO THAT USED C IN THE GRAF SUBROUTINES. DITTO THE DATA STATEMENTS. C COMMON /GRAFCX/ XPLOTL, XPLOTR, YPLOTB, YPLOTT, DXSAVE, DYSAVE, 1 XLSAVE, XRSAVE, YBSAVE, YTSAVE, NUSCAL, NOGRID, NSYMBO, 2 NOHASH, NOTICK, LOGARX, LOGARY, XSCALE, YSCALE, XLMOST, 3 NOSIZE, IPEN(10), HITE(10) C C READ POINTS UNTIL END OF FILE OR END DIRECTIVE C FOR NPTS=1,NXY { READ (LUN, %%, ERR=200, END=200) LLINE, LINE FORMAT (Q, 82A1) LINE(LLINE+1) = 0 CALL SUBSTR (KEYWD, LINE, 1, 3) CALL UPCASE (KEYWD) IF (COMPAR(I, KEYWD, 'END') .EQ. 0) GO TO 200 CALL DECODE (LINE, P, 2, NP) X(NPTS) = P(1)*XFACTOR(1) + XFACTOR(2) Y(NPTS) = P(2)*YFACTOR(1) + YFACTOR(2) } WRITE (5,%%) NXY FORMAT (' Number of data points exceeds maximum of', I4) CALL EXIT C C END OF FILE OR END DIRECTIVE READ C 200 NPTS = NPTS-1 !IGNORE END DIRECTIVE IF (LUN .EQ. 3) CLOSE (UNIT=LUN) C C FOR SPLINES, FIT SPLINES TO CURVE, THEN COPY BACK INTO X AND Y C IFF (USE_SPLINE) THEN { XMIN = SPLINE_LEFT XMAX = SPLINE_RIGHT IF (SPLINE_LEFT .EQ. PNULL) XMIN = X(1) IF (SPLINE_RIGHT .EQ. PNULL) XMAX = X(NPTS) CALL GRSPLI (XSPLINE, YSPLINE, NSPLINES, 1 XMIN, XMAX, X, Y, NPTS, SPLINE_WORK) FOR J=1,NSPLINES { X(J) = XSPLINE(J) Y(J) = YSPLINE(J) } NPTS = NSPLINES USE_SPLINE = .FALSE. !SPLINE ONE SET OF DATA ONLY } C C BEGIN DRAWING GRAPH - SEE GRAF1 AND GRAF2. C FOR NEW PLOT ONLY, CALCULATE DEFAULT SCALE. C IFF (NEWPLOT) THEN { CALL PLOTS !NEW PAGE CALL GRSCAL (X, Y, NPTS, 1 XLS, XRS, DXS, YBS, YTS, DYS, NDECX, NDECY) NPOINTS = 0 !FORGET ALL OLD DATA POINTS } C C SUBSTITUTE SCALE VALUES GIVEN BY USER. C THE GRAPH LIMITS ARE XLS, XRS, YBS, YTS. C THE MAJOR TICKS AND NUMBERS ARE FROM X0S TO X1S BY DXS C AND FROM Y0S TO Y1S BY DYS. C IF (X0 .NE. PNULL) X0S = X0 IF (X1 .NE. PNULL) X1S = X1 IF (Y0 .NE. PNULL) Y0S = Y0 IF (Y1 .NE. PNULL) Y1S = Y1 IF (DX .NE. PNULL) DXS = DX IF (DY .NE. PNULL) DYS = DY IF (XL .NE. PNULL) XLS = XL IF (XR .NE. PNULL) XRS = XR IF (YB .NE. PNULL) YBS = YB IF (YT .NE. PNULL) YTS = YT IF (X0S .EQ. PNULL) X0S = XLS IF (X1S .EQ. PNULL) X1S = XRS IF (Y0S .EQ. PNULL) Y0S = YBS IF (Y1S .EQ. PNULL) Y1S = YTS IF (X0 .NE. PNULL .AND. XL .EQ. PNULL) XLS = X0 IF (X1 .NE. PNULL .AND. XR .EQ. PNULL) XRS = X1 IF (Y0 .NE. PNULL .AND. YB .EQ. PNULL) YBS = Y0 IF (Y1 .NE. PNULL .AND. YT .EQ. PNULL) YTS = Y1 C C COPY INTO COMMON THOSE REQUIRED BY SUBROUTINES C XLSAVE = XLS YBSAVE = YBS XSCALE = (XPLOTR-XPLOTL) / (XRS-XLS) YSCALE = (YPLOTT-YPLOTB) / (YTS-YBS) C C DRAW AXES FOR PLOT ONLY C IFF (NEWPLOT) THEN { IF (IXAXIS .EQ. 0) X1S = X0S-1.0 !NO X AXIS IF (IYAXIS .EQ. 0) Y1S = Y0S-1.0 !NO Y AXIS CALL GRAXIL (X0S, X1S, DXS, Y0S, Y1S, DYS) } C C NOW PLOT THE DATA ON TOP OF THE GRAPH C IFF (USE_SYMBOL) THEN CALL GRFIXL (X, Y, NPTS, 1, XLS, XRS, YBS, YTS) ELSE CALL GRAF1A (X, Y, NPTS, 1, LINE_TYPE, LINE_THICKNESS, 1 LINE_PEN, XPOINT, YPOINT, NPOINTS, 1, -HITE(4), -66, 1) C C NUMBER THE AXES. C SINCE THE USER MAY HAVE SPECIFIED A DIFFERENT SCALE THAN THAT C CALCULATED BY GRSCAL, WE MUST RECALCULATE THE NUMBER OF DIGITS C REQUIRED IN EACH NUMBER. THIS MAY NOT ALWAYS BE WHAT IS DESIRED, C SO THE OPTION IS GIVEN OF OVERRIDING IT THROUGH DECIMALS-X, VIZ NDECXS. C IFF (NEWPLOT) THEN { XX(1) = XLS !RECALCULATE NUM OF DEC PLACES FOR NEW SCALES XX(2) = XRS YY(1) = YBS YY(2) = YTS CALL GRSCAL (XX, YY, 2, T1, T2, T3, T4, T5, T6, NDECX, NDECY) IF (NDECXS .NE. NULL) NDECX = NDECXS IF (NDECYS .NE. NULL) NDECY = NDECYS XLMOST = XPLOTL !MOVED LEFT BY GRNUML IF (IXAXIS .NE. 0) 1 CALL GRNUML (1, LOGARX, X0S, X1S, DXS, XLS, 2 XSCALE, XPLOTL, NDECX) IF (IYAXIS .NE. 0) 1 CALL GRNUML (2, LOGARY, Y0S, Y1S, DYS, YBS, 2 YSCALE, YPLOTB, NDECY) C C DRAW TITLES, DATE C CALL GRTITL (MTITLE, 80, XTITLE, 80, YTITLE, 80) IF (IDATE .NE. 0) CALL GRDATE } CALL PLOTF C C IF WE JUST PLOTTED SOME SYMBOLS, REMEMBER THEM SO SUBSEQUENT C CURVES DO NOT PASS ON TOP OF THEM. C IFF (USE_SYMBOL) THEN { J = 0 WHILE (J .LT. NPTS .AND. NPOINTS .LT. NPOINTMAX) { NPOINTS = NPOINTS + 1 J = J+1 XPOINT(NPOINTS) = X(J) YPOINT(NPOINTS) = Y(J) } } RETURN END subroutine subs (line, lline, cmdlin, iarg, narg) C C This searchs the asciz string LINE for occurrences of the %n% code, C and replaces them with the corresponding arguments from the command C line in CMDLIN, pointed to by IARG. There are NARG arguments on the C command line, counting the first. C byte line(1), cmdlin(1), search(4) integer iarg(1) nskip = 2 !number of args before P1 if (narg .le. nskip) return !no substitutes on cmd line for j=1,narg-nskip { call string (search, '%1%') search(2) = '0' + j call substi (line, search, cmdlin(iarg(j+nskip))) } lline = length(line) return end logical function substi (instr, search, replac) C C This takes an input string INSTR, searchs it for occurrences of C string SEARCH, and replaces it with string REPLAC. C If called as a logical function (and declared so), it will return C true if a substitition occurred. C byte instr(1), search(1), replac(1) C C Find search string in instr C substi = .false. call indexc (index, search, instr) if (index .le. 0) return !no luck C C Index points to beginning of search string in instr C ls = length(search) lr = length(replac) li = length(instr) + 1 !include zero byte at end k1 = index+ls !start of instr after search piece idif = ls - lr !amount to shorten string by if (idif .ge. 0) go to 200 C C Search string shorter than replacement, must shift end of instr to right C do 100 j = li, k1, -1 !copy right to left 100 instr(j-idif) = instr(j) go to 500 C C Serach string longer than replacement, must shift end of instr to left C 200 do 400 j = k1, li 400 instr(j-idif) = instr(j) C C Now copy replacement string into place C 500 do 600 j = 1, lr 600 instr(index+j-1) = replac(j) C C Finished C substi = .true. return end