Skip to content

Instantly share code, notes, and snippets.

@laserson
Created April 30, 2010 15:10
Show Gist options
  • Select an option

  • Save laserson/385326 to your computer and use it in GitHub Desktop.

Select an option

Save laserson/385326 to your computer and use it in GitHub Desktop.
diff --git a/Bio/GenBank/Scanner.py b/Bio/GenBank/Scanner.py
index cc72e7f..dd9d7f0 100644
--- a/Bio/GenBank/Scanner.py
+++ b/Bio/GenBank/Scanner.py
@@ -1183,7 +1183,69 @@ class GenBankScanner(InsdcScanner):
return
except StopIteration:
raise ValueError("Problem in misc lines before sequence")
+
+class ImgtScanner(EmblScanner):
+ """For extracting chunks of information in IMGT/LIGM-DB flatfiles"""
+
+ # RECORD_START = "ID "
+ # HEADER_WIDTH = 5
+ FEATURE_START_MARKERS = ["FH Key Location/Qualifiers",
+ "FH Key Location/Qualifiers (from EMBL)",
+ "FH Key Location/Qualifiers",
+ "FH"]
+ FEATURE_END_MARKERS = ["XX"] #XX can also mark the end of many things!
+ FEATURE_QUALIFIER_INDENTS = {"FH Key Location/Qualifiers":21,
+ "FH Key Location/Qualifiers (from EMBL)":21,
+ "FH Key Location/Qualifiers":25}
+ FEATURE_QUALIFIER_SPACERS = {"FH Key Location/Qualifiers":
+ "FT ",
+ "FH Key Location/Qualifiers (from EMBL)":
+ "FT ",
+ "FH Key Location/Qualifiers":
+ "FT "}
+ # FEATURE_QUALIFIER_INDENTS = [21,25]
+ # FEATURE_QUALIFIER_SPACERS = [("FT" + " " * (f-2),f) for f in FEATURE_QUALIFIER_INDENTS]
+ FEATURE_QUALIFIER_INDENT = 0 # set dynamically
+ FEATURE_QUALIFIER_SPACER = "" # set dynamically
+ # SEQUENCE_HEADERS=["SQ", "CO"] #Remove trailing spaces
+
+ def parse_header(self):
+ """Return list of strings making up the header
+
+ New line characters are removed.
+
+ Assumes you have just read in the ID/LOCUS line.
+ """
+ assert self.line[:self.HEADER_WIDTH]==self.RECORD_START, \
+ "Not at start of record"
+ header_lines = []
+ while True:
+ line = self.handle.readline()
+ if not line:
+ raise ValueError("Premature end of line during sequence data")
+ line = line.rstrip()
+ if line in self.FEATURE_START_MARKERS:
+ if self.debug : print "Found header table"
+ # NOTE: if first FH found has no info on indentation, we can't
+ # define the qualifier indent/spacer
+ if line != 'FH':
+ # determine if the IMGT record indentation is 21 or 25 chars
+ self.FEATURE_QUALIFIER_INDENT = self.FEATURE_QUALIFIER_INDENTS[line]
+ self.FEATURE_QUALIFIER_SPACER = self.FEATURE_QUALIFIER_SPACERS[line]
+ break
+ #if line[:self.HEADER_WIDTH]==self.FEATURE_START_MARKER[:self.HEADER_WIDTH]:
+ # if self.debug : print "Found header table (?)"
+ # break
+ if line[:self.HEADER_WIDTH].rstrip() in self.SEQUENCE_HEADERS:
+ if self.debug : print "Found start of sequence"
+ break
+ if line == "//":
+ raise ValueError("Premature end of sequence data marker '//' found")
+ header_lines.append(line)
+ self.line = line
+ return header_lines
+
if __name__ == "__main__":
from StringIO import StringIO
diff --git a/Bio/SeqIO/InsdcIO.py b/Bio/SeqIO/InsdcIO.py
index 752ed57..c10d74d 100644
--- a/Bio/SeqIO/InsdcIO.py
+++ b/Bio/SeqIO/InsdcIO.py
@@ -26,7 +26,7 @@ http://www.ddbj.nig.ac.jp/
"""
from Bio.Seq import UnknownSeq
-from Bio.GenBank.Scanner import GenBankScanner, EmblScanner
+from Bio.GenBank.Scanner import GenBankScanner, EmblScanner, ImgtScanner
from Bio import Alphabet
from Interfaces import SequentialSequenceWriter
from Bio import SeqFeature
@@ -61,6 +61,17 @@ def EmblIterator(handle):
#This calls a generator function:
return EmblScanner(debug=0).parse_records(handle)
+def ImgtIterator(handle):
+ """Breaks up an IMGT/LIGM-DB flatfile into SeqRecord objects.
+
+ Every section from the LOCUS line to the terminating // becomes
+ a single SeqRecord with associated annotation and features.
+
+ Note that for genomes or chromosomes, there is typically only
+ one record."""
+ #This calls a generator function:
+ return ImgtScanner(debug=0).parse_records(handle)
+
def GenBankCdsFeatureIterator(handle, alphabet=Alphabet.generic_protein):
"""Breaks up a Genbank file into SeqRecord objects for each CDS feature.
diff --git a/Bio/SeqIO/__init__.py b/Bio/SeqIO/__init__.py
index 03d281a..cb4e91f 100644
--- a/Bio/SeqIO/__init__.py
+++ b/Bio/SeqIO/__init__.py
@@ -325,6 +325,7 @@ _FormatToIterator = {"fasta" : FastaIO.FastaIterator,
"embl" : InsdcIO.EmblIterator,
"embl-cds" : InsdcIO.EmblCdsFeatureIterator,
"ig" : IgIO.IgIterator,
+ "imgt": InsdcIO.ImgtIterator,
"swiss" : SwissIO.SwissIterator,
"phd" : PhdIO.PhdIterator,
"ace" : AceIO.AceIterator,
diff --git a/Bio/SeqIO/_index.py b/Bio/SeqIO/_index.py
index 0901e61..e15493c 100644
--- a/Bio/SeqIO/_index.py
+++ b/Bio/SeqIO/_index.py
@@ -401,6 +401,23 @@ class EmblDict(_SequentialSeqFileDict):
break
self._record_key(key, offset)
+class ImgtDict(_SequentialSeqFileDict):
+ """Indexed dictionary like access to an IMGT/LIGM-DB flatfile."""
+ def __init__(self, filename, alphabet, key_function):
+ _IndexedSeqFileDict.__init__(self, filename, alphabet, key_function)
+ self._format = "imgt"
+ handle = self._handle
+ marker_re = re.compile("^ID ")
+ self._marker_re = marker_re #saved for the get_raw method
+ while True:
+ offset = handle.tell()
+ line = handle.readline()
+ if not line : break #End of file
+ if marker_re.match(line):
+ # We assume the first word after ID is the accession
+ key = line.split()[1]
+ self._record_key(key, offset)
+
class SwissDict(_SequentialSeqFileDict):
"""Indexed dictionary like access to a SwissProt file."""
def __init__(self, filename, alphabet, key_function):
@@ -594,6 +611,7 @@ _FormatToIndexedDict = {"ace" : AceDict,
"genbank" : GenBankDict,
"gb" : GenBankDict, #alias of the above
"ig" : IntelliGeneticsDict,
+ "imgt" : ImgtDict,
"phd" : PhdDict,
"pir" : PirDict,
"sff" : SffDict,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment