PROGRAM SPM C C To read the SPM data and graph. C C B. Z. Lederman C 4-Sep-84 Update to Plotter, file, etc. C 18-Oct-84 Color map and plot speed enhancements C 29-Oct-84 Update for new SPM C 06-Dec-84 "Flattop" graph C 07-Dec-84 Change order of graphs again. C IMPLICIT INTEGER (A-F, H-Z) PARAMETER POINTS = 600 PARAMETER POINT2 = 2 * POINTS INCLUDE '[001005]CGL.FTN/NOLIST' REAL X(2, POINTS), Y(2, POINTS, 4), MAX(4), MIN(4) REAL XA(POINT2), YA(POINT2, 4) REAL A, B, C, D, A2, D2, AL, AR, DX, DY, HOURS(24) INTEGER*2 SAVCOL(24), MOVCOL(24), DATA(22), COUNT INTEGER*4 KW, KER, IDL, DEVUSD, DEVFRE, BASTIM INTEGER*4 ID(4, 6), OLD1, OLD2, GH, TI, OUTF, BASE BYTE DATE(8), STARTM(8), ENDTIM(8), SPMLOG(6) BYTE MAXVAL(8), VALUE(8), TITLE(16, 6), BLANKS(10), INFILE(32), ANS BYTE OUTFIL(32) REAL*8 T8(2, 6) LOGICAL FIRST, PRINT, PLOT, FILE C EQUIVALENCE (T8, TITLE), (OUTFIL(1), OUTF) EQUIVALENCE (DATA(2), KW), (DATA(4), KER), (DATA(6), IDL), 1 (DATA(18), DEVUSD), (DATA(20), DEVFRE) EQUIVALENCE (XA, X), (YA, Y) C DATA MOVCOL / 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 3, 7, 1 7, 7, 0, 0, 7, 7, 7, 0, 7, 7, 7, 7 / C DATA HOURS, FRM, INFILE, OUTFIL / 24 * 0., 0, 32 * 0, 32 * 0 / DATA BLANKS, SPMLOG / 10 * ' ', 'S','P','M',' ',' ',' ' / DATA TI, GH / 'TI:', 'GH:' / DATA DATE, STARTM, ENDTIM / 24 * ' ' / DATA ID / 'KRNL', 'IDLE', ' ', ' ', 2 'FREE', 'LARG', 'SMAL', 'NODE', 3 'SUBP', 'USED', ' ', ' ', 4 'USED', 'FREE', ' ', ' ', 5 'FREE', ' ', ' ', ' ', 6 'SPAC', 'USED', ' ', ' ' / DATA T8 / 'CPU Usag', 'e ', 'Pool Usa', 'ge ', 1 'Memory U', 'sage ', 'Measured', ' Device ', 2 'Secondar', 'y Pool ', 'Checkpoi', 'nt Space' / C PRINT = .FALSE. PLOT = .FALSE. FILE = .FALSE. C WRITE (5, 10) 10 FORMAT('$ Enter data file name: ') READ (5, 20, END = 2000) INFILE 20 FORMAT( 32A1) OPEN (UNIT = 1, NAME = INFILE, TYPE = 'OLD', ERR = 2000, 1 FORM='UNFORMATTED', RECORDTYPE = 'VARIABLE', 2 READONLY) C WRITE (5, 22) 22 FORMAT('$ Store graphic output in a file [Y/N] ? ') READ (5, 40, END = 2000) ANS IF ((ANS .EQ. 'Y') .OR. (ANS .EQ. 'y')) THEN WRITE (5, 25) 25 FORMAT('$ Enter output file name: ') READ (5, 28, END = 2000) OUTLEN, OUTFIL 28 FORMAT(Q, 32A1) FILE = .TRUE. GOTO 90 ENDIF C OUTLEN = 3 WRITE (5, 32) 32 FORMAT('$ Output directly to plotter [Y/N] ? ') READ (5, 40, END = 2000) ANS IF ((ANS .EQ. 'Y') .OR. (ANS .EQ. 'y')) THEN OUTF = GH PLOT = .TRUE. GOTO 90 ENDIF C OUTF = TI WRITE (5, 30) 30 FORMAT(' Output will be to video screen.' / 1 '$ Copy output to printer [Y/N] ? ') READ (5, 40, END = 2000) ANS 40 FORMAT(A1) IF ((ANS .EQ. 'Y') .OR. (ANS .EQ. 'y')) PRINT = .TRUE. IF (PRINT) OPEN (UNIT = 2, FILE = 'TT2:FORMF.EED', TYPE = 'NEW') C 90 CALL CGL (GIC) ! Initialize Core CALL CGL (GIVS, OUTFIL, OUTLEN) ! Initialize Surface CALL CGL (GSVS, OUTFIL, OUTLEN) ! Select Surface IF (FILE .OR. PLOT) CALL CGL (GDVS, 'TI:', 3) ! De-Select Video Screen CALL CGL (GNF) ! New Frame CALL CGL (GICM, SAVCOL) ! Save preset colors CALL CGL (GSCM, MOVCOL) ! First set of colors CALL CGL (GSWM, 6) ! set write mode replace CALL CGL (GSWI, 7) ! write index white CALL CGL (GSCJ, 1, 2) ! justify text left, center C DO 1000 FRM = 1, 6 ! once for each data set REWIND 1 ! start at beginning of file DO 50 J = 1, 4 ! reset variables MIN(J) = 1.6E38 50 MAX(J) = 0. OLDHR = 0. H = 0 L = 1 OLD1 = 0 OLD2 = 0 COUNT = 0 FIRST = .TRUE. C 100 READ (1, END = 200) DATA C IF (DATA(1) .EQ. '407'O) THEN ENCODE (8, 110, DATE) DATA(5), DATA(6), DATA(4) ! get date 110 FORMAT ( I2, 2( '/', I2.2)) ENCODE (8, 120, STARTM) (DATA(J), J = 7, 9) ! and time 120 FORMAT ( I2, 2( ':', I2.2)) BASE = KW COUNT = (DATA(8) * 60) + DATA(9) ! seconds into hour GOTO 100 ! finished with first record ENDIF C IF (DATA(1) .EQ. '410'O) THEN ENCODE (8, 120, ENDTIM) (DATA(J), J = 7, 9) GOTO 100 ENDIF C DO 130 J = 1, 4 130 Y(1, L, J) = 0. ! wipe out previous data C IF (FRM .EQ. 1) THEN ! get CPU IF (FIRST) THEN OLD1 = KER OLD2 = IDL ELSE Y(1, L, 1) = 0.00001 * ABS(FLOATJ(KER - OLD1)) OLD1 = KER Y(1, L, 3) = 0.00001 * ABS(FLOATJ(IDL - OLD2)) OLD2 = IDL Y(1, L, 2) = Y(1, L, 1) + Y(1, L, 3) ENDIF ELSE IF (FRM .EQ. 2) THEN ! convert bytes to words Y(1, L, 1) = 0.5 * FLOATI(DATA(9)) ! free pool Y(1, L, 2) = 0.5 * FLOATI(DATA(11)) ! largest segment Y(1, L, 3) = 0.5 * FLOATI(DATA(10)) ! smallest segment CCC Y(1, L, 4) = 0.5 * FLOATI(DATA(8)) ! number of pool nodes ELSE IF (FRM .EQ. 3) THEN ! memory Y(1, L, 1) = FLOATI(DATA(13)) ! sub. par Y(1, L, 2) = FLOATI(DATA(14)) / 1024. ! used ELSE IF (FRM .EQ. 6) THEN ! checkpoint space Y(1, L, 1) = FLOATI(DATA(15)) ! space Y(1, L, 2) = FLOATI(DATA(16)) ! used ELSE IF (FRM .EQ. 4) THEN ! device used IF (FIRST) THEN OLD1 = DEVUSD ELSE Y(1, L, 1) = FLOATJ(DEVUSD - OLD1) OLD1 = DEVUSD Y(1, L, 2) = 0.00001 * FLOATJ(DEVFRE) ENDIF ELSE ! only secondary pool left Y(1, L, 1) = FLOATI(DATA(22)) ENDIF C DO 160 J = 1, 4 IF (Y(1, L, J) .LT. MIN(J)) MIN(J) = Y(1, L, J) ! capture minimums IF (Y(1, L, J) .GT. MAX(J)) MAX(J) = Y(1, L, J) ! capture maximums 160 Y(2, L, J) = Y(1, L, J) ! duplicate point C A = 0.00001 * ABS(FLOATJ(KW - BASE)) ! get elapsed time in seconds IF (A .GE. 1.) THEN ! one second has elapsed B = B + A ! count seconds BASE = KW ! reset base ENDIF COUNT = JNINT(B) ! convert to nearest integer IF (COUNT .GE. 3600) THEN ! have gone past end of hour IF (H .LT. 24) THEN ! Get hour marker H = H + 1 ! (up to 24 of them) HOURS(H) = L + 0.5 ENDIF COUNT = 0 ! reset for next hour B = B - 3600. ! ditto ENDIF C IF (FIRST) THEN FIRST = .FALSE. ELSE X(1, L) = L ! set X coordinate X(2, L) = L + 1 ! pair L = L + 1 ! next point ENDIF C IF (L .LT. POINTS) GOTO 100 ! get next record if not full C 200 CONTINUE C A = L ! convert end point to real L = L - 1 ! correct point count L = 2 * L ! double points B = AMAX1( MAX(1), MAX(2), MAX(3), MAX(4)) ! get maximum data value IF (B .LE. 0.0) GOTO 1000 ! skip if no data this queue KW = JNINT(B) ! convert to integer (re-use KW) ENCODE (8, 250, MAXVAL) KW ! convert to ASCII 250 FORMAT( I8) IF (B .LT. 10.) B = 10. ! set minimum Y-axis value C D2 = 1. ! start Y-axis grid at 1. 630 D2 = 10. * D2 ! go up by factors of 10. DY = 2.4 * D2 ! limit to change grid IF (DY .LT. B) GOTO 630 ! haven't hit limit yet D2 = 0.1 * D2 ! went past, go back down one C C = -0.12 * A ! corners of window D = -0.1 * B IF (PLOT) THEN ! wait for paper WRITE (5, 830) 830 FORMAT('$ Insert paper, then press Return or Enter.') READ (5, 40, END = 900) ANS ENDIF C IF (FILE .OR. PLOT) CALL CGL (GBB) ! begin batch update CALL CGL (GSW, C, A, D, B) ! Set window CALL CGL (GSO, 0) ! Set origin to bottom left CALL CGL (GMA2, 1., 0.) ! Move to origin CALL CGL (GRA2, A, B) ! Draw box around window C DX = 0.025 * A ! length of tic DY = A - DX ! position of right tic DX = DX + 1. ! correct for starting position A2 = 0.98 * B ! upper limit to grid DO 600 J = 1, 2 ! for left and right sides DO 600 AR = D2, A2, D2 ! for each Y axis interval IF (J .EQ. 1) THEN ! do each side seperately CALL CGL (GMA2, 1., AR) ! move to position on left edge CALL CGL (GLA2, DX, AR) ! draw small line ELSE CALL CGL (GMA2, A, AR) ! move to right edge CALL CGL (GLA2, DY, AR) ! draw another small line ENDIF 600 CONTINUE C D2 = 0.5 * D ! need for positioning A2 = B + D2 ! ditto AR = 0.01 * A ! right end of sample line AL = -6. *(AR) ! left end of sample line C DO 300 J = 1, 2 ! for two variables IF (MAX(J) .LE. 0.0) GOTO 300 ! don't plot if no data CALL CGL (GSWI, J) ! Set color K = J + 1 ! don't start with solid line IF (.NOT.PLOT) CALL CGL (GSLS, K, 0, 0) ! set line type IF (KW .EQ. MAX(J)) CALL CGL(GSLS, 1, 0, 0) ! solid line for max. CALL CGL (GMA2, XA(1), YA(1, J)) ! Move to start CALL CGL (GPLA2, XA(1), YA(1, J), L) ! Draw lines, connected A2 = D2 + A2 ! drop down for each device CALL CGL (GMA2, C, A2) ! move to position at left IF (.NOT.PLOT) CALL CGL (GT, BLANKS, 10) ! make room for name and sample CALL CGL (GT, ID(J, FRM), 4) ! name device IF (.NOT.PLOT) THEN CALL CGL (GMA2, AL, A2) ! start of sample line CALL CGL (GLA2, AR, A2) ! draw sample ENDIF IF (FRM .EQ. 3) THEN KER = JNINT(MIN(J)) ! smallest segment of pool ELSE KER = JNINT(MAX(J)) ! maximum for this variable ENDIF ENCODE (8, 250, VALUE) KER ! convert to text A2 = D2 + A2 ! drop down CALL CGL (GMA2, C, A2) ! move to position CALL CGL (GT, VALUE, 8) ! write out value 300 CONTINUE C CALL CGL (GSLS, 1, 0, 0) ! set line type to solid CALL CGL (GSWI, 7) ! set color to white A2 = D2 + A2 ! drop down once more CALL CGL (GMA2, C, A2) ! move to position CALL CGL (GT, SPMLOG, 6) ! identify source CC A2 = D2 + A2 ! drop down again CC CALL CGL (GMA2, C, A2) ! move to position CC CALL CGL (GT, MAXTIC, 8) ! write out secondary maximum A2 = B + D2 ! remember D is negative CALL CGL (GMA2, C, A2) ! top left CALL CGL (GT, MAXVAL, 8) ! write in maximum Y CALL CGL (GMA2, C, D2) ! lower left CALL CGL (GT, STARTM, 8) ! starting time CALL CGL (GITE2, 20, DX, DY) ! obtain amount of space used A2 = C + DX CALL CGL (GMA2, A2, D2) ! over that amount CALL CGL (GT, DATE, 8) ! note the date CALL CGL (GITE2, 22, DX, DY) ! repeat process A2 = DX + A2 CALL CGL (GMA2, A2, D2) CALL CGL (GT, TITLE(1, FRM), 16) ! identify variable plotted CALL CGL (GITE2, 30, DX, DY) A2 = DX + A2 CALL CGL (GMA2, A2, D2) CALL CGL (GT, ENDTIM, 8) ! ending time C DY = 0.25 * D2 ! length of tic DX = -(DY) ! actually move above line A2 = 0.96 * B ! length of top tic DO 800 J = 1, 2 ! for top and bottom of graph DO 800 M = 1, H ! put in hour tics AR = HOURS(M) ! re-use AR as temp. var. IF (AR .LE. (0.02 * A)) GOTO 800 ! don't overprint first time IF (AR .GE. (0.98 * A)) GOTO 800 ! or last time IF (J .EQ. 1) THEN CALL CGL (GMA2, AR, DX) ! move over above bottom line CALL CGL (GLA2, AR, DY) ! draw small line ELSE CALL CGL (GMA2, AR, B) ! move over on top line CALL CGL (GLA2, AR, A2) ! draw another small line ENDIF 800 CONTINUE C CALL CGL (GMA2, C, D) ! move cursor to lower left IF (PRINT) THEN IF ((FRM .EQ. 1) .OR. (FRM .EQ. 4)) 1 WRITE (2, 810) ! need form feed 810 FORMAT ( '1' ) CALL CGL (GPS, C, A, D, B, 0., 0.) ! print screen ELSE IF (FILE .OR. PLOT) THEN CALL CGL (GEB) ! end batch WRITE (5, 820) FRM 820 FORMAT(' Writing frame ', I3) ELSE CALL CGL (GMA2, C, D) ! move to lower left corner CALL CGL (GCW, 8.) ! Wait ENDIF CALL CGL (GNF) ! New Frame 1000 CONTINUE C 900 CALL CGL (GSCM, SAVCOL) ! Put original colors back CALL CGL (GDVS, OUTFIL, OUTLEN) ! De-Select view surface CALL CGL (GTVS, OUTFIL, OUTLEN) ! Terminate view surface CALL CGL (GTC) ! Terminate Core 2000 CALL EXIT ! also closes files C END