GeneOntology OBO v1.4-Parser in Python
Das GeneOntology Consortium bietet Bulk-Downloads für die GO-Terms im OBO v1.2-Format an.
Wenn man nach GO OBO parser sucht, fällt etwas auf: Man findet leicht Parser in Perl, Parser in Java, aber nicht einmal BioPython hat einen Parser in Python. Das Format selbst scheint jedoch maßgeschneidert für Pythons Generator-Konzept zu sein. Nur wenige SLOCs werden benötigt, um es ohne Speicherung aller Daten im RAM zu verarbeiten.
Ich habe diesen Parser in einem Prototyp-Projekt verwendet, das eine interaktive GO-Suche ermöglicht (es ist schnell). Ich bin mir nicht sicher, wann/ob ich das veröffentliche, aber hier ist der Parser-Code.
Kopiere einfach beide Funktionen in deine Codebasis – es gibt keine Abhängigkeiten außer collections.defaultdict aus der Python-Standardbibliothek.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Ein konstanten-Speicher-Parser für das GeneOntology OBO v1.2 & v1.4 Format
https://owlcollab.github.io/oboformat/doc/GO.format.obo-1_4.html
Version 1.1: Python3-ready & --verbose CLI-Option
"""
from __future__ import with_statement
from collections import defaultdict
__author__ = "Uli Köhler"
__copyright__ = "Copyright 2013 Uli Köhler"
__license__ = "Apache v2.0"
__version__ = "1.1"
def processGOTerm(goTerm):
"""
Ersetzt in einem Objekt, das einen GO-Term repräsentiert, ein-elementige Listen
durch ihr einziges Element.
Gibt das modifizierte Objekt als Dictionary zurück.
"""
ret = dict(goTerm) #Eingabe ist ein defaultdict, könnte unerwartetes Verhalten zeigen
for key, value in ret.items():
if len(value) == 1:
ret[key] = value[0]
return ret
def parseGOOBO(filename):
"""
Parst einen Gene Ontology-Dump im OBO v1.2-Format.
Yielded jeden
Keyword-Argumente:
filename: Der Dateiname zum Lesen
"""
with open(filename, "r") as infile:
currentGOTerm = None
for line in infile:
line = line.strip()
if not line: continue #Leere Zeilen überspringen
if line == "[Term]":
if currentGOTerm: yield processGOTerm(currentGOTerm)
currentGOTerm = defaultdict(list)
elif line == "[Typedef]":
#[Typedef]-Abschnitte überspringen
currentGOTerm = None
else: #Nicht [Term]
#Nur verarbeiten, wenn wir uns in einer [Term]-Umgebung befinden
if currentGOTerm is None: continue
key, sep, val = line.partition(":")
currentGOTerm[key].append(val.strip())
#Letzten Term hinzufügen
if currentGOTerm is not None:
yield processGOTerm(currentGOTerm)
if __name__ == "__main__":
"""Gibt die Anzahl der GO-Objekte in der angegebenen GO OBO-Datei aus"""
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('infile', help='Die Eingabedatei im GO OBO v1.2-Format.')
parser.add_argument('-v', '--verbose', action="store_true",
help='Alle GO-Items ausgeben anstatt nur deren Anzahl zu drucken')
args = parser.parse_args()
#Über GO-Terms iterieren
termCounter = 0
if args.verbose:
for goTerm in parseGOOBO(args.infile):
print(goTerm)
else:
for goTerm in parseGOOBO(args.infile):
termCounter += 1
print ("Found %d GO terms" % termCounter)