GeneOntology OBO v1.4-Parser in Python

English Deutsch

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.

obo_parser.py
#!/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)

Check out similar posts by category: Bioinformatics, Python