2199 lines
63 KiB
Fortran
2199 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
|