X-Delivery-Notice:  SMTP MAIL FROM does not correspond to sender.
Return-Path: <BAILEY@hmivax.humgen.upenn.edu>
X-Envelope-To: tolvanen@KLAAVA.HELSINKI.FI, Info-GCG@UTORONTO.BITNET
X-Vms-To: IN%"tolvanen@KLAAVA.HELSINKI.FI"
X-Vms-Cc: IN%"Info-GCG@UTORONTO.BITNET",BAILEY
Newsgroups: bit.listserv.info-gcg
Date:         Fri, 20 Nov 1992 19:25:00 EST
Reply-To:     Charles Bailey <BAILEY@HMIVAX.HUMGEN.UPENN.EDU>
              <INFO-GCG@UTORONTO.BITNET>
From:         Charles Bailey <BAILEY@HMIVAX.HUMGEN.UPENN.EDU>
Subject:      Re: PIR format
Comments: To: tolvanen@KLAAVA.HELSINKI.FI

Martti Tolvanen writes:
>How should I go about reformatting a sequence fetched from the PIR
>server for GCG use, since FROMPIR (UNIX version 7.0 of GCG) doesn't
>recognize the current PIR/NBRF format.  The recognized one (from
>GENHELP):
>
>[Format examples deleted.]
>
>I know I could strip off the numbering from the sequence by hand, add
>the two dots in the start of the sequence data and use REFORMAT, but I
>need reformatting for about 100 sequences, and I thought there could be
>an easier way.

The format is much like GenBank, as Christoph Gartmann noted, but is just
different enough to fool the GCG conversion utilities.  I've appended to this
message a quick hack to FromPIR which adds a qualifier /New to handle the new
PIR format.  It worked on the sample given in the original message, running
under VMS 5.4, VAX FORTRAN, and GCG 7.1 (though I don't think there's been any
changes in the procedures used since 7.0).  If anyone knows more about the PIR
format and can point out bugs in the new code, I'd e happy to hear about them.
Elegance will have to await free time.

Sorry for the length of this message.  I can't think of distribution method
besides mail which is certain to reach people, and the context diff of this
version vs. the original is 75% as long as the program itself - not much of a
savings.  If anyone's copy gets munged by a mailer, or if they need a compiled
version, they can pick source or image up by anonymous ftp (host
genetics.upenn.edu, directory anon_root:[util.gcg]), or I can arrange to send
source or UUEncoded image in several parts.   I hope this is useful to people.
[Aside to GCG folks:  Do you feel that this infirnges you copyright on the
original version?  Would you rather I only made diffs available?]

					Charles Bailey

!-------------------------------------------------------------------------------
!             Dept. of Genetics / Howard Hughes Medical Institute
! University of Pennsylvania School of Medicine  Rm. 430 Clinical Research Bldg.
!     422 Curie Blvd.  Philadelphia, PA 19104 USA      Tel. (215) 898-1699
!          Internet: bailey@genetics.upenn.edu  (IN 128.91.200.37)
!-------------------------------------------------------------------------------

!***  FromPIR  ********************************************************
!*
!*	converts PIR Protein Sequence Database files into individual
!*	files in GCG format.
!*
!*				Copyright John Devereux,  June 1984
!*				Revised			  August 1985
!*
!*	Revised September 1988 by Irv Edelman to read new PIR Protein
!*	Sequence Database format.
!*
!*  Revised 20-NOV-1992 to read PIR mailserver format, when qualifier /New
!*  is present on CL.  Charles Bailey  bailey@genetics.upenn.edu
!*
!******************************************************************************

	Program FromPIR

	Implicit None
	Include 'GenInclude:Sequence.inc'

	Record /Sequence/ SQ

	Character InFName(256), OutFName(256)
	Character OutLine(512), Directory(132), Extension(132), Delim(8)
	Integer InFile, OutFile, Pos
	Logical Card, Monitor, Summary, Dummy, New
	Integer Tot, Files

	Logical ReadToHeader, ReOpenF
	Integer GetString
	Logical CLGetOldFName, CLNoInteract

	Call Doc('GenRunDoc:FromPIR.Txt')
	Call CLComCheck('GenRunDoc:FromPIR.Cmd')

	Call StrCopy(Extension, '.Gcg')
	Call CLGetStr('EXTension', Extension)
	Call CLGetStr('DIRectory', Directory)
	Call CLGetBool('CARd', Card)
	Call CLGetBool('New', New)
	Monitor = .not.CLNoInteract()
	Summary = Monitor
	Call CLGetBool('MONitor', Monitor)
	Call CLGetBool('SUMmary', Summary)

! identify the "flat" PIR input file

        If ( .not.CLGetOldFName('INfile', 1, InFName)  ) Then
          If ( .not.CLNoInteract() ) then
	    Call WriteF('\n FROMPIR of what PIR sequence file ?  ')
	    If ( GetString(InFName).eq.0 ) Stop ' '
	  End If
        End If

	If ( InFName(1).eq.Char(0) ) Call WriteF('\n\b *** ERROR, '//
     &	  ' FROMPIR requires an input file! ***\n\s')
	Call OpenFile(InFile, InFName, 'r')

! now make individual Files out of each PIR entry

	If (New) Then
	  Call StrCopy(Delim,'ENTRY')
	Else
	  Call StrCopy(Delim,'>')
	EndIf
	Do While ( ReadToHeader(InFile, OutLine, Delim) )
	  If (New) Then
	    Call StrToken(OutFName,OutLine,Pos)
	    Call StrToken(OutFName,OutLine,Pos)
	  Else
	    Call StrCopy(OutFName, OutLine(5) )
	    OutFName(7) = Char(0)
	  EndIf
	  Call VaxName(OutFName)
	  Call NewFileType(OutFName, Extension)
	  Call ReDirectFile(Directory, OutFName)
	  If ( ReOpenF(OutFile, OutFName, 'w') ) then
	    Call SQClear(SQ)
	    If ( Card ) then
	      Call CardCopyToSeq(InFile, OutFile, OutLine)
	      Call CardReadPIRSeq(InFile, OutLine, SQ.Seq, SQ.Len)
	    Else
	      If (New) Then
            ! Write out the ENTRY line we picked up before
	        Call WriteLongString(OutFile,OutLine)
	        Call NewHeaderCopy(InFile,OutFile,OutLine,Sq.Seq,SQ.Len)
	      Else
	        Call HeaderCopy(InFile, OutFile, OutLine, SQ.Seq,SQ.Len)
	      EndIf
	    End If
	    Call FWriteF(OutFile, '\n')

	    Call StrCopy(SQ.Name, OutFName)
	    Call BaseName(SQ.Name)
	    Call SQWrite(OutFile, SQ)

	    Tot = Tot + SQ.Len
	    Files = Files + 1
	    If ( Monitor ) Call WriteF('\n %15.2n %5D aa',
     &	      OutFile, SQ.Len)
	    If ( SQ.Len.gt.MAXSEQLEN ) Call WriteF('\b\n\n'//
     &	      ' "%.2n" is too long for the GCG Package!!!\b\n', OutFile)
	  End If
	End Do

	If ( Summary ) then
	  Call WriteF('\n\n'//

     &	    ' FROMPIR complete:\n\n'//

     &	    '     Files written: %6D\n'//
     &      '      Total length: %6D\n\n',

     &	    Files, Tot)
	End If

	Call Account('FromPIR')

	End ! of FromPIR

!***  ReadToHeader  ***************************************************
!*
!*	reads down in file to a line whose first token is Token
!*	and returns that line in OutLine.  ReadToIDLine returns false
!*	if the end of file is read without an id line
!*
!******************************************************************************

	Logical Function ReadToHeader(File, OutLine, Token)

	Implicit None

	Integer File
	Character OutLine(*), Token(*)

	Integer Length, StrFind

	Do While ( (StrFind(Token,OutLine).eq.0) .and. Length.ge.0 )
	   Call ReadString(File, OutLine ,Length)
	End Do

	ReadToHeader = Length.gt.0

	Return
	End ! of ReadToHeader

!***  CardCopyToSeq  *************************************************
!*
!*	copy the InFile to the OutFile until a line with an 'S' in the
!*	74th column is read.
!*
!******************************************************************************

	Subroutine CardCopyToSeq(InFile, OutFile, OutLine)

	Implicit None

	Integer InFile, OutFile
	Character OutLine(*)

	Integer Length

	Length = 1
	Do while ( Length.ge.0 .and. OutLine(74).ne.'S' )
	   OutLine(76) = Char(0)
	   Call StrAerate(OutLine)               ! eliminate any '..'
	   Call WriteString(OutFile, OutLine)
	   Call ReadString(InFile, OutLine, Length)
	End Do

	If ( Length.lt.0 ) then
	  Call RingBell(1)
	  Call WriteF('\n\n *** End of file during a heading copy! ***')
	  Stop ' '
	End If

	Return
	End ! of CardCopyToSeq

!***  CardReadPIRSeq   **********************************************
!*
!*	reads the legal GCG sequence characters for the PIR data
!*	file until a lines does not have an 'S' at column 74.
!*
!******************************************************************************

	Subroutine CardReadPIRSeq(InFile, String, Strand, SeqLength)

	Implicit None

	Integer InFile
	Character String(*), Strand(*)
	integer SeqLength

	Integer I, J, Length, calls/1/, Str_Len
	Character Symbols(0:255), Null, OneChar
	Parameter ( Null = Char(0) )

!* initialize the buffers once only

	If ( Calls.eq.1 ) then
	  Call SymbolSet(symbols)
	  Symbols(46) = Null
	  Calls = -1
	end if

	Length = Str_Len(String)
	J = 1

	Do While ( Length.ge.0 .and. String(74).eq.'S' )
	   String(74) = Null  ! blow off the 'S'
	   Do i = 1, Length
	     OneChar = Symbols(Ichar(String(i)))
	      If ( OneChar.ne.Null ) then
	         Strand(J) = OneChar
	         J = J + 1
	      End If
	   End Do
	   Call readstring(InFile, string, Length)
	End Do

	Strand(J) = Null
	SeqLength = J - 1

	Return
	End ! of CardReadPIRSeq

!***  WriteLongString  *********************************************************
!*
!*  	Writes OutLine to OutFile, splitting line at last blank space before
!*  	end of 80 character line.
!*
!*******************************************************************************

	Subroutine WriteLongString(OutFile, OutString)

	Implicit None

	Integer OutFile
	Character OutString(*)

	Integer Length, I

	Integer Str_Len, StrCopy

	Length = Str_Len(OutString)
	Do While ( Length.gt.80 )
	  I = 80
	  Do While ( OutString(I).ne.' ' )
	    I = I - 1
	  End Do
	  Length = I - 1
	  Call WriteBuff(OutFile, OutString, Length)
	  Length = StrCopy(OutString, OutString(Length+1))
	End Do

	Call WriteString(OutFile, OutString)

	Return
	End ! of WriteLongString

!***  HeaderCopy  ****************************************************
!*
!*	copy first two lines of the InFile, and all lines of the InFile after
!*	the line containing an asterisk, to the OutFile.
!*
!******************************************************************************

	Subroutine HeaderCopy(InFile, OutFile, OutLine, Strand, SeqLength)

	Implicit None
	Include 'GenInclude:SQConstants.inc'

	Integer InFile, OutFile
	Character OutLine(*), Strand(*)
	Integer SeqLength, i

	Integer Length, Lines
	Character TempStr(512)

	Integer StrFind, StrAerate, SWriteF, Str_Len, StrShift
	Logical StrIsBlank, ReadString

! Concatenate the first 2 lines, and get rid of the leading >'s (mks 11/8/90)

	Call ReadString(InFile, TempStr, Length)
	If ( SWriteF(OutLine, '~ - %s',TempStr ).gt.MAXDOCSTRING )
     &	  OutLine(MAXDOCSTRING-10) = Char(0)
	Call StrAerate(OutLine)               ! eliminate any '..'
	Length = Str_Len(OutLine)

! Get rid of any leading '>'

	i = 1
	Do While (OutLine(i).eq.'>')
	  i = i + 1
	End Do
	If ( (i-1).gt.0 ) Length = StrShift(OutLine, -(i-1))

	Call WriteLongString(OutFile, OutLine)

! read the sequence

	Call ReadPIRSeq(InFile, OutLine, Strand, SeqLength,'*')

! Copy the text following the sequence

	Do While ( ReadString(Infile, OutLine, Length).ge.0 )
	  If ( OutLine(1).eq.'>' ) Go to 1000
	  If ( .not.StrIsBlank(OutLine) ) then
	    Length = StrAerate(OutLine)              ! eliminate any '..'
	    Call WriteLongString(OutFile, OutLine)
	  End If
	End Do

1000	Continue

	Return
	End ! of HeaderCopy

!***  ReadPIRSeq   *************************************************
!*
!*	reads the legal GCG sequence characters for the PIR data
!*	file until the sequence is terminated by Term
!*
!******************************************************************************

	Subroutine ReadPIRSeq(InFile, String, Strand, SeqLength, Term)

	Implicit None

	Integer InFile
	Character String(*), Strand(*), Term(*)
	integer SeqLength

	Integer Length, calls/1/
	Character Symbols(0:255)

	Integer ReadString, StrFind, StrFilter

! initialize the buffers once only

	If ( Calls.eq.1 ) then
	  Call SymbolSet(Symbols)
	  Symbols(IChar('.')) = Char(0)
	  Symbols(IChar('*')) = Char(0)
	  Symbols(IChar('@')) = Char(0)
	  Symbols(IChar('&')) = Char(0)
	  Symbols(IChar('+')) = Char(0)
	  Calls = -1
	end if

	Strand(1) = Char(0)
	Do While ( ReadString(InFile, String, Length).ge.0 )
	  Call StrConCat(Strand, String)
	  If ( StrFind(Term, String).ne.0 ) Goto 1000
	End Do

	Call WriteF('\n\b ***  End of file during a sequence read! ***\n')

1000	SeqLength = StrFilter(Strand, Symbols)

	Return
	End ! of ReadPIRSeq

!*** NewHeaderCopy(InFile.ir,OutFile.iw,Strand.sw, SeqLen.iw) ******************
!*
!*	Read a new PIR format file from InFile.  Header info is copied to
!*	outfile, Strand is populated with the sequence, and SeqLen is set
!*	to the length of Strand.  OutLine is just used to pass a buffer
!*	around rather than allocating a new one for each function.
!*
!*******************************************************************************

	Subroutine NewHeaderCopy(InFile,OutFile,OutLine,Strand,SeqLen)

	Implicit None

	Character Strand(*), OutLine(*)
	Integer InFile, OutFile, SeqLen

	Character NextToken(32), Symbols(0:255)
	Integer InLen
	Logical Found_It

	Integer ReadString, StrFind

	Found_It = .False.
	Do While(.not.Found_It)
	  If (ReadString(InFile,OutLine,InLen).lt.0)
     &   Call WriteF('\n\b   *** Error - end of file encountered while'//
     &               ' reading header\n\s')

	  Call StrAerate(OutLine)
	  Call WriteString(OutFile,OutLine)
	  If (StrFIND('SEQUENCE',OutLine).eq.1) Found_It = .True.
	EndDo

	Call ReadPIRSeq(InFile,OutLine,Strand,SeqLen,'//')

	End  !  of NewHeaderCopy

!***  End of FromPIR.For
Comments: Gated by NETNEWS@AUVM.AMERICAN.EDU