staden-lg/src/staden/dias89.f

2200 lines
63 KiB
Fortran

C DIASUB SUBROUTINES FOR DIAGON
C AUTHOR: RODGER STADEN
C 16-7-92 Now passing isame to qicks so that main diagonal can be ignored
C 16-7-92 Now passing isame to cfsq so that main diagonal can be ignored
C 7-2-90 mhist changed to using reals (rm and rmsq) for sd calc
C 8-2-90 switched idim1,idim2 in 2 places in mhist, once in qicks
C 14-2-90 removed call getreg from actout for compatibility with other
C programs
C 12-6-90 Changed all occurrences of lh to lf
C 9-7-90 removed menu routine
C 13-11-90 replaced all radio by radion
C 12-1-91 ALIGNM changed call to alignd to use nmax instead of maxseq
C Changed alignd to check for pout exceeding array bounds
C 25-4-91 Fixed bug in cfsq that allowed cfseq to extend off end of arrays
C 6-6-91 Added a check for pout over end of array to alignd
C added ctonum to pcon to allow for difference case letters
C 2-3-92 added filnam = ' ' for som ecalls to openf1
C ROUTINES IN THIS LIBRARY:
C DMENU
C DIAPRW
C SHOBOX
C WRITAL
C ACTOUT
C DIAPER
C DIAPRO
C DIABOX
C DIAEXP
C DIAOBS
C DIALIN
C ALIGN
C FMT2
C FRAME
C MOVEI
C HELPD
C FILEDG
C QVORH
C CFSQ
C ENCONB
C CFSEQ
C NCODE
C SETCON
C EXTNDM
C DSTAT
C REDEFD
C PRINTD
C MXPTHD
C SCORED
C APBIAS
C ACALCD
C GAPRM
C ALIGND
SUBROUTINE SWTCHD(SAME,KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH)
INTEGER SAME,OPT
CHARACTER HELPF*(*)
CALL YESNO(OPT,'Show main diagonal',
+IHELPS,IHELPE,HELPF,IDEVH,KBIN,KBOUT)
IF(OPT.LT.0) RETURN
SAME = 0
IF(OPT.EQ.1) SAME = 1
END
SUBROUTINE SWTCHI(MARKI,KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH)
INTEGER OPT
CHARACTER HELPF*(*)
CALL YESNO(OPT,'Plot identities in matching spans',
+IHELPS,IHELPE,HELPF,IDEVH,KBIN,KBOUT)
IF(OPT.LT.0) RETURN
MARKI = 1
IF(OPT.EQ.1) MARKI = 0
END
C DIAPRW
SUBROUTINE DIAPRW(S1M,S1P,IDIM1P,S2M,S2P,IDIM2P,
+M,IDM,LINEB,
+LINEC,LINEE,LENGTH,MINS,SEQVC,IDIM1,SEQHC,IDIM2,
+KBOUT,IDEV1,IV1,IH1,ISTARH,ISTARV,SAME)
C AUTHOR: RODGER STADEN
INTEGER S1M(IDIM1P),S1P(IDIM1P)
INTEGER S2M(IDIM2P),S2P(IDIM2P)
INTEGER LINEB(IDIM2P),LINEC(IDIM2P),M(IDM,IDM),LINEE(IDIM1P)
INTEGER TEMPB,TEMPP,SAME
CHARACTER SEQVC(IDIM1),SEQHC(IDIM2)
1 CONTINUE
C WRITE(KBOUT,1000)
C1000 FORMAT(' List matching spans')
CALL BUSY(KBOUT)
LB=LENGTH/2
IDIM1T=IDIM1P-LENGTH
IDIM2T=IDIM2P-LENGTH
C NEED TO SET LINEB TO INITAL VALUE FOR FIRST LENGTH POSITIONS
C AND LINEE TO LEFT EDGE VALUES
C FIX LEFT EDGE BY SUMMING ALL THE VALUES FOR A LENGTH LENGTH/2
C EITHER SIDE OF THE REAL SEQUENCE EDGE
DO 10 I=1,IDIM1T
LINEE(I)=0
IM1 = I - 1
DO 10 J=1,LENGTH
K = IM1 + J
LINEE(I)=LINEE(I)+M(S1M(K),S2M(J))
10 CONTINUE
C NOW DO TOP EDGE
DO 20 I=1,IDIM2T
C SET UP POINTERS
LINEC(I)=0
IM1 = I - 1
DO 15 J=1,LENGTH
K = IM1 + J
LINEC(I)=LINEC(I)+M(S1M(J),S2M(K))
15 CONTINUE
20 CONTINUE
DO 21 I=1,IDIM2T
LINEC(I)=LINEC(I+1)
21 CONTINUE
LINEC(IDIM2T)=0
C MAIN LOOPS NOW
C LOOP FOR EACH ROW
C
ITV1P=LB+IV1-1-ISTARV+1
ITV1M=IV1-LB-1-ISTARV+1
ITH1P=LB+IH1-1-ISTARH+1
ITH1M=IH1-LB-1-ISTARH+1
ITV1MM=ITV1M+ISTARV-1
ITH1MM=ITH1M+ISTARH-1
DO 200 I=1,IDIM1T
C SET LINEB TO LINEC, THEN ZERO LINEC
DO 110 J=1,IDIM2T
LINEB(J+1)=LINEC(J)
LINEC(J)=0
110 CONTINUE
C SET LINEB(1) TO EDGE VALUE AS ITS OFF PAGE
LINEB(1)=LINEE(I)
C
C NOW COMPARE THIS CHAR OF SEQ1 WITH WHOLE OF SEQ2
TEMPP=S1P(I)
TEMPB=S1M(I)
DO 150 J=1,IDIM2T
LINEC(J)=LINEB(J)+M(TEMPP,S2P(J))-M(TEMPB,S2M(J))
IF(LINEC(J).LT.MINS)GO TO 150
C ABOVE CUTOFF SO WRITE
IF(I.EQ.J)THEN
IF(SAME.NE.1)THEN
WRITE(IDEV1,1006)I+ITV1MM
WRITE(IDEV1,1005)(SEQVC(K),K=MAX(1,I+ITV1M),MIN(IDIM1,I+ITV1P))
WRITE(IDEV1,1005)(SEQHC(K),K=MAX(1,J+ITH1M),MIN(IDIM2,J+ITH1P))
WRITE(IDEV1,1006)J+ITH1MM
END IF
ELSE
WRITE(IDEV1,1006)I+ITV1MM
WRITE(IDEV1,1005)(SEQVC(K),K=MAX(1,I+ITV1M),MIN(IDIM1,I+ITV1P))
WRITE(IDEV1,1005)(SEQHC(K),K=MAX(1,J+ITH1M),MIN(IDIM2,J+ITH1P))
WRITE(IDEV1,1006)J+ITH1MM
END IF
1006 FORMAT(' ',I7)
1005 FORMAT(' ',200A1)
150 CONTINUE
200 CONTINUE
END
SUBROUTINE SHOBOX(SEQVC,IDIMV,SEQHC,IDIMH,IWX1,IWX2,IWX3,IWX4,
+IHELPS,IHELPE,HELPF,IDEVH,KBIN,KBOUT,KSTARH,KSTARV,IENDH,IENDV)
C AUTHOR: RODGER STADEN
CHARACTER HELPF*(*)
CHARACTER SEQVC(IDIMV),SEQHC(IDIMH)
IF(0.EQ.0) GO TO 671
1000 FORMAT(' Zoom-in to matrix',/)
WRITE(KBOUT,1000)
1002 FORMAT(' Horizontal sequence')
601 CONTINUE
WRITE(KBOUT,1002)
WRITE(KBOUT,10091)
10091 FORMAT(' MAX SIZE=36,DEFAULT=XHAIR POSITION - SPAN/2 TO',
+' XHAIR POSITION + SPAN/2')
C CALL FSTLST(IWB3,IWB4,KBIN,KBOUT)
IF(IWB3.LT.0)RETURN
IF(IWB4.LT.0)RETURN
IF((IWB3.EQ.0).AND.(IWB4.EQ.0))GO TO 651
IF((IWB4-IWB3).GT.35)GO TO 601
IF(IWB3.LT.KSTARH)GO TO 601
IF(IWB3.GT.IENDH)GO TO 601
IF(IWB4.GT.IENDH)GO TO 601
IF(IWB3.GE.IWB4)GO TO 601
C NE 0 SO USE
IWX3=IWB3
IWX4=IWB4
651 CONTINUE
IF((IWX4-IWX3).GT.35)GO TO 601
IF(IWX3.LT.1)GO TO 601
IF(IWX4.LT.IWX3)GO TO 601
661 CONTINUE
WRITE(KBOUT,1001)
1001 FORMAT(' Vertical sequence')
WRITE(KBOUT,10091)
C CALL FSTLST(IWB1,IWB2,KBIN,KBOUT)
IF((IWB1.EQ.-99).OR.(IWB2.EQ.-99))THEN
CALL HELP2(IHELPS,IHELPE,HELPF,IDEVH,KBIN,KBOUT)
GO TO 661
END IF
IF(IWB1.LT.0)RETURN
IF(IWB2.LT.0)RETURN
IF((IWB1.EQ.0).AND.(IWB2.EQ.0))GO TO 671
IF((IWB2-IWB1).GT.35)GO TO 661
IF(IWB1.LT.KSTARV)GO TO 661
IF(IWB1.GT.IENDV)GO TO 661
IF(IWB2.GT.IENDV)GO TO 661
IF(IWB1.GE.IWB2)GO TO 661
C NE 0 SO USE
IWX1=IWB1
IWX2=IWB2
671 CONTINUE
C IF((IWX2-IWX1).GT.35)GO TO 661
C IF(IWX1.LT.1)GOTO 661
C IF(IWX2.LT.IWX1)GO TO 661
IF(IWX1.LT.1) RETURN
IF(IWX2.LT.1) RETURN
IF(IWX3.LT.1) RETURN
IF(IWX4.LT.1) RETURN
IF(IWX1.GT.IDIMV) RETURN
IF(IWX2.GT.IDIMV) RETURN
IF(IWX3.GT.IDIMH) RETURN
IF(IWX4.GT.IDIMH) RETURN
IF(IWX2-IWX1.GT.35) RETURN
IF(IWX4-IWX3.GT.35) RETURN
CALL DIABOX(SEQVC(KSTARV),IDIMV,SEQHC(KSTARH),
+IDIMH,IWX1,IWX2,IWX3,IWX4,KBOUT)
RETURN
END
SUBROUTINE WRITAL(SEQHC,IDIMH,ISTARH,IENDH,
+SEQVC,IDIMV,ISTARV,IENDV,IDEVOT,KBIN,KBOUT,
+IHELPS,IHELPE,HELPF,IDEVH)
C AUTHOR: RODGER STADEN
CHARACTER HELPF*(*),SEQHC(IDIMH),SEQVC(IDIMV)
C WRITE(KBOUT,*)' Write out aligned sequences'
IW3 = ISTARH
IW4 = IENDH
CALL GTREG(KBIN,KBOUT,ISTARH,IENDH,IW3,IW4,
+'Region of horizontal sequence',
+IHELPS,IHELPE,HELPF,IDEVH,IOK)
IF(IOK.NE.0) RETURN
IW1 = ISTARV
IW2 = IENDV
CALL GTREG(KBIN,KBOUT,ISTARV,IENDV,IW1,IW2,
+'Region of vertical sequence',
+IHELPS,IHELPE,HELPF,IDEVH,IOK)
IF(IOK.NE.0) RETURN
IDIML=MIN(IW2-IW1,IW4-IW3) + 1
CALL FMT2(IDEVOT,SEQVC(IW1-ISTARV+1),SEQHC(IW3-ISTARH+1),
+IDIML,IW1,IW3)
RETURN
END
SUBROUTINE ACTOUT(SEQ,IDIM,ISTART,IEND,IDEVOT,FILOUT,KBIN,KBOUT,
+IHELPS,IHELPE,HELPF,IDEVH)
CHARACTER FILOUT*(*),HELPF*(*),SEQ(IDIM)
C AUTHOR: RODGER STADEN
C FILE SEQUENCE TO DISK
FILOUT = ' '
CALL OPENF1(IDEVOT,FILOUT,1,IOK,KBIN,KBOUT,
+'File name',IHELPS,IHELPE,HELPF,IDEVH)
IF(IOK.NE.0)RETURN
IW1 = ISTART
IW2 = IEND
C CALL GTREG(KBIN,KBOUT,ISTART,IEND,IW1,IW2,
C +'Region of sequence',
C +IHELPS,IHELPE,HELPF,IDEVH,IOK)
C IF(IOK.NE.0) RETURN
IDIML=IW2-IW1+1
CALL TITOUT(IDEVOT,KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH)
CALL FMTDK(IDEVOT,SEQ(IW1-ISTART+1),IDIML)
CLOSE(UNIT=IDEVOT)
RETURN
END
C
C DIAPER
SUBROUTINE DIAPER(SEQ1,IDIM1,SEQ2,IDIM2,LINEB,LINEC,IDL,MINS,
+MARGXL,MARGXR,MARGYL,MARGYR,ISXMAX,ISYMAX,KBOUT)
C AUTHOR: RODGER STADEN
INTEGER SEQ1(IDIM1),SEQ2(IDIM2)
INTEGER LINEB(IDL),LINEC(IDL)
INTEGER TEMPB
CALL BUSY(KBOUT)
C WRITE(KBOUT,*)'Working'
XMAX=IDIM2
XMIN=1.
YMAX=IDIM1
YMIN=1.
DO 10 I=1,IDIM2+1
LINEB(I)=0
LINEC(I)=0
10 CONTINUE
C LOOP FOR EACH ROW
DO 200 I=1,IDIM1
C ZERO LINE C AND SET LINEB TO LINEC
DO 110 J=1,IDIM2
LINEB(J+1)=LINEC(J)
110 LINEC(J)=0
C SET LINEB(1) TO ZERO AS ITS OFF PAGE
LINEB(1)=0
C
C NOW COMPARE THIS CHAR OF SEQ1 WITH WHOLE OF SEQ2
TEMPB=SEQ1(I)
DO 150 J=1,IDIM2
IF(TEMPB.NE.SEQ2(J))GO TO 150
C MATCH SO COUNT LENGTH BY ADDING CURRENT LENGTH OF THIS DIAGONAL
LINEC(J)=LINEB(J)+1
C IS THIS HIGH ENOUGH?
IF(LINEC(J).LT.MINS)GO TO 150
X=J
Y=I
CALL POINT(X,Y,XMAX,XMIN,YMAX,YMIN,
1MARGXL,MARGXR,MARGYL,MARGYR,ISXMAX,ISYMAX)
150 CONTINUE
200 CONTINUE
RETURN
END
C
C DIAPRO
SUBROUTINE DIAPRO(S1M,S1P,IDIM1P,S2M,S2P,IDIM2P,
+M,IDM,LINEB,
+LINEC,LINEE,LENGTH,MINS,
+MARGXL,MARGXR,MARGYL,MARGYR,ISXMAX,ISYMAX,KBOUT,SAME)
C AUTHOR: RODGER STADEN
INTEGER S1M(IDIM1P),S1P(IDIM1P)
INTEGER S2M(IDIM2P),S2P(IDIM2P)
INTEGER LINEB(IDIM2P),LINEC(IDIM2P),M(IDM,IDM),LINEE(IDIM1P)
INTEGER TEMPB,TEMPP,SAME
CALL BUSY(KBOUT)
C WRITE(KBOUT,*)'Working'
IDIM1=IDIM1P-LENGTH
IDIM2=IDIM2P-LENGTH
XMAX=IDIM2
XMIN=1.
YMAX=IDIM1
YMIN=1.
C NEED TO SET LINEB TO INITAL VALUE FOR FIRST LENGTH POSITIONS
C AND LINEE TO LEFT EDGE VALUES
C FIX LEFT EDGE BY SUMMING ALL THE VALUES FOR A LENGTH LENGTH/2
C EITHER SIDE OF THE REAL SEQUENCE EDGE
DO 10 I=1,IDIM1
LINEE(I)=0
IM1 = I - 1
DO 9 J=1,LENGTH
K = IM1 + J
LINEE(I)=LINEE(I)+M(S1M(K),S2M(J))
9 CONTINUE
10 CONTINUE
C NOW DO TOP EDGE
DO 20 I=1,IDIM2
C SET UP POINTERS
LINEC(I)=0
IM1 = I - 1
DO 15 J=1,LENGTH
K = IM1 + J
LINEC(I)=LINEC(I)+M(S1M(J),S2M(K))
15 CONTINUE
20 CONTINUE
DO 21 I=1,IDIM2
LINEC(I)=LINEC(I+1)
21 CONTINUE
LINEC(IDIM2)=0
C MAIN LOOPS NOW
C LOOP FOR EACH ROW
C
DO 200 I=1,IDIM1
C SET LINEB TO LINEC, THEN ZERO LINEC
DO 110 J=1,IDIM2
LINEB(J+1)=LINEC(J)
LINEC(J)=0
110 CONTINUE
C SET LINEB(1) TO EDGE VALUE AS ITS OFF PAGE
LINEB(1)=LINEE(I)
C
C NOW COMPARE THIS CHAR OF SEQ1 WITH WHOLE OF SEQ2
TEMPP=S1P(I)
TEMPB=S1M(I)
DO 150 J=1,IDIM2
LINEC(J)=LINEB(J)+M(TEMPP,S2P(J))-M(TEMPB,S2M(J))
IF(LINEC(J).LT.MINS)GO TO 150
C ABOVE CUTOFF SO PLOT
IF(I.EQ.J)THEN
IF(SAME.NE.1)THEN
X=J
Y=I
CALL POINT(X,Y,XMAX,XMIN,YMAX,YMIN,
1 MARGXL,MARGXR,MARGYL,MARGYR,ISXMAX,ISYMAX)
END IF
ELSE
X=J
Y=I
CALL POINT(X,Y,XMAX,XMIN,YMAX,YMIN,
1 MARGXL,MARGXR,MARGYL,MARGYR,ISXMAX,ISYMAX)
END IF
150 CONTINUE
200 CONTINUE
END
C DIAPRI
SUBROUTINE DIAPRI(S1M,S1P,IDIM1P,S2M,S2P,IDIM2P,
+M,IDM,LINEB,
+LINEC,LINEE,LENGTH,MINS,
+MARGXL,MARGXR,MARGYL,MARGYR,ISXMAX,ISYMAX,KBOUT,SAME)
C AUTHOR: RODGER STADEN
INTEGER S1M(IDIM1P),S1P(IDIM1P)
INTEGER S2M(IDIM2P),S2P(IDIM2P)
INTEGER LINEB(IDIM2P),LINEC(IDIM2P),M(IDM,IDM),LINEE(IDIM1P)
INTEGER TEMPB,TEMPP,SAME
C VERSION TO MARK ALL IDENTITIES
CALL BUSY(KBOUT)
IDIM1=IDIM1P-LENGTH
IDIM2=IDIM2P-LENGTH
XMAX=IDIM2
XMIN=1.
YMAX=IDIM1
YMIN=1.
C NEED TO SET LINEB TO INITAL VALUE FOR FIRST LENGTH POSITIONS
C AND LINEE TO LEFT EDGE VALUES
C FIX LEFT EDGE BY SUMMING ALL THE VALUES FOR A LENGTH LENGTH/2
C EITHER SIDE OF THE REAL SEQUENCE EDGE
DO 10 I=1,IDIM1
LINEE(I)=0
IM1 = I - 1
DO 9 J=1,LENGTH
K = IM1 + J
LINEE(I)=LINEE(I)+M(S1M(K),S2M(J))
9 CONTINUE
10 CONTINUE
C NOW DO TOP EDGE
DO 20 I=1,IDIM2
C SET UP POINTERS
LINEC(I)=0
IM1 = I - 1
DO 15 J=1,LENGTH
K = IM1 + J
LINEC(I)=LINEC(I)+M(S1M(J),S2M(K))
15 CONTINUE
20 CONTINUE
DO 21 I=1,IDIM2
LINEC(I)=LINEC(I+1)
21 CONTINUE
LINEC(IDIM2)=0
C MAIN LOOPS NOW
C LOOP FOR EACH ROW
C
DO 200 I=1,IDIM1
C SET LINEB TO LINEC, THEN ZERO LINEC
DO 110 J=1,IDIM2
LINEB(J+1)=LINEC(J)
LINEC(J)=0
110 CONTINUE
C SET LINEB(1) TO EDGE VALUE AS ITS OFF PAGE
LINEB(1)=LINEE(I)
C
C NOW COMPARE THIS CHAR OF SEQ1 WITH WHOLE OF SEQ2
TEMPP=S1P(I)
TEMPB=S1M(I)
DO 150 J=1,IDIM2
LINEC(J)=LINEB(J)+M(TEMPP,S2P(J))-M(TEMPB,S2M(J))
IF(LINEC(J).LT.MINS)GO TO 150
C ABOVE CUTOFF SO PLOT
IF(I.EQ.J)THEN
IF(SAME.NE.1)THEN
K1 = I - 1
K2 = J - 1
DO 130 K = 1,LENGTH
K1 = K1 + 1
K2 = K2 + 1
IF(S1M(K1).EQ.S2M(K2))THEN
X = K2
Y = K1
CALL POINT(X,Y,XMAX,XMIN,YMAX,YMIN,
1 MARGXL,MARGXR,MARGYL,MARGYR,ISXMAX,ISYMAX)
END IF
130 CONTINUE
END IF
ELSE
K1 = I - 1
K2 = J - 1
DO 140 K = 1,LENGTH
K1 = K1 + 1
K2 = K2 + 1
IF(S1M(K1).EQ.S2M(K2))THEN
X = K2
Y = K1
CALL POINT(X,Y,XMAX,XMIN,YMAX,YMIN,
1 MARGXL,MARGXR,MARGYL,MARGYR,ISXMAX,ISYMAX)
END IF
140 CONTINUE
END IF
150 CONTINUE
200 CONTINUE
END
C ALIGN
C ROUTINE TO INSERT PADDING AS DASHES INTO DIAGON SEQS
SUBROUTINE ALIGN(SEQVV,IDIMV,SEQHH,IDIMH,
+MAXSEQ,KBIN,KBOUT,
+IHELPS,IHELPE,HELPF,IDEVH,ISTARV,IENDV,ISTARH,IENDH,
+FILEH,FILEV)
CHARACTER HELPF*(*),FILEH*(*),FILEV*(*)
C AUTHOR: RODGER STADEN
CHARACTER SEQVV(MAXSEQ),SEQHH(MAXSEQ)
CHARACTER VORH,DASH,IORD
PARAMETER (MAXPRM = 6)
CHARACTER PROMPT(2)*(MAXPRM)
SAVE DASH
DATA DASH/'-'/
C ONLY ALLOW EDITING TO SEQUENCES THAT CAN BE TOTALLY CONTAINED IN THE
C RAM BUFFER, AND WHICH START AT 1 (WE DONT PLAN TO WRITE OUT TO THE
C DISK BUFFER)
C IE ISTARH=1, IDIMH<MAXSEQ
C IE ISTARV=1, IDIMV<MAXSEQ
C
1 CONTINUE
CALL QVORH(VORH,IHELPS,IHELPE,HELPF,IDEVH,KBIN,KBOUT,
+FILEH,FILEV)
1004 FORMAT(A)
IF(VORH.EQ.' ')RETURN
C CHECK IF OK
IF(VORH.EQ.'H')THEN
IF(ISTARH.NE.1)GO TO 100
IF(IDIMH.GT.MAXSEQ)GO TO 100
END IF
IF(VORH.EQ.'V')THEN
IF(ISTARV.NE.1)GO TO 100
IF(IDIMV.GT.MAXSEQ)GO TO 100
END IF
IF(VORH.EQ.'H') THEN
MN = ISTARH
MX = IENDH
ELSE IF(VORH.EQ.'V') THEN
MN = ISTARV
MX = IENDV
END IF
MPOS = 1
CALL GETINT(MN,MX,MPOS,'Position to edit',
+IVAL,KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH,IOK)
IF(IOK.NE.0) RETURN
IPOS = IVAL
MN = 0
MX = MIN(IENDH,IENDV)
MPOS = 0
CALL GETINT(MN,MX,MPOS,'Number of characters',
+IVAL,KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH,IOK)
IF(IOK.NE.0) RETURN
IF(IVAL.LT.1) RETURN
NCHAR = IVAL
I = 1
PROMPT(1) = 'Insert'
PROMPT(2) = 'Delete'
CALL RADION('Select edit command',PROMPT,2,I,
+IHELPS,IHELPE,HELPF,IDEVH,KBIN,KBOUT)
IF(I.LT.1) RETURN
IF(I.EQ.2) IORD = 'D'
IF(I.EQ.1) IORD = 'I'
IF(IORD.EQ.'D')NCHAR=SIGN(NCHAR,-1)
C
C V
IF(VORH.EQ.'V')THEN
IF((IDIMV+NCHAR).GT.MAXSEQ)THEN
WRITE(KBOUT,1008)MAXSEQ
1008 FORMAT(' This would make sequence longer than ',I6,
+ ' so not done.')
GO TO 1
END IF
CALL MOVEC(SEQVV,MAXSEQ,IDIMV,IPOS,NCHAR)
IF(IORD(1:1).EQ.'I')CALL FILLC(SEQVV(IPOS),NCHAR,DASH)
IDIMV=IDIMV+NCHAR
IENDV = IDIMV
WRITE(KBOUT,1010)
GO TO 1
END IF
C H
IF(VORH.EQ.'H')THEN
IF((IDIMH+NCHAR).GT.MAXSEQ)THEN
WRITE(KBOUT,1008)MAXSEQ
GO TO 1
END IF
CALL MOVEC(SEQHH,MAXSEQ,IDIMH,IPOS,NCHAR)
IF(IORD(1:1).EQ.'I')CALL FILLC(SEQHH(IPOS),NCHAR,DASH)
IDIMH=IDIMH+NCHAR
IENDH = IDIMH
WRITE(KBOUT,1010)
END IF
1010 FORMAT(' Edit done')
GO TO 1
100 CONTINUE
C COME HERE IF DISK BUFFERING SEQUENCE AND ITS TOO LONG
WRITE(KBOUT,1011)
1011 FORMAT(' Sorry but sequences of this length cannot be edited',
+' on this machine')
GO TO 1
END
C DIABOX
C WRITES BOX OF PERFECT MATCHES
SUBROUTINE DIABOX(SEQ1,IDIM1,SEQ2,IDIM2,I11,I12,I21,I22,
+KBOUT)
C AUTHOR: RODGER STADEN
CHARACTER SEQ1(IDIM1),SEQ2(IDIM2),LINE(36),SPACE
DATA SPACE/' '/
1000 FORMAT(4X,36A1)
WRITE(KBOUT,*)
DO 100 I=I12,I11,-1
DO 10 J=1,36
10 LINE(J)=SPACE
L=0
DO 50 J=I21,I22
L=L+1
50 IF(SEQ1(I).EQ.SEQ2(J))LINE(L)=SEQ1(I)
WRITE(KBOUT,1001)SEQ1(I),(LINE(K),K=1,L)
1001 FORMAT(3X,A1,36A1)
100 CONTINUE
WRITE(KBOUT,1000)(SEQ2(K),K=I21,I22)
RETURN
END
C DIAEXP COPIED ORIGINALLY FROM ANDREW MC LACHLAN
C NA=IDIM1
C NB=IDIM2
C MATS=MATRIX THE SCORE MATRIX
C NACID=IDM THE DIMENSION OF THE SCORE MATRIX
C IS=LENGTH THE SPAN LENGTH
C LIMIT=HIGHEST INDIVIDUAL SCORE IN SCORE MATRIX MATS
SUBROUTINE DIAEXP(SEQ1,NA,SEQ2,NB,MATS,NACID,IS1,
+LIMIT,POLYA,POLYB,IDPOLY,KBIN,KBOUT,IDEV,CHRSET,NORO,
+IHELPS,IHELPE,HELPF,IDEVH)
CHARACTER HELPF*(*)
C AUTHOR: RODGER STADEN
REAL POLYG(50),POLYA(IDPOLY),POLYB(IDPOLY)
INTEGER JCOMPA(26),JCOMPB(26)
REAL FCOMPA(26),FCOMPB(26),PR(10)
INTEGER MATS(NACID,NACID)
INTEGER NUM(10),OPT
CHARACTER SEQ1(NA),SEQ2(NB),CHRSET(NACID),NORO,CHART
INTEGER CTONUM
EXTERNAL CTONUM
PARAMETER (SMALL = 1.0E-30)
PARAMETER (MAXPRM = 29)
CHARACTER PROMPT(3)*(MAXPRM)
C DATA SMALL/0.00000000000000000000000000001/
C IF HAVE ALREADY DONE CALC FOR THIS SPAN SKIP
IF(NORO.EQ.'O')GO TO 533
C SET NORO TO OLD IE BEEN DONE BEFORE
NORO='O'
CALL BUSY(KBOUT)
C SET SPAN
IS=IS1
C SEQ'S ENTER ALREADY TRANSLATED TO AMINOACID POINTERS 1-26
C CALC COMPOSITION
DO 300 IC=1,NACID
JCOMPA(IC)=0
JCOMPB(IC)=0
300 CONTINUE
DO 301 JA=1,NA
CHART = SEQ1(JA)
ITEMP = CTONUM(CHART)
JCOMPA(ITEMP) = JCOMPA(ITEMP) + 1
301 CONTINUE
DO 302 JB=1,NB
CHART = SEQ2(JB)
ITEMP = CTONUM(CHART)
JCOMPB(ITEMP) = JCOMPB(ITEMP) + 1
302 CONTINUE
ANA=NA
ANB=NB
DO 303 IC=1,NACID
FCOMPA(IC)=JCOMPA(IC)
FCOMPA(IC)=FCOMPA(IC)/(ANA+0.0000001)
FCOMPB(IC)=JCOMPB(IC)
FCOMPB(IC)=FCOMPB(IC)/(ANB+0.0000001)
303 CONTINUE
C WRITE(KBOUT,1004)JCOMPA
C WRITE(KBOUT,1004)JCOMPB
1004 FORMAT(2((1X,13I4)/))
C CALC EXPECTED AV SCORE AND MEAN SQUARE
S1=0.0
S2=0.0
DO 310 L=1,NACID
DO 310 M=1,NACID
AM=MATS(L,M)
S1=S1+FCOMPA(L)*AM*FCOMPB(M)
S2=S2+FCOMPA(L)*(AM**2)*FCOMPB(M)
310 CONTINUE
C RMS SCORE PER POSITION
IF(S3.GT.0.0)S3=SQRT(S3)
S3=SQRT(S2-(S1**2))
S4=IS
S3=S3*SQRT(S4)
S1=S1*IS
C
WRITE(KBOUT,1000)S1
1000 FORMAT(' Average score=',F12.5)
WRITE(KBOUT,1001)S3
1001 FORMAT(' RMS deviation=',F12.5)
C
C SET UP GENERATING POLYNOMIAL WHICH IS THE PROBABILITY OF SELECTION
C FOR EACH OF THE LEVELS OF SCORE IN THE SCORE MATRIX MATS AND SO
C DEPENDS ONLY ON THE COMPOSITION OF THE TWO SEQUENCES AND THE
C DISTRIBUTION OF SCORES IN THE SCORE MATRIX
DO 320 J=1,50
POLYG(J)=0.
320 CONTINUE
C SUM THE PROBABILITY OF SELECTION FOR EACH LEVEL OF SCORE
DO 322 L=1,NACID
DO 321 M=1,NACID
C SCORE?
J=MATS(L,M)+1
POLYG(J)=POLYG(J)+FCOMPA(L)*FCOMPB(M)
321 CONTINUE
322 CONTINUE
C SET THOSE LESS THAN SMALL TO ZERO
DO 325 J=1,50
IF(ABS(POLYG(J)).LT.SMALL)POLYG(J)=0.0
325 CONTINUE
C
C COMPUTE PROBABILITIES
C ZERO POLYA,POLYB AND SET POLYA(1) TO 1.
DO 400 I=1,IDPOLY
POLYA(I)=0.
POLYB(I)=0.
400 CONTINUE
POLYA(1)=1.0
C SET UP
LORDER=LIMIT
MORDER=1
C LOOP SPAN TIMES TO RAISE THE POLYNOMIAL TO THE POWER SPAN
DO 500 JS=1,IS
LR=LORDER+1
MR=MORDER+1
DO 450 JG=1,LR
DO 451 JA=1,MR
C CAN SUM THE JB TERMS BECAUSE THEY GIVE THE SAME SCORE WHEN COMBINED
JB=JA+JG-1
POLYB(JB)=POLYB(JB)+POLYA(JA)*POLYG(JG)
451 CONTINUE
450 CONTINUE
MORDER=MORDER+LORDER
MR=MORDER+1
C SET VERY SMALL VALUES TO ZERO AND PREPARE FOR NEXT MULTIPLICATION STEP
DO 453 JA=1,MR
P=POLYB(JA)
IF(ABS(P).LT.SMALL)P=0.0
POLYA(JA)=P
POLYB(JA)=0.
453 CONTINUE
500 CONTINUE
C CALC CUMULATIVE PROBABILITY
MR=MORDER+1
C THIS LOOP LEAVES THE CUMULATIVE PROBABILITY FOR SCORE I IN POLYA(I)
C IE ALL THE PROBABILITY OF ACHEIVING AT LEAST SCORE I IS STORED IN POLYA(I)
DO 510 JB=1,MR
JA=MR+1-JB
POLYA(JA)=POLYA(JA)+POLYA(JA+1)
510 CONTINUE
MORDER=LIMIT*IS
XMN = 0.0000000001
MXS = MORDER
DO 520 J=1,MORDER
IF(POLYA(J).GT.XMN) GO TO 520
MXS = J
GO TO 530
520 CONTINUE
530 CONTINUE
C
533 CONTINUE
OPT = 1
590 CONTINUE
PROMPT(1) = 'Show probability for a score'
PROMPT(2) = 'Show score for a probability'
PROMPT(3) = 'List scores and probabilities'
CALL RADION('Select probability display mode',PROMPT,3,OPT,
+IHELPS,IHELPE,HELPF,IDEVH,KBIN,KBOUT)
IF(OPT.LT.1) RETURN
IF(OPT.EQ.2)GO TO 700
IF(OPT.EQ.3)GO TO 800
IF(OPT.NE.1)GO TO 590
MN = 1
ISCORE = S1 + (MXS - S1) / 2
CALL GETINT(MN,MXS,ISCORE,'Show probability for score',
+IVAL,KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH,IOK)
IF(IOK.NE.0) RETURN
ISCORE = IVAL
WRITE(KBOUT,1008)ISCORE,POLYA(ISCORE+1)
1008 FORMAT(' Probability of score ',I6,' is ',F12.10)
GO TO 590
700 CONTINUE
XMN = 0.0000000001
XMX = 1.
PROB = 0.00001
CALL GETRLS(XMN,XMX,PROB,'Show score for probability',
+VAL,KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH,IOK)
IF(IOK.NE.0) RETURN
PROB = VAL
C LOOK FOR FIRST SCORE GIVING THIS PROBABILITY
DO 710 J=1,MORDER
IF(POLYA(J).GT.PROB)GO TO 710
WRITE(KBOUT,1012)PROB,J
1012 FORMAT(' Score for probability ',F12.10,' is ',I5)
GO TO 590
710 CONTINUE
GO TO 590
800 CONTINUE
MN = 1
MX = 10
JSTEP = 5
CALL GETINT(MN,MX,JSTEP,'Number of steps between scores',
+IVAL,KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH,IOK)
IF(IOK.NE.0) RETURN
JSTEP = IVAL
MMAX=MORDER+1
LROW=MMAX/(3*JSTEP)
DO 541 JROW=1,LROW
DO 540 J=1,3
NUM(J)=(JROW-1+(J-1)*LROW)*JSTEP
PR(J)=POLYA(NUM(J)+1)
540 CONTINUE
WRITE(IDEV,1002)(NUM(J),PR(J),J=1,3)
541 CONTINUE
1002 FORMAT(3(2X,I5,1X,E12.5))
GO TO 590
END
C
C DIAOBS
SUBROUTINE DIAOBS(S1M,S1P,IDIM1P,S2M,S2P,
+IDIM2P,M,IDM,LINEB,
+LINEC,LINEE,LENGTH,NORO,PERC,SCORE,IDSCOR,KBIN,KBOUT,
+IDEV,IHELPS,IHELPE,HELPF,IDEVH,SAME)
CHARACTER HELPF*(*)
C AUTHOR: RODGER STADEN
INTEGER S1M(IDIM1P),S1P(IDIM1P)
INTEGER S2M(IDIM2P),S2P(IDIM2P)
INTEGER LINEB(IDIM2P),LINEC(IDIM2P),M(IDM,IDM),LINEE(IDIM1P)
INTEGER SCORE(IDSCOR)
REAL PERC(IDSCOR)
INTEGER TEMPB,TEMPP,OPT,SAME
PARAMETER (MAXPRM = 32)
CHARACTER PROMPT(3)*(MAXPRM)
CHARACTER NORO
C ALREADY DONE CALC FOR THIS LENGTH AND REGION?
IF(NORO.EQ.'O')GO TO 533
C SET NORO TO OLD IE BEEN DONE BEFORE
NORO='O'
CALL BUSY(KBOUT)
DO 5 I=1,IDSCOR
SCORE(I)=0
5 CONTINUE
IDIM1=IDIM1P-LENGTH
IDIM2=IDIM2P-LENGTH
C NEED TO SET LINEB TO INITAL VALUE FOR FIRST LENGTH POSITIONS
C AND LINEE TO LEFT EDGE VALUES
C FIX LEFT EDGE BY SUMMING ALL THE VALUES FOR A LENGTH LENGTH/2
C EITHER SIDE OF THE REAL SEQUENCE EDGE
DO 10 I=1,IDIM1
LINEE(I)=0
IM1 = I - 1
DO 9 J=1,LENGTH
K = IM1 + J
LINEE(I)=LINEE(I)+M(S1M(K),S2M(J))
9 CONTINUE
10 CONTINUE
C NOW DO TOP EDGE
DO 20 I=1,IDIM2
C SET UP POINTERS
LINEC(I)=0
IM1 = I - 1
DO 15 J=1,LENGTH
K = IM1 + J
LINEC(I)=LINEC(I)+M(S1M(J),S2M(K))
15 CONTINUE
20 CONTINUE
DO 21 I=1,IDIM2
LINEC(I)=LINEC(I+1)
21 CONTINUE
LINEC(IDIM2)=0
C MAIN LOOPS NOW
C LOOP FOR EACH ROW
C
DO 200 I=1,IDIM1
C SET LINEB TO LINEC, THEN ZERO LINEC
DO 110 J=1,IDIM2
LINEB(J+1)=LINEC(J)
LINEC(J)=0
110 CONTINUE
C SET LINEB(1) TO EDGE VALUE AS ITS OFF PAGE
LINEB(1)=LINEE(I)
C
C NOW COMPARE THIS CHAR OF SEQ1 WITH WHOLE OF SEQ2
TEMPP=S1P(I)
TEMPB=S1M(I)
DO 150 J=1,IDIM2
LINEC(J)=LINEB(J)+M(TEMPP,S2P(J))-M(TEMPB,S2M(J))
IF(LINEC(J).NE.0)THEN
IF(I.EQ.J)THEN
IF(SAME.NE.1)THEN
SCORE(LINEC(J)) = SCORE(LINEC(J)) + 1
END IF
ELSE
SCORE(LINEC(J)) = SCORE(LINEC(J)) + 1
END IF
END IF
150 CONTINUE
200 CONTINUE
C FIND MAX SCORE
IDSCOS=IDSCOR+1
DO 300 I=1,IDSCOR
J=IDSCOS-I
IF(SCORE(J).NE.0)THEN
C FOUND A NON ZERO SCORE. IT MUST BE LARGEST
MAX=J
GO TO 301
END IF
300 CONTINUE
301 CONTINUE
WRITE(KBOUT,1000)MAX
1000 FORMAT(' Maximum observed score is ',I6)
C CALC CUMULATIVE SCORE
DO 400 I=1,MAX-1
J=MAX-I
SCORE(J)=SCORE(J)+SCORE(J+1)
400 CONTINUE
ISQ=IDIM1*IDIM2
TOTPER=100./ISQ
C CALC PERCENT SCORES
DO 410 I=1,MAX
PERC(I)=SCORE(I)*TOTPER
410 CONTINUE
401 CONTINUE
533 CONTINUE
OPT = 1
590 CONTINUE
PROMPT(1) = 'Show percentage reaching a score'
PROMPT(2) = 'Show score for a percentage'
PROMPT(3) = 'List scores and percentages'
CALL RADION('Select score display mode',PROMPT,3,OPT,
+IHELPS,IHELPE,HELPF,IDEVH,KBIN,KBOUT)
IF(OPT.LT.1) RETURN
IF(OPT.EQ.2)GO TO 700
IF(OPT.EQ.3)GO TO 800
IF(OPT.NE.1)GO TO 590
MN = 1
ISCORE = 0.75 * MAX
CALL GETINT(MN,MAX,ISCORE,'Show percentage for score',
+IVAL,KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH,IOK)
IF(IOK.NE.0) RETURN
ISCORE = IVAL
WRITE(KBOUT,1008)ISCORE,PERC(ISCORE)
1008 FORMAT(' Percentage of points with score ',I6,' is ',F13.9)
GO TO 590
700 CONTINUE
XMN = 0.00001
XMX = 1.
PROB = 0.001
CALL GETRLS(XMN,XMX,PROB,'Show score for percentage',
+VAL,KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH,IOK)
IF(IOK.NE.0) RETURN
PROB = VAL
C LOOK FOR FIRST SCORE GIVING THIS PROBABILITY
DO 710 J=1,MAX+1
IF(PERC(J).GT.PROB)GO TO 710
WRITE(KBOUT,1012)PROB,J
1012 FORMAT(' Score for percentage ',F13.9,' is ',I5)
GO TO 590
710 CONTINUE
GO TO 590
800 CONTINUE
MN = 1
MX = 10
JSTEP = 5
CALL GETINT(MN,MX,JSTEP,'Number of steps between scores',
+IVAL,KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH,IOK)
IF(IOK.NE.0) RETURN
JSTEP = IVAL
C LIST
DO 420 I=1,MAX,JSTEP
IF(PERC(I).NE.100.)WRITE(IDEV,1005)I,SCORE(I),PERC(I)
1005 FORMAT(1X,I5,1X,I8,1X,E12.5)
420 CONTINUE
GO TO 590
END
SUBROUTINE DIALIN(ISXMAX,ISYMAX,MARGL,MARGR,MARGB,MARGT)
C AUTHOR: RODGER STADEN
XF=MARGL
XT=XF+MARGR
YF=MARGB
YT=YF+MARGT
XMIN=XF
XMAX=XT
YMIN=YF
YMAX=YT
CALL LINE(XF,XT,YF,YT,XMAX,XMIN,YMAX,YMIN,
1MARGL,MARGR,MARGB,MARGT,ISXMAX,ISYMAX)
CALL VT100M
RETURN
END
C SUBROUTINE TO WRITE 3 LINES OF SEQUENCES
C
SUBROUTINE FMT2(IDEV,SEQ1,SEQ2,IDIM,ISW,ISX)
C AUTHOR: RODGER STADEN
CHARACTER SEQ1(IDIM),SEQ2(IDIM),MATCH(60)
INTEGER KL(6)
C
C
ISXX=ISX
ISWW=ISW
IE=0
1 CONTINUE
C DO 100 I=1,100
C SET UP DECIMAL COUNTERS
DO 50 J=1,6
KL(J)=ISWW
ISWW=ISWW+10
50 CONTINUE
IS=IE+1
IE=IE+60
IF(IE.GT.IDIM)IE=IDIM
C COMPARE THE TWO SECTIONS OF SEQUENCE
IL=IE-IS+1
WRITE(IDEV,1001)'V',(KL(K),K=1,1+(IL-1)/10)
CALL SQMTCH(SEQ1(IS),SEQ2(IS),MATCH,IL)
WRITE(IDEV,1002)(SEQ1(K),K=IS,IE)
WRITE(IDEV,1002)(MATCH(K),K=1,IL)
WRITE(IDEV,1002)(SEQ2(K),K=IS,IE)
1002 FORMAT( 10X,6(10A1,1X))
C SET UP DECIMAL COUNTERS
DO 60 J=1,6
KL(J)=ISXX
ISXX=ISXX+10
60 CONTINUE
WRITE(IDEV,1001)'H',(KL(K),K=1,1+(IL-1)/10)
1001 FORMAT( ' ',A,' ',6(I5,6X))
C1001 FORMAT( 6X,6(I5,6X))
IF(IE.EQ.IDIM)RETURN
C100 CONTINUE
GO TO 1
END
C MOVEI
C MOVES INTEGER ARRAY CONTENTS LEFT OR RIGHT
SUBROUTINE MOVEI(SEQ,IDIMX,IDIM,IPOS,NCHAR1)
C AUTHOR: RODGER STADEN
INTEGER SEQ(IDIMX)
INTEGER TO,FROM
NCHAR=ABS(NCHAR1)
C LEFT OR RIGHT?
IF(NCHAR1.LT.0)GO TO 20
C RIGHT
FROM=IDIM
TO=IDIM+NCHAR
C NUMBER TO MOVE?
NUM=IDIM-IPOS+1
DO 10 I=1,NUM
SEQ(TO)=SEQ(FROM)
TO=TO-1
FROM=FROM-1
10 CONTINUE
RETURN
20 CONTINUE
C LEFT
FROM=IPOS+NCHAR
TO=IPOS
C NUMBER TO MOVE?
NUM=IDIM-FROM+1
DO 30 I=1,NUM
SEQ(TO)=SEQ(FROM)
TO=TO+1
FROM=FROM+1
30 CONTINUE
RETURN
END
SUBROUTINE FILEDG(SEQC,IDIMC,I1,I2,
+SEQN,IDIMN,SPAN,CHRSET,IDCHR,MSPO2,ISTART,IEND)
C AUTHOR: RODGER STADEN
C ROUTINE TO SORT OUT EDGES OF ACTIVE SEQUENCE:
C WE NOW COPY THE ACTIVE SEQUENCE INTO A TEMPORARY ARRAY
C FOR PROCESSING (ACTUALLY ALSO CONVERTING CHARS TO NUMBERS)
C AND WE NEED TO EITHER FILL UP THE EDGES WITH NULL CHARS
C OR, IF THERE IS REAL DATA AVAILABLE, WITH THAT
CHARACTER SEQC(IDIMC),CHRSET(IDCHR)
INTEGER SEQN(IDIMN),SPAN,SPANO2
INTEGER CTONUM
EXTERNAL CTONUM
C DO LEFT EDGE
C FILL WITH VALUES IDCHR FOR SPAN/2
C CALC ACTIVE SEQUENCE LENGTH
IDIMCA=I2-I1+1
SPANO2=SPAN/2
DO 1 I=MSPO2-SPANO2,MSPO2
1 SEQN(I)=IDCHR
C NOW PUT ANY IN REAL SEQ CHARACTERS AVAILABLE (IF I1>ISTART)
IF(I1.GT.ISTART)THEN
C NEED TO INSERT AT MOST SPAN/2 ELEMENTS
N=MIN(SPANO2+1,I1-ISTART)
C FIRST TO COPY?
J1=I1-1-ISTART+1
K1=MSPO2
DO 2 I=1,N
SEQN(K1)=CTONUM(SEQC(J1))
J1=J1-1
K1=K1-1
2 CONTINUE
END IF
C DO RIGHT EDGE
DO 3 I=MSPO2+IDIMCA+1,MSPO2+IDIMCA+SPANO2
3 SEQN(I)=IDCHR
IF(I2.LT.IEND)THEN
N=MIN(SPANO2,(IEND-I2))
J1=I2+1-ISTART+1
K1=MSPO2+1+IDIMCA
DO 4 I=1,N
SEQN(K1)=CTONUM(SEQC(J1))
J1=J1+1
K1=K1+1
4 CONTINUE
END IF
RETURN
END
SUBROUTINE QVORH(VHOUT,IHELPS,IHELPE,HELPF,IDEVH,KBIN,KBOUT,
+FILEH,FILEV)
C AUTHOR: RODGER STADEN
CHARACTER HELPF*(*),VHOUT,FILEH*(*),FILEV*(*)
PARAMETER (MAXPRM = 19)
CHARACTER PROMPT(2)*(MAXPRM)
PROMPT(1) = 'Horizontal sequence'
PROMPT(2) = 'Vertical sequence'
WRITE(KBOUT,1001)FILEH
1001 FORMAT(' Horizontal sequence is ',A)
WRITE(KBOUT,1002)FILEV
1002 FORMAT(' Vertical sequence is ',A)
VHOUT = ' '
I = 1
CALL RADION('Select sequence',PROMPT,2,I,
+IHELPS,IHELPE,HELPF,IDEVH,KBIN,KBOUT)
IF(I.LT.1) RETURN
IF(I.EQ.2) VHOUT = 'V'
IF(I.EQ.1) VHOUT = 'H'
END
SUBROUTINE CFSQ(SEQ1,IDIM1,SEQ2,IDIM2,POSN,WORDP,IDE,IDCHAR,
+CONSTS,LCONST,LENGTH,MINMAT,
+MARGXL,MARGXR,MARGYL,MARGYR,ISXMAX,ISYMAX,KBOUT,ISAME)
C 25-4-91 Fixed bug that allowed cfseq to extend off end of arrays
C by changing call to enconc from idim1 to idim1-minmat+1
C
C NOTE !!!!!!! this "fix" does NOT work well for short sequences:
C enconc only process 1 to idim-length+1 so if idim = idim1-minmat+1
C <= length-1 nothing gets hashed !!!!!!!!!! FIX IT sometime.
C should it be idim1-length+1 that gets sent to enconc ??
C
INTEGER SEQ1(IDIM1),SEQ2(IDIM2)
INTEGER POSN(IDIM1),WORDP(IDE),CONSTS(0:LCONST)
CALL BUSY(KBOUT)
CALL SETCN(CONSTS,LENGTH,IDCHAR,LCONST)
CALL ENCONC(SEQ1,IDIM1-MINMAT+1,POSN,WORDP,IDE,IDCHAR,
+CONSTS,LENGTH,LCONST)
CALL CFSEQ(SEQ1,IDIM1,POSN,WORDP,IDE,SEQ2,IDIM2,CONSTS,LCONST,
+LENGTH,IDCHAR,MINMAT,
+MARGXL,MARGXR,MARGYL,MARGYR,ISXMAX,ISYMAX,ISAME)
END
SUBROUTINE CFSEQ(SEQ1,IDIM1,POSN,WORDP,IDE,SEQ2,IDIM2,CONSTS,
+LCONST,
+LENGTH,IDCHAR,MINMAT,
+MARGXL,MARGXR,MARGYL,MARGYR,ISXMAX,ISYMAX,ISAME)
INTEGER SEQ1(IDIM1),SEQ2(IDIM2)
INTEGER POSN(IDIM1),WORDP(IDE),CONSTS(0:LCONST)
INTEGER NCODEA,EXTNDM
EXTERNAL NCODEA,EXTNDM
LEX = MINMAT - LENGTH
XMAX=IDIM2
XMIN=1.
YMAX=IDIM1
YMIN=1.
DO 20 I = 1,IDIM2-MINMAT+1
J = NCODEA(SEQ2(I),LENGTH,CONSTS,IDCHAR,LCONST)
IF(J.NE.0)THEN
J1 = WORDP(J)
IF(J1.NE.0)THEN
IF (((ISAME.EQ.1).AND.(I.NE.J1)).OR.(ISAME.EQ.0)) THEN
IMATCH = 0
IF(MINMAT.GT.LENGTH) IMATCH = EXTNDM(SEQ1(J1+LENGTH),
+ SEQ2(I+LENGTH),LEX)
IF(IMATCH.EQ.0)THEN
X=I
Y=J1
CALL POINT(X,Y,XMAX,XMIN,YMAX,YMIN,
+ MARGXL,MARGXR,MARGYL,MARGYR,ISXMAX,ISYMAX)
END IF
END IF
10 CONTINUE
J2 = J1
J1 = POSN(J2)
IF(J1.NE.0)THEN
IF (((ISAME.EQ.1).AND.(I.NE.J1)).OR.(ISAME.EQ.0)) THEN
IMATCH = 0
IF(MINMAT.GT.LENGTH) IMATCH = EXTNDM(SEQ1(J1+LENGTH),
+ SEQ2(I+LENGTH),LEX)
IF(IMATCH.EQ.0)THEN
X=I
Y=J1
CALL POINT(X,Y,XMAX,XMIN,YMAX,YMIN,
+ MARGXL,MARGXR,MARGYL,MARGYR,ISXMAX,ISYMAX)
END IF
END IF
GO TO 10
END IF
END IF
END IF
20 CONTINUE
END
INTEGER FUNCTION EXTNDM(SEQ1,SEQ2,LENGTH)
INTEGER SEQ1(LENGTH),SEQ2(LENGTH)
EXTNDM = 1
DO 10 I = 1,LENGTH
IF(SEQ1(I).NE.SEQ2(I))RETURN
10 CONTINUE
EXTNDM = 0
END
SUBROUTINE DSTAT(FILEH,ISH1,ISH2,FILEV,ISV1,ISV2,
+LENGTH,MINPRO,MINPER,KBOUT,ISAME,IMARK)
CHARACTER FILEH*(*),FILEV*(*)
WRITE(KBOUT,*)'Horizontal sequence'
WRITE(KBOUT,1023)FILEH
WRITE(KBOUT,10010)ISH1,ISH2
WRITE(KBOUT,*)'Vertical sequence'
WRITE(KBOUT,1023)FILEV
1023 FORMAT(' ',A)
WRITE(KBOUT,10010)ISV1,ISV2
10010 FORMAT(' Positions',/,' ',I6,' TO ',I6)
WRITE(KBOUT,10011)LENGTH
10011 FORMAT(' Span length=',I6)
WRITE(KBOUT,10014)
10014 FORMAT(' Scores')
WRITE(KBOUT,10012)MINPRO
10012 FORMAT(' Proportional=',I6)
WRITE(KBOUT,10013)MINPER
10013 FORMAT(' Identities=',I6)
IF(IMARK.EQ.1)THEN
WRITE(KBOUT,1001)
1001 FORMAT(' Identities on')
ELSE
WRITE(KBOUT,1002)
1002 FORMAT(' Identites off')
END IF
IF(ISAME.EQ.1)THEN
WRITE(KBOUT,1004)
1004 FORMAT(' Main diagonal blank')
ELSE
WRITE(KBOUT,1005)
1005 FORMAT(' Main diagonal shown')
END IF
END
C REDEFD
SUBROUTINE REDEFD(IDIMT,J1,J2,MAXSEQ,IDIMA,ISTART,IEND,IDIMB)
C AUTHOR RODGER STADEN
C DIAGON IS COMPLICATED BY HAVING SEVERAL ARRARY LIMITS
C THE SMALL MACHINE VERSION USES A DISK BUFFER
C ALL VERSIONS HAVE A CHUNK OF SEQUENCE IN RAM (ON THE LARGE MACHINE
C VERSION THIS WILL BE THE WHOLE SEQUENCE IF < MAXSEQ)
C ALL VERSIONS HAVE AN ACTIVE REGION FOR COMPARISON
C FOR ALL PROGRAMS OTHER THAN DIAGON THE ACTIVE REGION IS THE CHUNK IN THE
C RAM BUFFER, BUT FOR DIAGON IT MAY BE ONLY A PART OF THIS UP TO MAXCOM
C THIS CHUNK IS ALSO KEPT AS INTEGERS.
C THIS ROUTINE IS TO INITIALIZE THE ARRAY POINTERS AND SIZES
C MAXSEQ = THE DIMENSION OF THE RAM BUFFER SEQ
C IDIMT = THE ACTUAL SEQUENCE LENGTH (AND THEREFORE THE NUMBER OF ELEMENTS
C IN THE DISK BUFFER)
C ISTART = THE SEQUENCE NUMBER OF THE CHARACTER OCCUPYING SEQ(1)
C J1 = THE SEQUENCE NUMBER OF THE FIRST CHARACTER IN THE ACTIVE REGION
C J2 = THE SEQUENCE NUMBER OF THE LAST CHARACTER IN THE ACTIVE REGION
C IDIMA = J2-J1+1 I.E. THE NUMBER OF ELEMENTS IN THE ACTIVE REGION
C IEND = THE SEQUENCE NUMBER OF THE LAST ELEMENT OF SEQ
C IDIMB = IEND-ISTART+1 I.E. THE NUMBER OF ELEMENTS IN THE RAM BUFFER
K1 = 0
K2 = 0
IF(K1.EQ.0)K1=J1
K2MAX=MIN((K1+MAXSEQ-1),IDIMT)
IF(K2.GT.K2MAX)K2=K2MAX
IF(K2.EQ.0)K2=MIN(J2,K2MAX)
J1=K1
J2=K2
IDIMA=J2-J1+1
IDIMB=IEND-ISTART+1
END
SUBROUTINE MATTIN(MATRIX,IDM,FILNAM,FILEP,CHRSET,
+KBIN,KBOUT,IDEV,MATMAX,IHELPS,IHELPE,HELPF,IDEVH)
INTEGER MATRIX(IDM,IDM)
CHARACTER FILEP*(*),FILNAM*(*),CHRSET(IDM),HELPF*(*)
PARAMETER (MAXPRM = 20)
CHARACTER PROMPT(3)*(MAXPRM)
IN = 1
PROMPT(1) = 'Identity matrix'
PROMPT(2) = 'MDM78 matrix'
PROMPT(3) = 'Personal matrix file'
10 CONTINUE
CALL RADION('Select score matrix',PROMPT,3,IN,
+IHELPS,IHELPE,HELPF,IDEVH,KBIN,KBOUT)
IF(IN.LT.1) RETURN
IF(IN.EQ.1)THEN
C SET IDENTITIES
DO 15 I = 1,IDM
DO 15 J = 1,IDM
IF(I.EQ.J)THEN
MATRIX(I,J) = 1
ELSE
MATRIX(I,J) = 0
END IF
15 CONTINUE
ELSE IF(IN.EQ.2)THEN
C READ IN MDM78
CALL GETMAT(IDEV,FILEP,MATRIX,IDM,CHRSET,KBOUT,IOK)
IF(IOK.NE.0)GO TO 100
ELSE IF(IN.EQ.3)THEN
FILNAM = ' '
CALL OPENF1(IDEV,FILNAM,0,IOK,KBIN,KBOUT,
+ 'Matrix file name',
+ IHELPS,IHELPE,HELPF,IDEVH)
IF(IOK.NE.0)GO TO 10
CALL GETMAT(IDEV,FILNAM,MATRIX,IDM,CHRSET,KBOUT,IOK)
IF(IOK.NE.0)GO TO 100
ELSE
GO TO 10
END IF
C NEED TO KNOW LARGEST SCORE IN MATRIX FOR STATS
MATMAX=0
DO 20 I=1,IDM
DO 20 J=1,IDM
IF(MATMAX.LT.MATRIX(I,J))MATMAX=MATRIX(I,J)
20 CONTINUE
MATMAX=MATMAX+1
WRITE(KBOUT,1004)
1004 FORMAT(' Remember to reset the score for',/,
+ ' the proportional algorithm')
RETURN
100 CONTINUE
CALL ERROM(KBOUT,'Error in score matrix file')
GO TO 10
END
SUBROUTINE ALIGNM(SEQ1N,SEQ2N,IDIM1,IDIM2,CC,DD,RR,SS,SOP,
+NMAX,IV1,IH1,IDIMV,IDIMH,MAXSEQ,WTS,IDM,ISCORE,IG,IH,KBIN,
+KBOUT,IDEV,SEQ1,SEQ2,SEQ1A,SEQ2A,
+IHELPS,IHELPE,HELPF,IDEVH,KEEP,STACK,MAXSTK,STKREC,IOK)
INTEGER CC(0:NMAX+1),DD(0:NMAX+1),RR(0:NMAX+1),SS(0:NMAX+1)
INTEGER WTS(0:IDM,0:IDM),SOP(0:2*NMAX),R1,R2
INTEGER SEQ1N(NMAX),SEQ2N(NMAX),STKREC,STACK(0:MAXSTK)
CHARACTER SEQ1(MAXSEQ),SEQ2(MAXSEQ),SEQ1A(NMAX),SEQ2A(NMAX)
CHARACTER HELPF*(*),PAD
SAVE PAD
DATA PAD/','/
C
C 12-1-91 modified call to alignd to send nmax instead of maxseq
C
C MN = 1
C MX = NMAX
C WINDOW = NMAX
C CALL GETINT(MN,MX,WINDOW,'Window size',
C +IVAL,KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH,IOK)
C IF(IOK.NE.0) RETURN
C WINDOW = IVAL
C10 CONTINUE
CALL BUSY(KBOUT)
LW1 = MIN(IDIM1,NMAX)
LW2 = MIN(IDIM2,NMAX)
N = MAX(LW1,LW2)
CALL DIFF(SEQ1N,SEQ2N,LW1,LW2,
+CC,DD,RR,SS,SOP,N,
+WTS,IDM,ISCORE,IG,IH,KBOUT,STACK,MAXSTK,STKREC,IOK)
IF(IOK.NE.0) RETURN
CALL ALIGND(SEQ1(IV1),SEQ2(IH1),SOP,
+SEQ1A,SEQ2A,N,NMAX,R1,R2,PAD,NP1,NP2,IDIM1,IDIM2)
KPOUT = MAX(R1,R2)
PC = PCON(SEQ1A,SEQ2A,KPOUT,PAD)
CALL FMT2(IDEV,SEQ1A,SEQ2A,KPOUT,IV1,IH1)
WRITE(IDEV,1001)PC
1001 FORMAT(' Conservation ',F5.1,'%')
WRITE(IDEV,1002)NP1,NP2
1002 FORMAT(' Number of padding characters inserted',I6,' and',I6)
CALL YESNO(KEEP,'Keep alignment',
+IHELPS,IHELPE,HELPF,IDEVH,KBIN,KBOUT)
IF(KEEP.LT.0) RETURN
IF(KEEP.EQ.1) RETURN
NMOV = KPOUT - IDIM1
IV2 = IV1 + IDIM1
CALL MOVEC(SEQ1,MAXSEQ,IDIMV,IV2,NMOV)
IDIMV = IDIMV + NMOV
CALL SQCOPY(SEQ1A,SEQ1(IV1),KPOUT)
NMOV = KPOUT - IDIM2
IV2 = IH1 + IDIM2
CALL MOVEC(SEQ2,MAXSEQ,IDIMH,IV2,NMOV)
IDIMH = IDIMH + NMOV
CALL SQCOPY(SEQ2A,SEQ2(IH1),KPOUT)
END
SUBROUTINE ALIGND(SEQ1,SEQ2,S,SEQ1A,SEQ2A,NMAX,MAXSEQ,
+R1,R2,PAD,NP1,NP2,IDIM1,IDIM2)
CHARACTER SEQ1(MAXSEQ),SEQ2(MAXSEQ),SEQ1A(MAXSEQ),SEQ2A(MAXSEQ)
CHARACTER PAD
INTEGER S(0:2*NMAX),P1,P2,POUT,R1,R2
C 12-1-91 Added checks for pout going off end of array
C 6-6-91 Added another check!
P1 = 1
P2 = 1
NP1 = 0
NP2 = 0
POUT = 1
I = -1
10 CONTINUE
IF((P1.LE.IDIM1).AND.(P2.LE.IDIM2).AND.(POUT.LE.MAXSEQ)) THEN
I = I + 1
IF(S(I).EQ.0) THEN
C WRITE(*,*)P1,'=',P2,SEQ1(P1),SEQ2(P2)
SEQ1A(POUT) = SEQ1(P1)
SEQ2A(POUT) = SEQ2(P2)
P1 = P1 + 1
P2 = P2 + 1
POUT = POUT + 1
ELSE
IF(S(I).LT.0) THEN
K = ABS(S(I))
C WRITE(*,*)'INSERT ',K,' AT',P2
CALL SQCOPY(SEQ1(P1),SEQ1A(POUT),K)
CALL FILLC(SEQ2A(POUT),K,PAD)
NP2 = NP2 + K
P1 = P1 + K
POUT = POUT + K
ELSE
K = S(I)
C WRITE(*,*)'INSERT ',K,' AT',P1
CALL SQCOPY(SEQ2(P2),SEQ2A(POUT),K)
CALL FILLC(SEQ1A(POUT),K,PAD)
NP1 = NP1 + K
P2 = P2 + K
POUT = POUT + K
END IF
END IF
GO TO 10
END IF
R1 = POUT - 1
R2 = POUT - 1
J = 0
K = 0
IF((P1.LE.IDIM1).AND.(POUT.LE.MAXSEQ)) THEN
J = IDIM1 - P1 + 1
J = MIN(J,MAXSEQ-POUT+1)
CALL SQCOPY(SEQ1(P1),SEQ1A(POUT),J)
R1 = R1 + J
END IF
IF((P2.LE.IDIM2).AND.(POUT.LE.MAXSEQ)) THEN
K = IDIM2 - P2 + 1
K = MIN(K,MAXSEQ-POUT+1)
CALL SQCOPY(SEQ2(P2),SEQ2A(POUT),K)
R2 = R2 + K
END IF
I = R1 - R2
IF(I.GT.0) THEN
CALL FILLC(SEQ2A(POUT+K),I,PAD)
ELSE IF(I.LT.0) THEN
I = ABS(I)
CALL FILLC(SEQ1A(POUT+J),I,PAD)
END IF
END
REAL FUNCTION PCON(SEQ1,SEQ2,L,PAD)
CHARACTER SEQ1(L),SEQ2(L),PAD
INTEGER CTONUM
EXTERNAL CTONUM
N = 0
DO 10 I = 1,L
IF(SEQ1(I).EQ.PAD) SEQ1(I) = '-'
IF(SEQ2(I).EQ.PAD) SEQ2(I) = '-'
IF(CTONUM(SEQ1(I)).EQ.CTONUM(SEQ2(I))) N = N + 1
10 CONTINUE
PCON = 100. * REAL(N)/REAL(L)
END
SUBROUTINE DIFF(SA,SB,IDIM1,IDIM2,CC,DD,RR,SS,SOP,NMAX,
+W,IDM,SCORE,G,H,KBOUT,STACK,MAXSTK,STKREC,IOK)
IMPLICIT INTEGER(A-Z)
INTEGER CC(0:NMAX+1),DD(0:NMAX+1),RR(0:NMAX+1),SS(0:NMAX+1)
INTEGER W(0:IDM,0:IDM),SOP(0:2*NMAX),STACK(0:MAXSTK)
INTEGER SA(NMAX),SB(NMAX)
EXTERNAL GAP
IOK = 0
CALL FILLI(SOP,2*NMAX+1,0)
M = IDIM1
N = IDIM2
LM = G + H
LAST = 0
SAPP = 0
A = 1
B = 1
TB = G
TE = H
MIDI = 0
MIDJ = 0
MIDC = 0
TYPE = 0
C INITIALISE THE STACK WITH A PUSH
CALL STACKH(1,A,B,M,N,TB,TE,MIDI,MIDJ,TYPE,MIDC,990,
+STACK,MAXSTK,STKREC,IOK)
IF(IOK.NE.0) GO TO 999
90 CONTINUE
IF(N.LE.0)THEN
IF(M.GT.0) CALL DEL(M,LAST,SOP,NMAX,SAPP)
ANS = GAP(M,G,H)
GO TO 980
END IF
IF(M.LE.1) THEN
IF(M.LE.0) THEN
CALL INS(N,LAST,SOP,NMAX,SAPP)
ANS = GAP(N,G,H)
GO TO 980
END IF
IF(TB.GT.TE) TB = TE
MIDC = TB + H + GAP(N,G,H)
MIDJ = 0
ITP = B - 1
DO 100 J = 1,N
C = GAP(J-1,G,H) + W(SA(A),SB(J+ITP)) + GAP(N-J,G,H)
IF (C.LT.MIDC) THEN
MIDC = C
MIDJ = J
END IF
100 CONTINUE
IF(MIDJ.EQ.0)THEN
CALL INS(N,LAST,SOP,NMAX,SAPP)
CALL DEL(1,LAST,SOP,NMAX,SAPP)
ELSE
IF(MIDJ.GT.1) CALL INS(MIDJ-1,LAST,SOP,NMAX,SAPP)
CALL REP(LAST,SOP,NMAX,SAPP)
IF(MIDJ.LT.N) CALL INS(N-MIDJ,LAST,SOP,NMAX,SAPP)
END IF
ANS = MIDC
GO TO 980
END IF
MIDI = M/2
C FORWARD PHASE
CC(0) = 0
T = G
DO 200 J=1,N
T = T + H
CC(J) = T
DD(J) = T + G
200 CONTINUE
T = TB
JTP = B - 1
DO 400 I = 1,MIDI
S = CC(0)
T = T + H
C = T
CC(0) = C
E = T + G
ITP = I + A - 1
DO 300 J = 1,N
C = C + LM
E = E + H
IF(C.LT.E) E = C
C = CC(J) + LM
D = DD(J) + H
IF(C.LT.D) D = C
C = S + W(SA(ITP),SB(J+JTP))
IF(E.LT.C) C = E
IF(D.LT.C) C = D
S = CC(J)
CC(J) = C
DD(J) = D
300 CONTINUE
400 CONTINUE
DD(0) = CC(0)
C REVERSE PHASE
RR(N) = 0
T = G
DO 500 J =N-1,0,-1
T = T + H
RR(J) = T
SS(J) = T + G
500 CONTINUE
T = TE
DO 700 I=M-1,MIDI,-1
S = RR(N)
T = T + H
C = T
RR(N) = C
E = T + G
ITP = I + A
DO 600 J = N-1,0,-1
C = C + LM
E = E + H
IF(C.LT.E) E = C
C = RR(J) + LM
D = SS(J) + H
IF(C.LT.D) D = C
C = S + W(SA(ITP),SB(J+B))
IF(E.LT.C) C = E
IF(D.LT.C) C = D
S = RR(J)
RR(J) = C
SS(J) = D
600 CONTINUE
700 CONTINUE
SS(N) = RR(N)
C FIND OPTIMAL MIDPOINT
MIDC = CC(0) + RR(0)
MIDJ = 0
TYPE = 1
DO 800 J = 0,N
C = CC(J) + RR(J)
IF(C.LE.MIDC) THEN
IF((C.LT.MIDC).OR.(CC(J).NE.DD(J)).AND.(RR(J).EQ.SS(J)))THEN
MIDC = C
MIDJ = J
END IF
END IF
800 CONTINUE
DO 900 J = N,0,-1
C = DD(J) + SS(J) - G
IF(C.LT.MIDC) THEN
MIDC = C
MIDJ = J
TYPE = 2
END IF
900 CONTINUE
C CONQUER RECURSIVELY AROUND MIDPOINT
IF(TYPE.NE.1) GO TO 960
IF(TYPE.EQ.1) THEN
CALL STACKH(1,A,B,M,N,TB,TE,MIDI,MIDJ,TYPE,MIDC,950,
+STACK,MAXSTK,STKREC,IOK)
IF(IOK.NE.0) GO TO 999
M = MIDI
N = MIDJ
TE = G
GO TO 90
END IF
950 CONTINUE
CALL STACKH(1,A,B,M,N,TB,TE,MIDI,MIDJ,TYPE,MIDC,980,
+STACK,MAXSTK,STKREC,IOK)
IF(IOK.NE.0) GO TO 999
A = A + MIDI
B = B + MIDJ
M = M - MIDI
N = N - MIDJ
TB = G
GO TO 90
960 CONTINUE
CALL STACKH(1,A,B,M,N,TB,TE,MIDI,MIDJ,TYPE,MIDC,970,
+STACK,MAXSTK,STKREC,IOK)
IF(IOK.NE.0) GO TO 999
M = MIDI - 1
N = MIDJ
TE = 0
GO TO 90
970 CONTINUE
CALL DEL(2,LAST,SOP,NMAX,SAPP)
CALL STACKH(1,A,B,M,N,TB,TE,MIDI,MIDJ,TYPE,MIDC,980,
+STACK,MAXSTK,STKREC,IOK)
IF(IOK.NE.0) GO TO 999
A = A + MIDI + 1
B = B + MIDJ
M = M - MIDI - 1
N = N - MIDJ
TB = 0
GO TO 90
980 CONTINUE
SCORE = MIDC
CALL STACKH(2,A,B,M,N,TB,TE,MIDI,MIDJ,TYPE,MIDC,ADDR,
+STACK,MAXSTK,STKREC,IOK)
IF(IOK.NE.0) GO TO 999
IF(ADDR.EQ.950) GO TO 950
IF(ADDR.EQ.970) GO TO 970
IF(ADDR.EQ.980) GO TO 980
IF(ADDR.EQ.990) GO TO 990
WRITE(KBOUT,*)'Unexpected address in align'
IOK = 4
RETURN
999 CONTINUE
IF(IOK.EQ.1) THEN
WRITE(KBOUT,*)'Stack overflow'
ELSE IF(IOK.EQ.2) THEN
WRITE(KBOUT,*)'Stack underflow'
ELSE IF (IOK.EQ.3) THEN
WRITE(KBOUT,*)'Unexpected stack task'
END IF
990 CONTINUE
END
SUBROUTINE GETGAP(KBIN,KBOUT,IG,IH,
+IHELPS,IHELPE,HELPF,IDEVH,IDM,IOK)
CHARACTER HELPF*(*)
C FOR GAP OF LENGTH K, COST IS G + H*K
C WHERE G IS COST OF STARTING GAP, AND H IS ADDED FOR EACH ELEMENT IN GAP
C WRITE(KBOUT,*)'THE COST OF A GAP OF LENGTH K = G + H*K'
MN = 1
MX = 100
IG = 10
IF(IDM.EQ.5) IG = 20
CALL GETINT(MN,MX,IG,'Penalty for starting a gap',
+IVAL,KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH,IOK)
IF(IOK.NE.0) RETURN
IG = IVAL
MN = 1
MX = 100
IH = 10
IF(IDM.EQ.5) IH = 5
CALL GETINT(MN,MX,IH,'Penalty for each residue in gap',
+IVAL,KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH,IOK)
IF(IOK.NE.0) RETURN
IH = IVAL
END
INTEGER FUNCTION GAP(K,G,H)
INTEGER K,G,H
C NOTE FOR DES: HE HAS EQ HERE
IF(K.LE.0) THEN
GAP = 0
ELSE
GAP = G + H * K
END IF
END
SUBROUTINE DEL(K,LAST,S,NMAX,SAPP)
INTEGER S(0:NMAX*2),SAPP
IF(LAST.LT.0) THEN
S(SAPP-1) = S(SAPP-1) - K
LAST = -K
ELSE
S(SAPP) = -K
SAPP = SAPP + 1
LAST = -K
END IF
END
SUBROUTINE INS(K,LAST,S,NMAX,SAPP)
INTEGER S(0:NMAX*2),SAPP
IF (LAST.LT.0) THEN
S(SAPP-1) = K
S(SAPP) = LAST
C DES HAS NEXT LINE. I REMOVED IT 16-5-89
C LAST = K
SAPP = SAPP + 1
ELSE
S(SAPP) = K
SAPP = SAPP + 1
LAST = K
END IF
END
SUBROUTINE REP(LAST,S,NMAX,SAPP)
INTEGER S(0:NMAX*2),SAPP
S(SAPP) = 0
SAPP = SAPP + 1
LAST = 0
END
SUBROUTINE STACKH(JOB,A,B,M,N,TB,TE,MIDI,MIDJ,TYPE,MIDC,ADDR,
+STACK,MAXSTK,STKREC,IOK)
IMPLICIT INTEGER (A-Z)
INTEGER STACK(0:MAXSTK)
SAVE
DATA SP/-1/
C HANDLE STACK: 1 = PUSH, 2 = POP
IF(JOB.EQ.1) THEN
SP = SP + STKREC
IF(SP.GT.MAXSTK) THEN
C WRITE(*,*)'HELP, STACK OVERFLOW'
IOK = 1
RETURN
END IF
STACK(SP-10) = A
STACK(SP-9) = B
STACK(SP-8) = M
STACK(SP-7) = N
STACK(SP-6) = TB
STACK(SP-5) = TE
STACK(SP-4) = MIDI
STACK(SP-3) = MIDJ
STACK(SP-2) = TYPE
STACK(SP-1) = MIDC
STACK(SP) = ADDR
ELSE IF(JOB.EQ.2) THEN
SP = SP - STKREC
IF(SP.LT.-1) THEN
C WRITE(*,*)'HELP, STACK UNDERFLOW'
IOK = 2
RETURN
END IF
A = STACK(SP+1)
B = STACK(SP+2)
M = STACK(SP+3)
N = STACK(SP+4)
TB = STACK(SP+5)
TE = STACK(SP+6)
MIDI = STACK(SP+7)
MIDJ = STACK(SP+8)
TYPE = STACK(SP+9)
MIDC = STACK(SP+10)
ADDR = STACK(SP+11)
ELSE
C WRITE(*,*)'HELP, STACK COCKUP'
IOK = 3
C STOP
END IF
END
SUBROUTINE PAMDIS(MATRIX,WTS,IDM)
INTEGER MATRIX(IDM,IDM),WTS(0:IDM,0:IDM)
IF(IDM.EQ.26) THEN
N = 8
M = 0
DO 10 I = 1,IDM
DO 5 J = 1,IDM
K = MATRIX(I,J)
M = MAX(M,K)
5 CONTINUE
10 CONTINUE
DO 20 I = 1,IDM
DO 15 J = 1,IDM
K = M - MATRIX(I,J)
WTS(I,J) = K
15 CONTINUE
20 CONTINUE
DO 30 I = 0,IDM
WTS(I,0) = N
WTS(0,I) = N
30 CONTINUE
RETURN
END IF
DO 40 I = 1,IDM
DO 40 J = 1,IDM
IF(I.EQ.J) THEN
WTS(I,J) = 0
ELSE
WTS(I,J) = 20
END IF
40 CONTINUE
DO 50 I = 0,IDM
WTS(I,0) = 10
WTS(0,I) = 10
50 CONTINUE
END
SUBROUTINE ENCONC(SEQ,IDIM,POSN,WORDP,IDE,IDCHAR,CONSTS,LENGTH,
+LCONST)
C AUTHOR RODGER STADEN
INTEGER SEQ(IDIM)
INTEGER POSN(IDIM),WORDP(IDE),CONSTS(0:LCONST)
INTEGER NCODEA
EXTERNAL NCODEA
C ENCODES A SEQUENCE OF LENGTH IDIM AND CHARACTERSET SIZE IDCHAR
C INTO TWO ARRAYS: WORDP(I) CONTAINS THE POSITION OF THE FIRST OCCURRENCE
C OF WORD(I), POSN(I) CONTAINS A LINKED LIST OF SECOND, THIRD,... OCCURENCES
C OF WORD
CALL FILLI(POSN,IDIM,0)
CALL FILLI(WORDP,IDE,0)
DO 20 I = 1, IDIM-LENGTH+1
J = NCODEA(SEQ(I),LENGTH,CONSTS,IDCHAR,LCONST)
IF(J.NE.0)THEN
J1 = WORDP(J)
IF(J1.EQ.0)THEN
WORDP(J) = I
ELSE
10 CONTINUE
J2 = J1
J1 = POSN(J2)
IF(J1.NE.0) GO TO 10
POSN(J2) = I
END IF
END IF
20 CONTINUE
END
SUBROUTINE QICKS(SEQ1,IDIM1,POSN,WORDP,IDE,SEQ2,IDIM2,CONSTS,
+LENGTH,IDM,LCONST,HIST,MAXSEQ,MATRIX,SEQS,MAIND,
+MARGL,MARGR,MARGB,MARGT,ISXMAX,ISYMAX,SPAN,MINPRO,KBOUT,RNSD,
+ISAME)
INTEGER SEQ1(IDIM1),SEQ2(IDIM2),SEQS(IDIM1),SPAN
INTEGER POSN(IDIM1),WORDP(IDE),CONSTS(0:LCONST)
INTEGER MAIND(IDM)
INTEGER HIST(-MAXSEQ:MAXSEQ)
PARAMETER (MAXDIA = 20)
INTEGER TOPD(MAXDIA),TOPI(MAXDIA),TOPJ(MAXDIA),MATRIX(IDM,IDM)
EXTERNAL NCODEA
NDIAG = MAXDIA
CALL BUSY(KBOUT)
CALL FILLI(HIST(-IDIM1),IDIM2+IDIM1+1,0)
CALL SETCN(CONSTS,LENGTH,IDM,LCONST)
C WRITE(*,*)'CONSTS'
C WRITE(*,*)CONSTS
CALL ENCONC(SEQ1,IDIM1,POSN,WORDP,IDE,IDM,CONSTS,LENGTH,
+LCONST)
DO 4 I = 1,IDM
MAIND(I) = MATRIX(I,I)
4 CONTINUE
C WRITE(*,*)'MAIND'
C WRITE(*,*)MAIND
CALL WDSCR(SEQ1,SEQS,IDIM1,LENGTH,MAIND,IDM)
C WRITE(*,*)'SEQS'
C WRITE(*,*)(SEQS(K),K=1,30)
C WRITE(*,*)'SEQ1'
C WRITE(*,*)(SEQ1(K),K=1,30)
C WRITE(*,*)IDIM1,IDIM2,LENGTH
DO 20 I = 1,IDIM2-LENGTH+1
J = NCODEA(SEQ2(I),LENGTH,CONSTS,IDM,LCONST)
IF(J.NE.0)THEN
J1 = WORDP(J)
IF(J1.NE.0)THEN
K = I - J1
C FOR IDENTITIES ADD 1 ON NEXT LINE (NOT SEQS)
HIST(K) = HIST(K) + SEQS(J1)
10 CONTINUE
J2 = J1
J1 = POSN(J2)
IF(J1.NE.0)THEN
K = I - J1
C FOR IDENTITIES ADD 1 ON NEXT LINE (NOT SEQS)
HIST(K) = HIST(K) + SEQS(J1)
GO TO 10
END IF
END IF
END IF
20 CONTINUE
IF (ISAME.EQ.1) HIST(0) = 0
CALL MHIST(HIST,IDIM1,IDIM2,TOPD,TOPI,TOPJ,
+NDIAG,MAXSEQ,RNSD)
IF(NDIAG.EQ.0) THEN
WRITE(KBOUT,*)' No diagonals found scoring',RNSD,
+ ' sd above mean'
RETURN
END IF
ISPO2 = SPAN/2
XMIN = 1.
XMAX = IDIM2
YMIN = 1.
YMAX = IDIM1
CALL VECTOM
DO 40 I = 1,NDIAG
IF(TOPD(I).NE.0) THEN
L = MIN(IDIM1-TOPJ(I),IDIM2-TOPI(I)) + 1
CALL DSCORP(SEQ1(TOPJ(I)),SEQ2(TOPI(I)),L,MATRIX,IDM,
+ SPAN,MINPRO,ISPO2,TOPJ(I),TOPI(I),
+XMAX,XMIN,YMAX,YMIN,MARGL,MARGR,MARGB,MARGT,ISXMAX,ISYMAX)
END IF
40 CONTINUE
CALL VT100M
END
SUBROUTINE DSCORP(SEQ1,SEQ2,L,MATRIX,IDM,SPAN,MINSCR,SPO2,JS,IS,
+XMAX,XMIN,YMAX,YMIN,MARGL,MARGR,MARGB,MARGT,ISXMAX,ISYMAX)
INTEGER SEQ1(L),SEQ2(L),MATRIX(IDM,IDM),SPAN,FRONT,BACK,SPO2
C 8-6-91 Fixed bug that allowed span>L
M = 0
FRONT = SPAN
BACK = 0
DO 10 I = 1,MIN(SPAN,L)
M = M + MATRIX(SEQ1(I),SEQ2(I))
10 CONTINUE
IF(M.GE.MINSCR) THEN
Y = JS + SPO2
X = IS + SPO2
C WRITE(*,*)IX,IY
CALL POINT(X,Y,XMAX,XMIN,YMAX,YMIN,
+ MARGL,MARGR,MARGB,MARGT,ISXMAX,ISYMAX)
END IF
DO 20 I = 2,L-SPAN+1
FRONT = FRONT + 1
BACK = BACK + 1
MM = MATRIX(SEQ1(BACK),SEQ2(BACK))
MP = MATRIX(SEQ1(FRONT),SEQ2(FRONT))
M = M - MM + MP
IF(M.GE.MINSCR) THEN
Y = JS + BACK + SPO2
X = IS + BACK + SPO2
C WRITE(*,*)IX,IY
CALL POINT(X,Y,XMAX,XMIN,YMAX,YMIN,
+ MARGL,MARGR,MARGB,MARGT,ISXMAX,ISYMAX)
END IF
20 CONTINUE
END
SUBROUTINE MHIST(HIST,IDIM1,IDIM2,TOPD,TOPI,TOPJ,NDIAG,
+ MAXSEQ,RNSD)
INTEGER HIST(-MAXSEQ:MAXSEQ),TOPD(NDIAG),TOPI(NDIAG),TOPJ(NDIAG)
C ANALYSE HISTOGRAM TO FIND BEST NDIAG DIAGONALS
C LOOK AT THE TOP TEN SCORES, TOP DOWN
C IF ELEMENT I > TOP(J) THEN MOVE J+1 TO NDIAG-1 DOWN
C PUT I AT TOP(J)
C DIAGO FINDS THE INTERSECTION OF DIAGONAL I ON THE 2 AXES
C FIRST FIND THE TOP SCORES AND THERE HIST ELEMENT NO
C THEN GET THEIR AXES INTERSECTIONS
IDIAG = 0
CALL FILLI(TOPD,NDIAG,0)
CALL FILLI(TOPI,NDIAG,0)
CALL FILLI(TOPJ,NDIAG,0)
RMSQ = 0.
RM = 0.
DO 20 I = -IDIM1,IDIM2
RJ = HIST(I)
RM = RM + RJ
RMSQ = RMSQ + RJ * RJ
20 CONTINUE
N = IDIM1 + IDIM2
RM = RM / N
RMSQ = RMSQ / N
RM2 = RM * RM
SD = 0.
T = RMSQ - RM2
IF(T.GT.0.) SD = SQRT(T)
MINS = NINT(RM + RNSD * SD)
C TRY TO FIND HIGHEST SCORES FIRST
DO 100 I = 0,IDIM2
M = HIST(I)
IF(M.GT.MINS) THEN
IDIAG = IDIAG + 1
IF(M.GT.TOPD(NDIAG)) THEN
DO 50 J = 1,NDIAG
IF(M.GT.TOPD(J)) THEN
DO 40 K = NDIAG-1,J,-1
TOPD(K+1) = TOPD(K)
TOPI(K+1) = TOPI(K)
40 CONTINUE
TOPD(J) = M
TOPI(J) = I
GO TO 60
END IF
50 CONTINUE
END IF
END IF
60 CONTINUE
100 CONTINUE
DO 200 I = -1,-IDIM1,-1
M = HIST(I)
IF(M.GT.MINS) THEN
IDIAG = IDIAG + 1
IF(M.GT.TOPD(NDIAG)) THEN
DO 150 J = 1,NDIAG
IF(M.GT.TOPD(J)) THEN
DO 140 K = NDIAG-1,J,-1
TOPD(K+1) = TOPD(K)
TOPI(K+1) = TOPI(K)
140 CONTINUE
TOPD(J) = M
TOPI(J) = I
GO TO 160
END IF
150 CONTINUE
END IF
END IF
160 CONTINUE
200 CONTINUE
NDIAG = MIN(IDIAG,NDIAG)
DO 300 I = 1,NDIAG
J = TOPI(I)
CALL DIAGO(J,TOPI(I),TOPJ(I))
300 CONTINUE
END
SUBROUTINE DIAGO(I,II,JJ)
IF(I.GE.0) THEN
JJ = 1
II = I + 1
ELSE
II = 1
JJ = ABS(I) + 1
END IF
END
SUBROUTINE WDSCR(SEQ1N,SEQS,IDIM1,KTUP,MAIND,IDM)
INTEGER SEQ1N(IDIM1),SEQS(IDIM1),MAIND(IDM)
DO 10 I =1,IDIM1-KTUP+1
K = 0
DO 5 J = I,I+KTUP-1
K = K + MAIND(SEQ1N(J))
5 CONTINUE
SEQS(I) = K
10 CONTINUE
END
SUBROUTINE DP21(MATMAX,AVSCOR,LENGTH,MINPRO,
+KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH,IOK)
CHARACTER HELPF*(*)
MN = 1
MX = MAX(1,MATMAX-1) * LENGTH
MINPRO = INT(AVSCOR*LENGTH)
CALL GETINT(MN,MX,MINPRO,'Proportional score',
+ IVAL,KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH,IOK)
IF(IOK.EQ.0) MINPRO = IVAL
END
SUBROUTINE DP22(IDM,MINPER,
+KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH,IOK)
CHARACTER HELPF*(*)
MN = 1
IF(IDM.EQ.5) THEN
MX = 100
ELSE
MX = 20
END IF
CALL GETINT(MN,MX,MINPER,'Identity score',
+ IVAL,KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH,IOK)
IF(IOK.EQ.0) MINPER = IVAL
END
SUBROUTINE DP20(LENGTH,MXSPAN,IDIMVA,IDIMHA,IDIMVP,IDIMHP,
+NOROO,NOROE,MAXSEQ,
+SEQVC,IDIMBV,ISV1,ISV2,SEQV,MXCOMP,
+CHRSET,IDM,MSPO2,ISTARV,IENDV,
+SEQHC,IDIMBH,ISH1,ISH2,SEQH,
+ISTARH,IENDH,LB,LF,
+KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH,IOK)
CHARACTER HELPF*(*),NOROO,NOROE,CHRSET(IDM)
CHARACTER SEQHC(MAXSEQ),SEQVC(MAXSEQ)
INTEGER SEQH(MXCOMP),SEQV(MXCOMP)
LTEMP=LENGTH
5 CONTINUE
MN = 1
MX = MIN(MXSPAN,MIN(IDIMVA,IDIMHA))
CALL GETINT(MN,MX,LENGTH,'Odd span length',
+ IVAL,KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH,IOK)
IF(IOK.NE.0) RETURN
IF(MOD(IVAL,2).NE.1)GO TO 5
LENGTH = IVAL
LB=(LENGTH+1)/2
LF=LENGTH/2
IDIMVP=IDIMVA+LENGTH
IDIMHP=IDIMHA+LENGTH
NOROO='N'
NOROE='N'
C IF LENGTH LONGER THAN BEFORE EXTEND INTEGER BUFFERS
IF(LTEMP.LT.LENGTH)THEN
CALL FILEDG(SEQVC,IDIMBV,ISV1,ISV2,SEQV,MXCOMP,LENGTH,
+ CHRSET,IDM,MSPO2,ISTARV,IENDV)
CALL FILEDG(SEQHC,IDIMBH,ISH1,ISH2,SEQH,MXCOMP,LENGTH,
+ CHRSET,IDM,MSPO2,ISTARH,IENDH)
END IF
END
SUBROUTINE DP33(RNSD,
+KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH,IOK)
CHARACTER HELPF*(*)
RMN = 0.
RMX = 10.
CALL GETRL(RMN,RMX,RNSD,'Number of sd above mean',
+ RVAL,KBIN,KBOUT,IHELPS,IHELPE,HELPF,IDEVH,IOK)
IF(IOK.EQ.0) RNSD = RVAL
END
SUBROUTINE CFSQL(SEQ1,IDIM1,SEQ2,IDIM2,POSN,WORDP,IDE,IDCHAR,
+CONSTS,LCONST,LENGTH,MINMAT,IDEV,KBOUT,ISAME,SEQ,HIST,MAXSEQ)
INTEGER SEQ1(IDIM1),SEQ2(IDIM2),HIST(-MAXSEQ:MAXSEQ)
INTEGER POSN(IDIM1),WORDP(IDE),CONSTS(0:LCONST)
CHARACTER SEQ(IDIM1)
CALL BUSY(KBOUT)
CALL SETCN(CONSTS,LENGTH,IDCHAR,LCONST)
CALL ENCONC(SEQ1,IDIM1-MINMAT+1,POSN,WORDP,IDE,IDCHAR,
+CONSTS,LENGTH,LCONST)
CALL CFSEQL(SEQ1,IDIM1,POSN,WORDP,IDE,SEQ2,IDIM2,CONSTS,LCONST,
+LENGTH,IDCHAR,MINMAT,IDEV,ISAME,SEQ,HIST,MAXSEQ)
END
SUBROUTINE CFSEQL(SEQ1,IDIM1,POSN,WORDP,IDE,SEQ2,IDIM2,CONSTS,
+LCONST,
+LENGTH,IDCHAR,MINMAT,IDEV,ISAME,SEQ,HIST,MAXSEQ)
INTEGER SEQ1(IDIM1),SEQ2(IDIM2)
INTEGER POSN(IDIM1),WORDP(IDE),CONSTS(0:LCONST)
INTEGER NCODEA,EXTNDN
INTEGER HIST(-MAXSEQ:MAXSEQ)
CHARACTER SEQ(IDIM1)
EXTERNAL NCODEA,EXTNDN
LEX = MINMAT - LENGTH - 1
C
C if we are looking for internal repeats we switch off half the matrix
C by making the saved score high
C
IF (ISAME.EQ.1) THEN
CALL FILLI(HIST(-IDIM1),IDIM1,IDIM1+IDIM2)
CALL FILLI(HIST(0),IDIM2,0)
ELSE
CALL FILLI(HIST(-IDIM1),IDIM1+IDIM2+1,0)
END IF
DO 20 I = 1,IDIM2-MINMAT+1
J = NCODEA(SEQ2(I),LENGTH,CONSTS,IDCHAR,LCONST)
IF(J.NE.0)THEN
J1 = WORDP(J)
IF(J1.NE.0)THEN
IF (((ISAME.EQ.1).AND.(I.NE.J1)).OR.(ISAME.EQ.0)) THEN
LT = 1 + MIN(IDIM1-(J1+LENGTH),IDIM2-(I+LENGTH))
IMATCH = EXTNDN(SEQ1(J1+LENGTH),SEQ2(I+LENGTH),LT)
IF(IMATCH.GT.LEX)THEN
L = I + IMATCH + LENGTH
K = I - J1
C
C if this match ends furthest away we display it and save it
C
IF (HIST(K).LT.L) THEN
HIST(K) = L
WRITE(IDEV,1000)I,J1,IMATCH+LENGTH
1000 FORMAT(' Positions',I7,'h',I7,'v and length',I7)
WRITE(IDEV,1001)(SEQ(K),K=J1,J1+IMATCH+LENGTH-1)
1001 FORMAT(' ',50A1)
END IF
END IF
END IF
10 CONTINUE
J2 = J1
J1 = POSN(J2)
IF(J1.NE.0)THEN
IF (((ISAME.EQ.1).AND.(I.NE.J1)).OR.(ISAME.EQ.0)) THEN
LT = 1 + MIN(IDIM1-(J1+LENGTH),IDIM2-(I+LENGTH))
IMATCH = EXTNDN(SEQ1(J1+LENGTH),SEQ2(I+LENGTH),LT)
IF(IMATCH.GT.LEX)THEN
L = I + IMATCH + LENGTH
K = I - J1
IF (HIST(K).LT.L) THEN
HIST(K) = L
WRITE(IDEV,1000)I,J1,IMATCH+LENGTH
WRITE(IDEV,1001)(SEQ(K),K=J1,J1+IMATCH+LENGTH-1)
END IF
END IF
END IF
GO TO 10
END IF
END IF
END IF
20 CONTINUE
END
INTEGER FUNCTION EXTNDN(SEQ1,SEQ2,LENGTH)
INTEGER SEQ1(LENGTH),SEQ2(LENGTH)
DO 10 I = 1,LENGTH
IF(SEQ1(I).NE.SEQ2(I)) THEN
EXTNDN = I - 1
RETURN
END IF
10 CONTINUE
EXTNDN = LENGTH
END