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, IDIMHISTART) 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