1! Lawrence University Department of Chemistry Appleton, Wisconsin 54911 (414) 739-3681, Ext. 456 2! Program name, version, date, authorship: NMRPLT, Version 1C, 13-Dec-74 (Slave program for NMRSIM) NMRSIM was written by Dr. James S. Evans, Department of Chemistry, Lawrence University. 3! Purpose of program: NMRSIM simulates nmr spectra from values of coupling constants, chemical shifts, rf power, and relaxation times. 4! Included are subroutines for several plotting devices: Tektronix 4010 graphics terminal; TSP-212 plotter system; Hewlett-Packard 7200A/7202A graphic plotter. 5! Language and operating system: NMRSIM, written in BASIC-PLUS, uses virtual core files and several non-privileged SYS functions, and runs in 8K under RSTS Versions 4A-12 (PDP-11/35), 05-21 (PDP-11/45), and 05B-24. 6! Availability: NMRSIM is a non-proprietary program product of Lawrence University. It is distributed at cost for educational use, on the condition that it not be sold, rented, or leased for profit. 7! Limitations: Variables in NMRSIM are dimensioned to handle up to 6 spin-1/2 nuclei, or fewer with larger spins. Larger systems might be feasible on an 11/45 configured for 16K of user core. 8! Further documentation: User's guide: 6 pages of run instructions and operational features for students who will use NMRSIM in physical or organic chemistry courses. 9! Programmer's guide: discussion of algorithms and instructions for system implementation. 10! Disclaimer: Neither the author of this program nor Lawrence University assumes any liability, expressed or implied, with respect to the correctness or performance of this program. 100 ! NMRPLT - SECTIONS 21-28 OF NMRSIM 110 DIM E(70%),I(70%),X%(70%),Y(780%) ! E,I,X% DIMENSIONED FOR N9% LINES ! Y DIMENSIONED FOR N5% HORIZONTAL PLOT POSITIONS 120 DIM #2, N%(30%),N$(20%)=2%,N0$(10%)=8%, B$(6%)=4%,L%(6%),G(6%),J(6%,6%), I6%(64%,6%),I7%(64%),I8%(7%),I9%(7%),K(1000%,1%) 130 PRINT "CAN'T RUN NMRPLT" : GOTO 32000 200 N1$=CHR$(35%) 210 F0=0 : F1=1 : F2=2 : F9=0.5 : N2$=".NMR" : M6%,K0%=0% : K1%=1% : K2%=2% : K3%=3% : K4%=4% : K5%=5% : K6%=6% : K7%=7% : K8%=8% : P5%,K9%=9% : ON ERROR GOTO 30000 : GOSUB 21400 : N5%,X5%=780% : N9%=70% ! SET CONSTANTS; ENABLE ^C TRAP 220 I8%=K9% : GOSUB 20000 : OPEN "NMRTMP.J"+RIGHT(NUM$(100%+ASCII(K0$)/K2%),K3%) FOR INPUT AS FILE K2%, CLUSTERSIZE K8% : I%=N%(K7%) : P0%=N%(K2%) : IF P0%=K3% THEN 230 ELSE GOSUB 1100 : GOSUB 1200 : X5%=P5% ! GET MODULE AND PLOT CODES 230 N2%=22% : X5%=N5% IF X5%>N5% : Y5=X5% : GOTO 600 ! SET SCALING FACTORS; DEFAULT 9% PREVENTS DIV BY 0 500 GOSUB 21300 : PRINT : INPUT "NEXT"; A$ : GOTO 520 IF LEFT(A$,K2%)=N$(I%) FOR I%=K0% TO 20% ! CANCEL ^O; GET NEXT COMMAND 510 I9%=109% : GOSUB 21200 : GOTO 500 ! 'WHAT?' 520 M6%=K0% : N%(K7%)=I% ! RESET ^C FLAG; SAVE OPERATION CODE 600 ON I%+K1% GOTO 1900,1900,1900,1900,1900,510,1900,510,510,510, 1900,2100,2200,2300,2400,2500,2600,510,2800,510,1900 1100 RETURN UNLESS P0% : ON P0% GOTO 1101,1112,1113 !****ENTER PLOT MODE**** 1101 P5%=780% : P1$=CHR$(157%) : P2$=CHR$(13%)+CHR$(10%) : P8%=32% : PRINT CHR$(155%);CHR$(133%); : INPUT LINE P3$ ! [TEK] 1111 P3$=P1$+CHR$(128%+ASCII(RIGHT(P3$,K4%))) +CHR$(192%+ASCII(RIGHT(P3$,K5%))) +CHR$(128%+ASCII(RIGHT(P3$,K2%))) +CHR$(160%+ASCII(RIGHT(P3$,K3%)))+CHR$(159%) : GOTO 1190 ! [TEK] 1112 P4%=50% : P5%=510% : P1$=CHR$(13%)+CHR$(10%)+CHR$(144%) : P2$="" : P3$=CHR$(13%)+CHR$(10%)+CHR$(128%) : GOTO 1190 ! [TSP] 1113 P4%=1000% : P5%=9999% : P1$="PLTL" : P3$=" PLTT"+CHR$(13%)+CHR$(10%) : PRINT P1$ : GOTO 1190 ! [HP] 1190 P$="" : P9%=K0% : RETURN 1200 RETURN UNLESS P0% : ON P0% GOTO 1201,1202,1203 !****RESTORE PRINT MODE**** 1201 IF P9%>K4% THEN 1210 ELSE 1220 ! [TEK] 1202 IF P9% THEN 1210 ELSE 1220 ! [TSP] 1203 GOTO 1220 ! [HP] 1210 GOSUB 1380 ! FINISH OFF PLOT 1220 PRINT P3$; : RETURN ! SEND RELEASE CODE TO DEVICE 1300 RETURN UNLESS P0% : X2%=P5%*(X-X0)/(X1-X0) : Y2%=P5%*(Y-Y0)/(Y1-Y0) : X2%=K0% IF X2%P5% : Y2%=P5% IF Y2%>P5% : ON P0% GOTO 1301,1312,1312 !****PLOT (X,Y) IF L=0**** 1301 P$=P$+P1$ IF L<>F0 : X2%=X2%+243% : P1%=X2%/P8% : P2%=Y2%/P8% ! [TEK] 1311 P$=P$+CHR$(160%+P2%)+CHR$(224%+Y2%-P8%*P2%)+CHR$(160%+P1%) +CHR$(192%+X2%-P8%*P1%) : P9%=P9%+K4% : GOTO 1370 ! [TEK] 1312 IF L<>F0 THEN P8%=64% ELSE P8%=K0% 1313 GOTO 1314 UNLESS P8% : GOSUB 1316 UNLESS P0%=K3% : X3%,X4%=X2% : Y3%,Y4%=Y2% : GOSUB 1316 : RETURN IF P0%=K3% : GOSUB 1316 : GOTO 1370 ! LIFT PEN AND MOVE TO (X,Y) 1314 X3%=X2%-X4% : Y3%=Y2%-Y4% : Y1%=K1%+(ABS(X3%)+ABS(Y3%))/P4% : X1%=SGN(X3%)+X3%/Y1% : Y1%=SGN(Y3%)+Y3%/Y1% ! INCREMENTS 1315 X4%=X4%+X1% : X4%=X2% IF SGN(X4%-X2%)*X1%>=K0% : Y4%=Y4%+Y1% : Y4%=Y2% IF SGN(Y4%-Y2%)*Y1%>=K0% : GOSUB 1316 : GOTO 1315 UNLESS X4%=X2% AND Y4%=Y2% : RETURN ! LINEAR INTERPOLATION TO SLOW DOWN PEN 1316 ON P0% GOTO 1210,1322,1333 ! ERROR CONDITION FOR TEK; ELSE OK 1322 P1%=X4%/K8% : P2%=Y4%/K8% : IF P1%=63% THEN P$=P$+CHR$(191%) ELSE P$=P$+CHR$(192%+P1%) ! [TSP] 1323 IF P2%=63% THEN P$=P$+CHR$(191%) ELSE P$=P$+CHR$(192%+P2%) ! [TSP] 1324 P1%=Y4%+K8%*(X4%-P2%-K8%*P1%)+P8% : IF P1%=127% THEN P$=P$+CHR$(254%) ELSE P$=P$+CHR$(128%+P1%) ! [TSP] 1332 P9%=P9%+K3% : GOTO 1370 ! PLOT CODES [TSP] 1333 PRINT MID(NUM$(10000%+X4%),K3%,K4%);CHR$(32%); MID(NUM$(10000%+Y4%),K3%,K4%); : PRINT CHR$(222%); IF P8% : PRINT : GOTO 1370 ! [HP] 1370 L=F0 : GOSUB 1380 IF P9%>67% : RETURN ! TEST LINE LENGTH 1380 PRINT P1$;P$;P2$; : GOSUB 1190 ! SEND OUT PLOT STRING; RESET 1381 IF P0%=K1% THEN GOTO 1311 ! REMEMBER POINT [TEK] 1390 RETURN 1900 N%(I%)=K0% FOR I%=N2% TO 28% : CLOSE K2% : CHAIN N1$+"NMRSIM" 200 ! PLOT PARAMETERS ARE NOT SAVED - MUST BE REENTERED UPON RETURN FROM MAIN PROGRAM 2100 N%(K1%)=21% : N%(I%)=K0% FOR I%=21% TO 28% : INPUT "NEW PLOT: NAME OF LINE SPECTRUM FILE"; F$ : K%=VAL(N0$(K0%)) : GOTO 2110 IF F$=N0$(I%) FOR I%=K1% TO K% : N%(K6%)=K0% : GOTO 2120 2110 N%(K6%)=I% ! SAVE POINTER TO NAME IF FILE ORIGINATED DURING THIS RUN OF THE PROGRAM 2120 N%(21%)=K1% : N%(K0%)=K1% ! LOCK INTO SEQUENTIAL MODE 2200 N%(K1%)=N2% : N%(N2%),N%(26%),N%(28%)=K0% : PRINT : F$=N0$(N%(K6%)) IF N%(K6%) : GOTO 2100 UNLESS LEN(F$) : OPEN F$+N2$ FOR INPUT AS FILE K1% : INPUT #K1%, A$,G ! FILENAME COMES FROM SECTION 21 OR FROM MAIN PROGRAM 2210 INPUT "MINIMUM MEANINGFUL RESOLUTION (HZ)"; R1 : R=F1/R1 : N7%=K0% 2220 INPUT #K1%, E7,I7 : GOSUB 3400 : GOTO 2220 ! LOOP TERMINATES ON END OF FILE, RESUMING AT LINE 2230 2230 PRINT "NUMBER OF LINES ="N7% : PRINT "LINES EXTEND FROM"E(N7%)"TO"E(K1%)"HZ" : N%(N2%)=K1% : GOTO 2310 IF N%(K7%)=13% : GOTO 500 IF N%(K0%)=K2% 2300 N%(K1%)=23% : GOTO 2200 UNLESS N%(N2%) : N%(23%)=K0% : GOTO 2310 IF N%(K7%)=13% : INPUT "TYPE 'LL' TO LIST LINES, ELSE RETURN"; A$ : GOTO 2320 UNLESS LEFT(A$,K2%)=N$(13%) : N%(K7%)=13% 2310 PRINT : PRINT "FREQUENCY","INTENSITY" : PRINT : PRINT E(I%),I(I%) FOR I%=K1% TO N7% : PRINT "NUMBER OF LINES =";N7%,"RESOLUTION =";R1;"HZ" 2320 GOSUB 21300 : N%(23%)=K1% : GOTO 500 IF N%(K0%)=K2% ! CANCEL ^O 2400 N%(K1%)=24% : GOTO 2200 UNLESS N%(N2%) : N%(24%),N%(26%),N%(28%)=K0% : N%(K0%)=K1% UNLESS N%(25%) : GOTO 2410 IF N%(K0%)=K1% AND LEFT(A$,K2%)<>N$(13%) : PRINT : PRINT "LINES EXTEND FROM"E(N7%)"TO"E(K1%)"HZ" 2410 INPUT "WHAT LEFT,RIGHT FREQUENCIES (HZ) FOR X-AXIS"; X0,X1 : N%(24%)=K1% : GOTO 500 IF N%(K0%)=K2% 2500 N%(K1%)=25% : GOTO 2200 UNLESS N%(N2%) : GOTO 2400 UNLESS N%(24%) : N%(25%),N%(26%),N%(28%)=K0% : PRINT 2510 INPUT "WHAT RF POWER (MILLIGAUSS, TRY .01)"; H1 : INPUT "WHAT T1,T2 (SEC)"; T1,T2 : N%(25%)=K1% : GOTO 500 IF N%(K0%)=K2% 2600 N%(K1%)=26% : GOTO 2400 UNLESS N%(24%) : GOTO 2500 UNLESS N%(25%) : N%(26%),N%(28%)=K0% : GOSUB 3500 : PRINT : PRINT "MAX INTENSITY (ARBITRARY) =";Y9 2610 INPUT "WHAT BOTTOM,TOP INTENSITIES FOR Y AXIS"; Y0,Y1 : N%(26%)=K1% : GOTO 500 IF N%(K0%)=K2% 2800 N%(K1%)=28% : GOTO 2810 IF N%(26%) : N%(K0%)=K1% : GOTO 2600 2810 N%(28%)=K0% : GOSUB 1100 : P4%=P5%/K9% : L=F1 : Y=-Y(K0%)-F1 : FOR I%=K0% TO X5% : IF Y(I%)=Y THEN 2820 ELSE Y=Y(I%) : X=X0+I%/X6 : GOSUB 1300 ! PLOT SPECTRUM 2820 NEXT I% : X=X0+X5%/X6 : GOSUB 1300 2830 GOSUB 21300 : L=F1 : X=X1 : GOSUB 1300 : GOSUB 1200 : N%(28%)=K1% : N%(K0%)=K2% : N%(K1%)=K0% : GOTO 500 3400 ! INSERT NEW LINE IN STORAGE 3405 DEF FNR(E7)=INT(E7*R+F9*SGN(E7))/R 3410 E7=FNR(E7) : FOR J%=K1% TO N7% : GOTO 3420 IF E7>E(J%) : GOTO 3440 IF E7=E(J%) : T=E(J%) : E(J%)=E7 : E7=T : T=I(J%) : I(J%)=I7 : I7=T ! MOVE REST OF LIST DOWN 3420 NEXT J% 3430 IF N7%>=N9% THEN 3450 ELSE N7%=N7%+K1% : E(N7%)=E7 : I(N7%)=I7 : RETURN ! LAST ITEM ON LIST 3440 I(J%)=I(J%)+I7 : RETURN ! ADD INTENSITY IF FREQUENCY IS SAME 3450 R=F9*R : I9%=44% : GOSUB 21200 : PRINT "RESOLUTION DEGRADED TO"F1/R"HZ" : E(K1%)=FNR(E(K1%)) : K%=K1% : FOR J%=K2% TO N7% : E(J%)=FNR(E(J%)) : IF E(J%)<>E(K%) THEN 3460 ELSE I(K%)=I(K%)+I(J%) : GOTO 3470 3460 K%=K%+K1% : E(K%)=E(J%) : I(K%)=I(J%) 3470 NEXT J% : N7%=K% : IF E7=E(N7%) THEN 3440 ELSE 3430 3500 ! APPLY LORENTZ LINESHAPE FUNCTION TO LINE SPECTRUM 3510 X6=X5%/(X1-X0) : FOR I%=K1% TO N7% : T=X6*(E(I%)-X0) : X%(I%)=INT(T+F9*SGN(T)) : NEXT I% : Y(I%)=F0 FOR I%=K0% TO X5% : B1=G*H1*T2 : B2=F1+B1*G*H1*T1 : B3=T2*T2/(X6*X6) : L=B1/B2 : J%=K0% : Y9=F0 ! X% INDEXES LINES DIGITALLY ALONG X AXIS 3520 FOR I%=K1% TO N7% : K%=X%(I%) : IF K%X5% THEN 3530 ELSE Y=Y(K%)+L*I(I%) : Y9=Y IF Y>Y9 : Y(K%)=Y ! ADJUST PEAK HEIGHTS AT CENTERS 3530 NEXT I% : B4=F2*L/Y5 ! CUT-OFF CRITERION FOR PEAK TAILS 3540 J%=J%+K1% : L=B1/(B2+B3*J%*J%) : RETURN IF LX5% THEN 3550 ELSE Y=Y(K%)+L*I(I%) : Y9=Y IF Y>Y9 : Y(K%)=Y 3550 J%=-J% : NEXT L% : NEXT I% : GOTO 3540 ! ADD OFF-CENTER AMPLITUDES FOR EVERY LINE NOTE: J% ALTERNATES LEFT AND RIGHT SIDES OF PEAK 20000 I8%,I9%=K0% UNLESS I7%=K6% : K0$=SYS(CHR$(I7%)+CHR$(I8%)+CHR$(I9%)) : RETURN ! SYS FUNCTION CALL 21200 I7%=K6% : I8%=K9% : GOSUB 20000 : PRINT MID(K0$,K3%,INSTR(K3%,K0$,CHR$(K0%))-K3%) : RETURN ! RSTS ERROR MESSAGE 21300 I7%=K0% : GOSUB 20000 : SLEEP F1 : RETURN ! CANCEL ^O 21400 I7%=K6% : I8%=-K7% : I9%=K0% : GOSUB 20000 : RETURN ! ENABLE ^C TRAP 30000 RESUME 31000 IF ERR=28% : RESUME 2230 IF ERR=11% AND N%(K1%)=N2% : I9%=ERR : GOSUB 21200 : GOTO 30030 UNLESS ERR=K2% OR ERR=K5% : RESUME 2100 IF ERL=2200 : GOTO 31990 ! BAD FILENAME, OR FILE CANNOT BE FOUND 30030 GOTO 30040 IF ERR<>61% : RESUME 2210 IF ERL=2210 : RESUME 2410 IF ERL=3510 : GOTO 31990 ! DIVISION BY 0 30040 GOTO 31990 UNLESS ERR=50% 30050 RESUME 2210 IF ERL=2210 : RESUME 2410 IF ERL=2410 : RESUME 2510 IF ERL=2510 : RESUME 2610 IF ERL=2610 : GOTO 31990 ! ILLEGAL NUMBER TRAP***CHANGE TO ERR=52% PRIOR TO RSTS VERSION 05B-24*** 31000 GOSUB 21400 : RESUME 2320 IF N%(K1%)=23% : IF N%(K1%)=28% THEN GOSUB 1200 : RESUME 2830 31010 IF M6% THEN 31020 ELSE M6%=K1% : RESUME 500 31020 GOSUB 21300 : N%(K7%)=10% : RESUME 1900 31990 I9%=117% : GOSUB 21200 : I9%=114% : GOSUB 21200 : PRINT "IF POSSIBLE, CONTACT MR. EVANS BEFORE LOGGING OFF" : ON ERROR GOTO 0 32000 END